065.【Id】異なるinddの同名段落スタイルの差分を取得
※未完成
※同じ名前の段落スタイルであっても、スタイルグループが異なる場合は別物として扱う
挙動
前準備
- Github上でextendscript-es5-shimとして公開されているプロジェクトから、indexOf()とisArray()のポリフィルをダウンロードする
- このスクリプトと同階層に「indexOf.js」「isArray.js」を移動する
実行
- ドキュメントを2つ開いた状態でスクリプトを実行する
- 各inddの同名同グループの段落スタイルを比較する
- プロパティの値が異なる場合、差分を取得する
- デスクトップにlog.txtを出力する
コード
//@include "./indexOf.js" //@include "./isArray.js" if (app.documents.length !== 2) { alert("2つのドキュメントを開いてください"); exit(); } var indd0 = app.documents[0]; var indd1 = app.documents[1]; //各inddの全段落スタイルの情報を取得 var pStyles0 = getPstylesInfo(indd0); var pStyles1 = getPstylesInfo(indd1); //両inddで名前とグループ名の一致する段落スタイルを取得 var dupe = []; for (var i = 0; i < pStyles0.length; i++) { for (var j = 0; j < pStyles1.length; j++) { if (pStyles0[i]['name'] === pStyles1[j]['name'] && pStyles0[i]['group'] === pStyles1[j]['group']) { dupe.push([pStyles0[i], pStyles1[j]]) } } } if (dupe.length === 0) { alert("重複したスタイルはありませんでした"); exit(); } var log = "スタイル名\tグループ名\tプロパティ\t" + indd0.name + "\t" + indd1.name; for (var i = 1; i < dupe.length; i++) { //段落スタイルなしはスキップ var tmpStyle = indd0.paragraphStyles[0]; log = log + "\n" + compareProp(tmpStyle, dupe[i][0]['obj'], dupe[i][1]['obj']) } writeTxt("~/Desktop/log.txt", log); function compareProp(tgt, a, b) { var r = ""; for (p in tgt) { var propn = p; var aprop = bprop = ""; var skip = ["properties", "parent", "preferences", "styleUniqueId", "id","index"]; //このプロパティはスキップする if (skip.indexOf(p) === -1) { switch (getType(a[p])) { case "object": //nextStyleなどobjectの場合はnameで比較 //~ compareProp(a[p], a[p], b[p]); //本当はここで再帰処理するべきなんだと思う try { if (a[p].name !== b[p].name) { aprop = a[p].name.replace(/\t/g," "); bprop = b[p].name.replace(/\t/g," "); } } catch (e) { //nameで比較できない場合は比較しない aprop = "この項目は比較しませんでした" } break; case "array": if (a[p].toSource() !== b[p].toSource()) { if (typeof a[p][0] ==="object") { //tabListなどobjectを要素として持つ配列の場合 aprop = "この項目は比較しませんでした" } else { aprop = a[p]; bprop = b[p]; } } break; case "string": if (a[p] !== b[p]) { aprop = a[p].replace(/\t/g," "); bprop = b[p].replace(/\t/g," "); } break; default: //enum・数値・真偽値などの場合 if (a[p] !== b[p]) { aprop = a[p]; bprop = b[p]; } break; } } if (aprop !== "") { r = r + [dupe[i][0]['name'], dupe[i][0]['group'], p, aprop, bprop].join("\t") + "\n"; } } return r } //全段落スタイルの情報を取得 function getPstylesInfo(tgtDoc) { var result = []; for (var i = 0; i < tgtDoc.allParagraphStyles.length; i++) { var tmp = tgtDoc.allParagraphStyles[i]; result.push({ name: tmp.name, group: getStyleGroup(tmp).replace(/\//, ""), obj: tmp }); } return result; } //所属スタイルグループ名を取得 //入れ子になっている場合はスラッシュで繋ぐ function getStyleGroup(tgt) { var tgtGroup = "" if (tgt.parent.constructor.name === "Document") { return ""; } tgtGroup = getStyleGroup(tgt.parent) + "/" + tgt.parent.name; return tgtGroup; } //テキスト書き出し function writeTxt(path, txt) { var fObj = new File(path); fObj.encoding = (/csv$/.test(path)) ? "Shift-JIS" : "UTF-8"; //CSVで書き出す場合はShift-JIS if (fObj.open("w")) { fObj.write(txt); fObj.close(); return fObj; } else { alert("ファイルが開けません\n" + path); } } //型判定 //最初に大部分をふるい落とすほうがよい? //if (typeof obj !== "object") {return typeof obj;} function getType(obj) { if (obj === null){ return "null"; } if (Array.isArray(obj)) { return "array"; } if (obj.constructor.name === "Enumerator") { return "enumerator"; } return typeof obj; }
メモ
分かったこと
- Enumulatorについて
var tgt = app.activeDocument.paragraphStyles[2].justification; $.writeln(typeof tgt);//object $.writeln(Object.prototype.toString.call(tgt));//LEFT_JUSTIFIED $.writeln(tgt.constructor.name);//Enumerator $.writeln(tgt.toSource());//({}) var tgt2 = app.activeDocument.paragraphStyles[4].justification; $.writeln(tgt===tgt2);//true enum同士で比較できる
積み残し
- テストが不十分。おそらくバグがある。
- オブジェクト同士の比較について別の方法を模索する。
現状、値がオブジェクトの場合(「次の段落スタイル」など)はnameプロパティだけを比較している。
そのため名前が同じで中身が違う場合でも同じと見なしてしまう。 - 3つ以上のinddでも使えるようする。
ブックドキュメントの同期をする前に差分をチェックしたいなと思ったのがきっかけなので、複数のinddを対象としたい。
参考
- ExtendScript/extendscript-es5-shim: A collection of ES5 shims for polyfiling Exendscript | GitHub
- Adobe ExtendScriptのプリプロセッサディレクティブ | chalcedony_htnの日記
- #includeはどこに書いてもよく、コードの断片でもいい | ぼんぷろぐ
- null - JavaScript | MDN
null == undefined とすると、型変換が行われるためtrueになる。 - 暗黙的な型変換 · JavaScript Primer #jsprimer
「等価演算子(==)では異なるデータ型を比較した場合に、同じ型となるように暗黙的な型変換をしてから比較します」 - JavaScriptの「型」の判定について | Qiita