MacDownで編集中のMarkdown書類をいったんデスクトップにPDF書き出しして、見出しがページ末尾に位置していないか(見出し落ち)をチェックするAppleScriptです。
MacDownのAppleScript対応機能が少ないので、ほとんどAppleScriptだけで処理しています。Cocoaの機能を呼べるようになったので、とくに問題ありません。
MacDownで編集中の最前面のMarkdown書類からパスを取得し、AppleScriptで直接ファイルから内容を読み込み、正規表現で見出し一覧を取得します。
MacDownからGUI Scripting経由でメニューをコントロールしてPDF書き出しを行い、ページ単位でPDFからテキストを抽出。不要な空白文字列などを削除。
▲いわゆる「見出し落ち」の状態。ページ末尾に見出し項目が存在している
各ページのテキストが見出しの内容で終了していれば、結果出力用の変数midashiOchiListに{ページ数, 見出し名称} を追加して出力します。
–> {{2, “対象となるFramework”}}
AppleScript名:MacDownで編集中のMarkDown書類で見出しが見出し落ちしていないかチェック |
— Created 2017-08-12 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "Quartz" property NSString : a reference to current application’s NSString property NSCharacterSet : a reference to current application’s NSCharacterSet property NSRegularExpression : a reference to current application’s NSRegularExpression property NSRegularExpressionAnchorsMatchLines : a reference to current application’s NSRegularExpressionAnchorsMatchLines property NSRegularExpressionDotMatchesLineSeparators : a reference to current application’s NSRegularExpressionDotMatchesLineSeparators set docName to getFrontmostMarkdownDocName() of me if docName = false then return set newName to repFileNameExtension(docName, ".pdf") of me set newPath to (POSIX path of (path to desktop)) & newName set dRes to deleteItemAt(newPath) of me –前回実行時にデスクトップに残った同名のPDFを削除する –Markdownのソースを元ファイルから直接読み出す set docSourcePath to getFrontmostMarkdownFullPath() of me set aStr to (read (docSourcePath as alias) as «class utf8») –getHeader List set aList to retHeaders(aStr) of me –Export Markdown to PDF (desktop folder) macDownForceSave() of me set tList to textInPDFinEachPage(newPath) of me set pCount to 1 set midashOchiList to {} repeat with i in tList set j to (contents of i) as string repeat with ii in aList set jj to (contents of second item of ii) as string –set jj2 to replaceText(jj, "(", "(") of me –set jj3 to replaceText(jj2, ")", ")") of me if (j ends with jj) then set the end of midashOchiList to {pCount, jj} end if end repeat set pCount to pCount + 1 end repeat return midashOchiList on retHeaders(aCon) set tList to {} set regStr to "^#{1,6}[^#]*?$" set headerList to my findPattern:regStr inString:aCon repeat with i in headerList set j to contents of i set regStr2 to "^#{1,6}[^#]*?" set headerLevel to length of first item of (my findPattern:regStr2 inString:j) set tmpHeader1 to text (headerLevel + 1) thru -1 in j –ヘッダーの前後から空白文字をトリミング set tmpHeader2 to trimWhiteSpaceFromHeadAndTail(tmpHeader1) of me –ヘッダー部でPDF書き出ししたときに全角文字が半角文字に置換されてしまうケースに対処 set tmpHeader3 to replaceText(tmpHeader2, "(", "(") of me set tmpHeader4 to replaceText(tmpHeader3, ")", ")") of me set the end of tList to {headerLevel, tmpHeader4} end repeat return tList end retHeaders on findPattern:thePattern inString:theString set theOptions to ((NSRegularExpressionDotMatchesLineSeparators) as integer) + ((NSRegularExpressionAnchorsMatchLines) as integer) set theRegEx to NSRegularExpression’s regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value) set theFinds to theRegEx’s matchesInString:theString options:0 range:{location:0, |length|:length of theString} set theFinds to theFinds as list — so we can loop through set theResult to {} — we will add to this set theNSString to NSString’s stringWithString:theString repeat with i from 1 to count of items of theFinds set theRange to (item i of theFinds)’s range() set end of theResult to (theNSString’s substringWithRange:theRange) as string end repeat return theResult end findPattern:inString: –指定文字列の前後から空白をトリミング on trimWhiteSpaceFromHeadAndTail(aStr as string) set aString to NSString’s stringWithString:aStr set bString to aString’s stringByTrimmingCharactersInSet:(NSCharacterSet’s whitespaceAndNewlineCharacterSet()) return bString as list of string or string –as anything end trimWhiteSpaceFromHeadAndTail –ファイル名の拡張子を置換する on repFileNameExtension(origName, newExt) set aName to current application’s NSString’s stringWithString:origName set theExtension to aName’s pathExtension() if (theExtension as string) is not equal to "" then set thePathNoExt to aName’s stringByDeletingPathExtension() set newName to (thePathNoExt’s stringByAppendingString:newExt) else set newName to (aName’s stringByAppendingString:newExt) end if return newName as string end repFileNameExtension on textInPDFinEachPage(thePath) set aList to {} set anNSURL to (current application’s |NSURL|’s fileURLWithPath:thePath) set theDoc to current application’s PDFDocument’s alloc()’s initWithURL:anNSURL set theCount to theDoc’s pageCount() as integer repeat with i from 1 to theCount set thePage to (theDoc’s pageAtIndex:(i – 1)) set curStr to (thePage’s |string|()) set curStr2 to curStr’s decomposedStringWithCanonicalMapping() –Normalize Text with NFC set targString to string id 13 & string id 10 & string id 32 & string id 65532 –Object Replacement Character set bStr to (curStr2’s stringByTrimmingCharactersInSet:(current application’s NSCharacterSet’s characterSetWithCharactersInString:targString)) set the end of aList to (bStr as string) end repeat return aList end textInPDFinEachPage –注意!! ここでGUI Scriptingを使用。バージョンが変わったときにメニュー階層などの変更があったら書き換え on macDownForceSave() activate application "MacDown" tell application "System Events" tell process "MacDown" — File > Export > PDF click menu item 2 of menu 1 of menu item 14 of menu 1 of menu bar item 3 of menu bar 1 –Go to Desktop Folder keystroke "d" using {command down} –Save Button on Sheet click button 1 of sheet 1 of window 1 end tell end tell end macDownForceSave on getFrontmostMarkdownDocName() tell application "MacDown" set dList to every document set dCount to count every item of dList if dCount is not equal to 1 then display notification "Markdown document is not only one." return false end if tell document 1 set docName to name end tell return docName end tell end getFrontmostMarkdownDocName on getFrontmostMarkdownFullPath() tell application "MacDown" tell document 1 set aProp to properties end tell end tell set aPath to (file of aProp) end getFrontmostMarkdownFullPath –任意のデータから特定の文字列を置換 on replaceText(origData, origText, repText) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to {origText} set origData to text items of origData set AppleScript’s text item delimiters to {repText} set origData to origData as text set AppleScript’s text item delimiters to curDelim –set b to origData as text return origData end replaceText –指定のPOSIX pathのファイルを強制削除(あってもなくてもいい) on deleteItemAt(aPOSIXpath) set theNSFileManager to current application’s NSFileManager’s defaultManager() set theResult to theNSFileManager’s removeItemAtPath:(aPOSIXpath) |error|:(missing value) return (theResult as integer = 1) as boolean end deleteItemAt |