はじめに
先日 PHP で作成した CotEditor スクリプトを、pbpaste
の文字コード違いも気になったため JavaScript(JXA)で作り直しました。
使い方
先日のスクリプト同様、表計算ソフトからセル範囲を選択して「コピー」を行います。
CotEditor に戻って「⌘ + Shift + V」します。
以下のようになります。
Id |Name |Price ------|----------------|------------ 1 |Apple |200 2 |Banana |150 3 |Citrus |300 九九九|ドラゴンフルーツ|価格未設定。
スクリプトのソースコード
ファイル名を「TSVを表としてペースト.@$v.js」などと設定し、CotEditor のスクリプトフォルダに入れれば、「⌘ + Shift + V」で実行できます。
#!/usr/bin/osascript -l JavaScript (() => { 'use strict'; ObjC.import('stdlib') let CotEditor = Application('CotEditor'); CotEditor.includeStandardAdditions = true; let doc = CotEditor.documents[0]; const selection = doc.selection; const notification = (msg, title) => { let app = Application.currentApplication(); app.includeStandardAdditions = true; app.displayNotification(msg, { withTitle: "CotEditor - スクリプト", subtitle: title, soundName: "Frog", }); }; const clipboardText = () => { let app = Application.currentApplication(); app.includeStandardAdditions = true; return app.doShellScript("pbpaste"); }; const strlen = (str) => { // https://mebee.info/2020/12/21/post-26346/#outline__3 let len = 0; for (let i = 0; i < str.length; i++) { (str[i].match(/[ -~]/)) ? len += 1 : len += 2; } return len; }; const padright = (text, width, padString) => { let len = width - strlen(text); return text + padString.repeat(len); }; let str = clipboardText(); // 入力チェック if ((!str.includes("\r") || !str.includes("\n")) && !str.includes("\t")) { let msg = "改行/タブのいずれも含まれていないようです。"; let title = "クリップボードの内容は TSV ではありません"; notification(msg, title); $.exit(0); } // 行分割 let linesSrc = str.split(/(\n|\r)+/); // 列分割 let lines = []; linesSrc.forEach(line => { if (line.trim() === '') {return;} lines.push(line.trim().split("\t")); }); // 列幅取得 let colWidth = new Array(lines[0].length).fill(0); for (let i = 0; i < lines[0].length; i++) { lines.forEach(line => { let c = line[i]; let w = strlen(c); colWidth[i] = Math.max(w, colWidth[i]); }); } var ret = ""; // 見出し出力 let titles = []; lines[0].forEach((title, idx) => { titles.push(padright(title, colWidth[idx], ' ')); }); ret += titles.join("|") + "\n"; // 水平線出力 let hr = []; colWidth.forEach((w) => { hr.push("-".repeat(w)); }); ret += hr.join("|") + "\n"; // データ部出力 for (let row = 1; row < lines.length; row++) { let cols = []; lines[row].forEach((col, idx) => { cols.push(padright(col, colWidth[idx], ' ')); }); ret += cols.join("|") + "\n"; } selection.contents = ret; CotEditor.activate(); })();
参考
文字数のカウントに、以下のスクリプトを使わせていただきました。
javascript 全角文字は2文字で半角文字は1文字としてカウントする | mebee
環境
以下の環境で開発・動作確認しました。
ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H1323 AppleScript version: 2.7 CotEditor version: 2.7.4 Numbers.app version: 10.3.9
また、Google Spreadsheet でも確認しました。