タブでインデントしたテキストを、NSOutlineViewで表示できるデータ形式に変換するAppleScriptの改良版です。
主に、Keynote書類の各スライド(ページ)上のタイトルを、そのマスタースライド名をもとにインデントレベルを仮想的に判定し、PDFのTOCを作成する際の「プレビュー」を行うべく、NSOutLineViewで表示するために作成したものです。
ChatGPTにオーダーを出して、エラー内容と処理結果をそのまま差し返すことで、数回このフローを繰り返して正しい処理内容を取得できました。
これ自体は、テストデータ(テキスト)からNSOutLineView表示用のデータを作成するだけのScriptです。
Tab n個のn階層をサポートしています。
表紙 目次 1章 セクション1 項目1 コラム1 項目2 コラム2 セクション2 項目3 2章 セクションA 項目A1 項目A2 セクションB 裏表紙
こんなデータを、
{{|name|:"表紙", isLeaf:true, children:{}}, {|name|:"目次", isLeaf:true, children:{}}, {|name|:"1章", isLeaf:false, children:{{|name|:"セクション1", isLeaf:false, children:{{|name|:"項目1", isLeaf:false, children:{{|name|:"コラム1", isLeaf:true, children:{}}}}, {|name|:"項目2", isLeaf:false, children:{{|name|:"コラム2", isLeaf:true, children:{}}}}}}, {|name|:"セクション2", isLeaf:false, children:{{|name|:"項目3", isLeaf:true, children:{}}}}}}, {|name|:"2章", isLeaf:false, children:{{|name|:"セクションA", isLeaf:false, children:{{|name|:"項目A1", isLeaf:true, children:{}}, {|name|:"項目A2", isLeaf:true, children:{}}}}, {|name|:"セクションB", isLeaf:true, children:{}}}}, {|name|:"裏表紙", isLeaf:true, children:{}}}
のように変換します。
NSOutlineViewをダイアログ表示するAppleScriptライブラリを作りかけて、データ作成部分もライブラリに組み込まないと使い物にならないと気づき、ChatGPTに作らせたものです。
AppleScript名:タブでインデントしたテキストをOutLineViewで表示できるデータ形式に変換 v4(3階層対応).scpt |
— – Created by: Takaaki Naganoya – Created on: 2025/10/10 — – Copyright © 2025 Piyomaru Software, All Rights Reserved — use AppleScript version "2.8" use framework "Foundation" use scripting additions — サンプル入力(3階層以上) set srcText to "表紙 目次 1章 セクション1 項目1 コラム1 項目2 コラム2 セクション2 項目3 2章 セクションA 項目A1 項目A2 セクションB 裏表紙" set aRec to convStrToStructuredRec(srcText) of me –> {{|name|:"表紙", isLeaf:true, children:{}}, {|name|:"目次", isLeaf:true, children:{}}, {|name|:"1章", isLeaf:false, children:{{|name|:"セクション1", isLeaf:false, children:{{|name|:"項目1", isLeaf:false, children:{{|name|:"コラム1", isLeaf:true, children:{}}}}, {|name|:"項目2", isLeaf:false, children:{{|name|:"コラム2", isLeaf:true, children:{}}}}}}, {|name|:"セクション2", isLeaf:false, children:{{|name|:"項目3", isLeaf:true, children:{}}}}}}, {|name|:"2章", isLeaf:false, children:{{|name|:"セクションA", isLeaf:false, children:{{|name|:"項目A1", isLeaf:true, children:{}}, {|name|:"項目A2", isLeaf:true, children:{}}}}, {|name|:"セクションB", isLeaf:true, children:{}}}}, {|name|:"裏表紙", isLeaf:true, children:{}}} on convStrToStructuredRec(srcText) set nsText to current application’s NSString’s stringWithString:srcText set allLines to nsText’s componentsSeparatedByCharactersInSet:(current application’s NSCharacterSet’s newlineCharacterSet()) set topList to {} — 最終出力 set stack to {} — 階層ごとの親ノードを保持 repeat with aLine in allLines set lineNS to (current application’s NSString’s stringWithString:(aLine as text)) set trimmedStr to (lineNS’s stringByTrimmingCharactersInSet:(current application’s NSCharacterSet’s whitespaceAndNewlineCharacterSet())) as text if trimmedStr is "" then — 空行スキップ else — 行頭タブ数 set len to lineNS’s |length|() set tabCount to 0 repeat with i from 0 to (len – 1) set ch to (lineNS’s characterAtIndex:i) if (ch as integer) = 9 then set tabCount to tabCount + 1 else exit repeat end if end repeat — タブ除去文字列 if len > tabCount then set contentText to (lineNS’s substringFromIndex:tabCount) as text else set contentText to "" end if — 新しいレコード set newRec to {|name|:contentText, isLeaf:true, children:{}} if tabCount = 0 then — トップレベル set end of topList to newRec set stack to {newRec} else — stack を tabCount に合わせて切り詰め if (count of stack) ≥ tabCount then set stack to items 1 thru tabCount of stack end if — 親ノード取得 set parentRec to item tabCount of stack — 親の children に追加 set parentChildren to parentRec’s children set end of parentChildren to newRec set parentRec’s children to parentChildren — 親の isLeaf を false に set parentRec’s isLeaf to false — stack に追加 set end of stack to newRec end if end if end repeat return topList end convStrToStructuredRec |