TAWAMIラボ

2021/05/19 Illustrator Script

イラレスクリプトで文字の属性が変えられないときは…

イラレでテキストの属性を変えるようなスクリプトを書いていると、ときどき「なぜかスクリプトで設定した値が反映されてない」というバグに遭遇することがあります。

たとえば、こちら(Illustrator:文字の位置そのままで揃え方向を変えたい時に使うやつ / 車車車く本牛勿 -Rollin' Real-)のコメント欄を見ると、Ajabonさんがテキストの左揃えが適用できないことに苦しみ、最終的にresizeを使って 200%に拡大→左揃えを適用→50%に縮小して戻す、という手を使って解決されています。

また、こちらのAdobeフォーラムでは、文字サイズがなぜか特定の値にできない、という問題に対して、フォントを別のフォントに変える→文字サイズを変更する→元のフォントに戻す、という手で解決されています。

他にも、似たような「スクリプトで文字属性が適用できないバグ」に遭遇した報告、ちょくちょく目にするのですが、これらをまとめて次のように言えるのではないかと思っています。

仮説A:文字スタイル・段落スタイルのオーバーライドが完全になくなるような属性の変更が無効化される。

十分検証したわけではないので「仮説」としています。
以下では仮説Aが正しいとした上で、現象の解説と解決方法を書いています。
仮説Aでは説明がつかないような事例を知ってる方がいましたら、ぜひとも教えてください。


たとえば

「新規ドキュメントにテキストを作り、文字パネルで文字サイズを20ptにした」とします。
このとき、テキストの文字・段落属性は、文字スタイル・段落スタイルに対して文字サイズのみオーバーライドされています。
ここで、12ptに戻すスクリプト(テキストを、テキストツールではなく選択ツールで選択して使います)

app.selection[0].textRange.size = 12;

を実行しても、効果がありません。
もし文字サイズが12ptになったら、オーバーライドは完全になくなるため、仮説Aにより無効化された、と説明できます。

「文字パネルで文字サイズを20ptにし、さらにトラッキングを10にした」という状態であれば、上記スクリプトは正しく動作します。
文字サイズが12ptになっても、トラッキングのオーバーライドが残るからです。
しかしその後、

app.selection[0].textRange.tracking = 0;

でトラッキングを0に戻そうとしても、できません。

文字サイズが12ptにできない

トラッキングを10にすると、文字サイズを12ptにできた

今度はトラッキングが0に戻せない

また別の文字属性を変更すると、トラッキングを0にできた

今度はその変更した属性が戻せない

という無限ループに陥ってしまう、やっかいなバグなのです。

そして、この現象は文字属性、段落属性それぞれ独立に起こります。さきほどは「トラッキングを10にすると、文字サイズを12ptにできた」のですが、文字属性のトラッキングの代わりに、段落属性の「左インデントを10にした」ではダメなのです。
逆に、段落属性の左揃えが適用できない現象に対しては、「トラッキングを10にする」はダメで「左インデントを10にする」なら効きます。


※以下のスクリプトはすべて、文字サイズのみをデフォルトから変更されたテキストを、選択ツールで選択した状態で実行し、文字サイズを12ptにするものです。

解決方法その1:近い値でごまかす

var newSize = 12; var text1 = app.selection[0].textRange; text1.size = newSize; if (text1.size != newSize) { text1.size = newSize + 0.01; }

12がダメなら、まあほとんど見た目変わらないだろうから12.01でいいや、というとき向け。
なお12.001だと12と同じとみなされてダメなようです。

欠点

  • 値が不正確
  • いくつかの値しか取らない属性(たとえば引く・引かないの2値しかない下線)には使えない

解決方法その2:フォントを変更する

var newSize = 12; var text1 = app.selection[0].textRange; text1.size = newSize; if (text1.size != newSize) { var font1 = app.textFonts.getByName("KozMinPro-Regular"); var font2 = text1.textFont; text1.textFont = font1; text1.size = newSize; text1.textFont = font2; }

実はこのバグが例外的に効かない唯一の文字属性があります。
適用されているフォントを指すtextFontです。
そこで「フォントを変更する→文字属性を変更する→フォントを戻す」という手が使えます。
しかし、このとき適用するフォントは

  • インストールされている
  • 適用しようとしているテキストのグリフがそのフォントにすべて含まれる

という条件を満たすことが必要です。上記の例では「小塚明朝 Pro R」を使っています。

欠点

  • 適用するフォントの選定が難しい
  • 段落属性には使えない

解決方法その3:めったに使わない属性を変えたままにする

var newSize = 12; var text1 = app.selection[0].textRange; text1.size = newSize; if (text1.size != newSize) { text1.wariChuScale = 49; text1.size = newSize; }

どこか1か所、通常の文字組みに影響を与えないような属性をオーバーライドしっぱなしにしよう、という手です。
上の例では割注スケールを、デフォルトの50でなく49に変更しています。
これは割注(1行の中に2行で注釈を入れるやつ)を有効にした場合の文字サイズのスケールです。
割注自体めったに使われないですし(私は一度も使ったことない)、まれに使われても50と49ならほとんど変わらんだろう、という考えで選びましたが、このへんは人によるでしょう。
段落属性であれば、ジャスティフィケーションの単語間隔の最小値minimumWordSpacingとかであれば、日本語組版には影響を与えないでしょう。

欠点

  • スタイルのオーバーライドが残る
  • 使わない属性の選び方が難しい
  • 使わないと思ってた属性が使われるとまずい

解決方法その4:変形して戻す

var newSize = 12; var sel = app.selection[0] var text1 = sel.textRange; text1.size = newSize; if (text1.size != newSize) { sel.resize(50, 50); text1.size = newSize / 2; sel.resize(200, 200); }

上にも出てきた「50%に変形→文字属性を変更する→200%に拡大して戻す」というやつです。

欠点

  • 長さの単位を持つすべての文字・段落属性(文字サイズ、ベースラインシフト、インデント等)がオーバーライド状態になるため、段落スタイル、文字スタイルで文字サイズ等を管理している人にとっては有害

解決方法その5:文字サイズ・段落スタイルの方を変更して戻す

var newSize = 12; var text1 = app.selection[0].textRange; var style1 = text1.characterStyles[0]; text1.size = newSize; if (text1.size != newSize) { try{style1.size}catch(e){style1=activeDocument.characterStyles[0]} style1.size = newSize + 1; text1.size = newSize; style1.size = newSize; }

適用されているスタイルの方の設定値を変更して、オーバーライドが消えないようにしよう、という発想です。設定後はスタイルの設定も戻すので、副作用もないはず…。
段落属性の場合はcharacterStylesのところをparagraphStylesに変更します。

これが本命の解決方法になりそうな気がしますが、同じスタイルが適用されている別の場所に影響する可能性がないかなどあまり検証していませんので、自信を持ってオススメする方法とまではまだ言えないところです。

欠点

  • なさそう?(要検証)

コメントを残す

メールアドレスが公開されることはありません。