:note

アミかけにアキあけ

InDesignでテキストに下線をつかってアミかけ処理をするとき、アミかけの両脇に、四分とか八分などのアキを設ける場合があるかと思います。

「下線でアミかけ」作業は、スポイトツールや文字スタイルなどで施すことができますが、

アミかけ前・後のアキ量は一文字単位での設定になるので、

たとえば2文字のアミかけでも両脇に四分アキにするには、1文字目の「文字前のアキ量」と2文字目の「文字後のアキ量」をそれぞれいじらなくてはなりません。

アミかけにアキあけ /images/2010/09/636-aki_befor.jpg

こんなかんじ

  • アミかけ選択範囲の両端にアキを設ける。
  • 複数行にまたがるアミかけは行末・行頭それぞれのアキ処理もする。
  • 行末が追い出されたら、追従する。
  • 行末の欧文スペースは無視する。(トリプルクリックで行選択のとき)
  • 段落の終わりは無視する。(クアドラプルクリックで段落選択のとき)

そんなことを気にしながら範囲選択してアキ……となると、もう面倒。そこでスクリプトです。

アミかけにアキあけ /images/2010/09/638-aki_dialog.jpg

InDesignでのテキストの選択範囲の取り扱いは、足したり引いたりするととてもデリケート。禁則調整方式が絡んで来たりして、アキを設定していく過程で、文字流れが変わると、選択範囲のconstructor.nameが変わったり(1行のLineが追い出されて2行になるとTextになるとか)、行末の内容や改行位置も変わります。recompose()で再計算しながらの処理をしているのですが、すべての組み合せをシミュレートしているかは微妙。あと汎用性についてもかなり微妙かも。実際につかうならばダイアログをスキップして数値固定にするでしょう。

アミかけにアキあけ /images/2010/09/637-aki_afte.jpg

↑とりあえず、下線部を検索しながらスクリプトで両端にアキのつもり。2行目と7行目は追い出されて、2行に変わってます。7行目の行末の欧文スペースは無視されてます。最後の2行は改行が無視されてます。

/*
選択テキストの両脇のアキをいじる
"set Aki to both side of selected text "
使い方:
下線のアミかけ部分などの
選択テキストの両脇にそれぞれ文字前後のアキ量を設定します。
行末の欧文スペースは無視します。
選択範囲の取り方、禁則調整方式などにより思った通りにならない場合は
『アキ量を「自動」にする』にチェックをして、再度ためしてください。
動作確認:OS10.4.11 InDesign CS3
milligramme
www.milligramme.cc
*/
//おまじない
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if(app.selection.length == 1){
  var selObj = app.selection[0];
  var selWho = selObj.constructor.name;
  switch(selWho){
    case "Character":
    case "Word":
    case "Text":
    case "TextStyleRange":
    case "Line":
    case "Paragraph":
    case "TextColumn":
      akiDialog();
      break;
    default:
      alert("対象外オブジェクトです");
      exit();
  }  
}//if selections

//アキ設定ダイアログ
function akiDialog(){
  var dialogObj = app.dialogs.add({name:"両脇のアキ量を設定するん",canCancel:true});
  with(dialogObj){
    with(dialogColumns.add()){
      //アキ量を設定
      with(borderPanels.add()){
        with(dialogColumns.add()){
          staticTexts.add({staticLabel:"前のアキ量"});
        }
        with(dialogColumns.add()){
          var akiBefore = dropdowns.add({
            stringList: ["ベタ", "八分", "四分", "三分", "二分", "二分四分", "全角", "自動"], 
            selectedIndex: 2
            });
        }
        with(dialogColumns.add()){
          staticTexts.add({staticLabel:"/後のアキ量"});
        }
        with(dialogColumns.add()){
          var akiAfter = dropdowns.add({
            stringList: ["ベタ", "八分", "四分", "三分", "二分", "二分四分", "全角", "自動"],
            selectedIndex: 2
            });
        }
      }
      with(borderPanels.add()){//check box
        with(dialogColumns.add()){
          staticTexts.add({staticLabel: "アキ量を「自動」にする"});
        }
        with(dialogColumns.add()){
          var akiReset = checkboxControls.add({checkedState:false});
        }
      }//check box
    }//dialog column
  }//dialog
  //dialog の結果を変数に反映
  if(dialogObj.show() == true){
    var akiB, akiA, akiR;
    switch(akiBefore.selectedIndex){
      case 0: akiB = 0;break;
      case 1: akiB = 0.125;break;
      case 2: akiB = 0.25;break;
      case 3: akiB = 0.33333333333333;break;
      case 4: akiB = 0.5;break;
      case 5: akiB = 0.75;break;
      case 6: akiB = 1;break;
      case 7: akiB = -1;break;//自動
    }
    switch(akiAfter.selectedIndex){
      case 0: akiA = 0;break;
      case 1: akiA = 0.125;break;
      case 2: akiA = 0.25;break;
      case 3: akiA = 0.33333333333333;break;
      case 4: akiA = 0.5;break;
      case 5: akiA = 0.75;break;
      case 6: akiA = 1;break;
      case 7: akiA = -1;break;//自動
    }
    akiR = akiReset.checkedState;//trueかfalseか
    akiEnhance(akiB, akiA, akiR);//アキ量を設定Fn
    dialogObj.destroy();
  }
  else{
    dialogObj.destroy();
  }
}//dialog function

function akiEnhance(akiB, akiA, akiR){
  if(akiR == true){
    selObj.leadingAki =- 1;
    selObj.trailingAki =- 1;
    exit();
  }
  if(selObj.lines.length == 1){//1行のとき
    switch(selWho){
      case "Character":
        selObj.characters[0].leadingAki = akiB;
        selObj.characters[0].trailingAki = akiA;
        break;
      case "Word":
      case "Text":
      case "TextStyleRange":
        selObj.characters[0].leadingAki = akiB;//一文字目前のアキ
        selObj.recompose()//再計算後2行になっていたら複数行処理に移行
        if(selObj.lines.length == 2){
          break;
        }
        if(selObj.characters[-1].contents.charCodeAt(0).toString() == "13" || //改行
        selObj.characters[-1].contents.charCodeAt(0).toString() == "32"){//欧文スペース
          selObj.characters[-2].trailingAki = akiA;
        }
        else{
          selObj.characters[-1].trailingAki = akiA;
        }
        break;
      case "Line":
        selObj.characters[0].leadingAki = akiB;//一文字目前のアキ
        selObj.recompose()//再計算後2行になっていたら複数行処理に移行
        if(selObj.lines.length == 2){
          break;
        }
        if(selObj.lines[0].characters[-1].contents.charCodeAt(0).toString() == "13" || //改行
        selObj.lines[0].characters[-1].contents.charCodeAt(0).toString() == "32"){//欧文スペース
          selObj.lines[0].characters[-2].trailingAki = akiA;
        }
        else{
          selObj.lines[0].characters[-1].trailingAki = akiA;
        }
        break;
      case "Paragraph":
        selObj.characters[0].leadingAki = akiB;
        selObj.characters[-2].trailingAki = akiA;
        break;
    }//switch
  }//if line length=1
  if(selObj.lines.length >= 2){//複数行のとき
    switch(selWho){
      case "Word":
      case "Text":
      case "TextStyleRange":
      case "Line"://いらないかも
        for(var ln=0; ln < selObj.lines.length; ln++){
          selObj.characters[0].leadingAki = akiB;//1文字目
          selObj.recompose();
          if(ln != 0){
            selObj.lines[ln].characters[0].leadingAki = akiB;//2行目以降1文字目
            selObj.recompose();
          }
          if(ln != selObj.lines.length-1){//最終行以外の行末
            if(selObj.lines[ln].characters[-1].contents.charCodeAt(0).toString() == "13" || //改行
            selObj.lines[ln].characters[-1].contents.charCodeAt(0).toString() == "32"){//欧文スペース
              selObj.lines[ln].characters[-2].trailingAki = akiA;
            }
            else{
              selObj.lines[ln].characters[-1].trailingAki = akiA;
            }
          }
        }
        //最終行の行末
        if(selObj.characters[-1].contents.charCodeAt(0).toString() == "13" || //改行
        selObj.characters[-1].contents.charCodeAt(0).toString() == "32"){//欧文スペース
          selObj.characters[-2].trailingAki = akiA;
        }
        else{
          selObj.characters[-1].trailingAki = akiA;
        }
        break;
      case "Paragraph":
      case "TextColumn":
        for(var ln=0; ln < selObj.lines.length; ln++){
          selObj.lines[ln].characters[0].leadingAki = akiB;
          selObj.recompose();
          if(selObj.lines[ln].characters[-1].contents.charCodeAt(0).toString() == "13" || //改行
            selObj.lines[ln].characters[-1].contents.charCodeAt(0).toString() == "32"){//欧文スペース
            selObj.lines[ln].characters[-2].trailingAki = akiA;
          }
          else{
            selObj.lines[ln].characters[-1].trailingAki = akiA;
          }
        }
        break;
    }//switch
  }//if line length 2+
}//aki function
 
comments powered by Disqus
back to top