|
Windows XP, InDesign CS5です。
用語索引のある本を制作しています。今回、索引のページ番号をその単語が見出しの中にある場合のみ太字にしてほしいという要望があり、どのように作業をすすめようか悩んでいます。索引は、外部テキストから索引を作るJavascriptを使用して作っています。
現在考えている手順は 1. 今まで通りの索引を作る(これで抽出したページ番号をAとします) 2. 同じ索引項目を使用して見出しのみから索引を作る(スクリプトで検索オプションに見出しの段落スタイルを指定)(同じくBとします) 3. AとBを比較して、AのうちBにマッチする数字のみ太字にする。(タブ区切りテキストで書き出してExcelで 条件付き書式を設定)
これで可能かとは思いますが、どうにもスマートとは言いがたい(特に手順3)ので、使えそうなアイデアがありましたら教えていただけると助かります。 よろしくお願いします。
|
No.7148 2012/10/31(Wed) 15:16:39
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
|
Re: 索引の見出しで使用するページ番号のみ太字に / Subi |
|
|
|
杜王町民さん、ありがとうございます。 正規表現置換を複数回かける方法ですと、ページ数が20ある場合「もどし」は5回の置換ですみますが、「ばらし」は20回置換する必要があったので、スクリプト化できると大変ありがたいです。
//数字の最後の1文字を取って単語と連結し、新しい段落内容を作る for(j=1; j<separates.length;j++){ separates[j]=word+" "+separates[j].slice(0,-1)+"\r"; } この処理がよく分かりません。 文字列がabcd 00, 22, 33, 55, 111の場合、abcd 00, 22, 33, 55, 11(改行)が得られますよね。 この処理を繰り返して、数字部分のカンマやスペースがなくなり数字は2桁以上でも残るのはどうしてでしょうか?
|
No.7174 2012/11/07(Wed) 14:41:01
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
|
|
Re: 索引の見出しで使用するページ番号のみ太字に / 杜王町民 |
|
|
|
>文字列がabcd 00, 22, 33, 55, 111の場合、abcd 00, 22, 33, 55, 11(改行)が得られますよね。 >この処理を繰り返して、数字部分のカンマやスペースがなくなり数字は2桁以上でも残るのはどうしてでしょうか?
お尋ねのこの件についてお答えします。
このスクリプトの最初のキモはこのひとつ手前です。
//スペースで段落の内容を分割し、単語とノンブルに分ける separates = selStr.split(" ");
プログラムで扱うものに「配列」というのがあります。 配列そのものについてはさまざまな資料をあたっていただければと思います。 ここで、1行の文字列を1バイトスペース区切りで「ばらす」処理をしています。 selStrに「abcd 00, 22, 33, 55, 111(改行)」が入っていた場合、結果は以下のようになります。 separates[0]="abcd" separates[1]="00," separates[2]="22," separates[3]="33," separates[4]="55," separates[5]="111(+改行1文字)" ここで概ね分解はできていますが、0番目の単語以外はカンマや改行文字が邪魔ですね。 また、0番目を本文に流してしまうと、ノンブルのない単語だけの行が増えてしまいます。 そこで、本文として流す内容は 単語+1バイトスペース+「1〜5番目の要素から最後の1文字を取った内容」+改行 にすればよいということが判断できます。
>for(j=1; j<separates.length;j++){ は、配列にしたseparatesの1番目から配列の長さ全体-1番目までを繰り返し処理するループです。 「separates.length」とすると、分割された配列の「長さ/数」がわかり、0〜5までの「6個」という結果になるのですが、「6」番目の要素はないので、5までに留める処理を「j<separates.length」という形でしています。 ちなみに6番目まで含める場合は 「j<=separates.length」 と、「=」をつけます。
>separates[j]=word+" "+separates[j].slice(0,-1)+"\r"; ここで、ばらした後の1行全体を一度で組み立てます。 separates[j].slice(0,-1)というのはJavaScriptの機能で、 「sliceの直前で指定した文字列separates[j]の0番目から全体よりー1文字少ない長さの文字を抜き出す」 という動作をします。 separates[j]の内容が"00,"ですと、 0番目…0 1番目…0 2番目…, ですので、0番目から2"-1"の「1番目」までを抜き出します。 その前に単語が入っている文字列の変数「word」と1バイト巣スペース、一番最後(ノンブルの後)には改行文字を付け加え、この全体を改めてseparates[j]に代入しなおします。 なお、"111改行"であれば、 0番目…1 1番目…1 2番目…1 3番目…改行文字 となります。 最終的には「111」だけになります。 取り出す文字の長さはバラバラですから、ノンブルそのものが1桁でも3桁でも対応できるわけです。
|
No.7175 2012/11/07(Wed) 17:46:18
Mozilla/5.0 (Windows NT 6.0; rv:16.0) Gecko/20100101 Firefox/16.0
|
|
Re: 索引の見出しで使用するページ番号のみ太字に / オメガ |
|
|
|
>Subiさん テキストをばらすというのは思い付きませんでした。何より既存のスクリプトと検索置換で処理できる点が良いですね。
>杜王町民さん テキストを用意して試してみましたが、全選択では途中で参照エラーが起きました。先頭の段落から処理しているのが原因かと。 また蛇足ですが、slice(0,-1)は、separates[j]=word+" "+separates[j].replace(",","\r"); としてカンマを改行に置換すればいいのではないでしょうか。slice()はあまり使った事がなかったので勉強になりました。
さて、以前挙げたスクリプトも書いてみました(簡易版です)。一応動くと思いますが。 こちらは索引項目とページ数の間はタブ区切り、カンマの後は半角スペースを前提にしています。 ※リストBを読み込んで配列に入れるの処理は省略しています。myList配列がリストBに該当します。 ※リストAのストーリー全体を処理します。見つかったテキストの文字色をシアンに変えます。添付の図のようになります。 ※リストA内にカーソルを置くか、テキストフレームを1つ選んで実行して下さい。
var myDoc=app.documents[0]; var myStory=myDoc.selection[0].parentStory; //リストAのストーリー var myList=[ //リストBの内容 ["hogehoge","5, 20"], ["fugafuga","6, 21"] ]; //検索置換の環境設定 app.findGrep.Preferences=NothingEnum.NOTHING; app.changeGrepPreferences=NothingEnum.NOTHING; app.findChangeGrepOptions.includeLockedLayersForFind=false; app.findChangeGrepOptions.includeLockedStoriesForFind=false; app.findChangeGrepOptions.includeHiddenLayers=false; app.findChangeGrepOptions.includeMasterPages=false; app.findChangeGrepOptions.includeFootnotes=false; app.findChangeGrepOptions.kanaSensitive=true; //かなを区別 app.findChangeGrepOptions.widthSensitive=true; //大文字小文字を区別 //以下メイン処理 for(var i=0; i<myList.length; i++){ app.findGrepPreferences.findWhat="^"+myList[i][0]+"\\t"; var myMatchWords=myStory.findGrep(); //項目名で検索 if(myMatchWords.length>0){ for(var j=0; j<myMatchWords.length; j++){ var targetPara=myMatchWords[j].paragraphs[0]; //見つかったテキストを含む段落 app.findGrepPreferences.findWhat="(?<=, |\\t)("+myList[i][1].replace(/, /g,"|")+")(?=, |\\r|\\>)"; app.changeGrepPreferences.fillColor=myDoc.colors.item("Cyan"); targetPara.changeGrep(); //正規表現で置換 } } } app.findGrepPreferences=NothingEnum.NOTHING; app.changeGrepPreferences=NothingEnum.NOTHING;
|
No.7182 2012/11/09(Fri) 08:03:40
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
|
|
Re: 索引の見出しで使用するページ番号のみ太字に / オメガ |
|
|
|
検証不足でした。すみません。
24行目の、 app.findGrepPreferences.findWhat="(?<=, |\\t)("+myList[i][1].replace(/, /g,"|")+")(?=, |\\r|\\>)"; で、正規表現検索の文字列を指定しているのですが、この指定がおかしいようです。 (?<=, |\t)(5|20)(?=, |\t|\>)としているのですが、肯定後読みのタブが無視されるようですね。
どこかで見たような…と思ったら、せうぞーさんが以前記事にされていました。ありがとうございます。 http://d.hatena.ne.jp/seuzo/20110402#20110402f2
また肯定先読みの方は単語の終わり(\>)を入れると、カンマも改行も意味がないことに気付きました。これは最終段落に改行が抜けていた場合を想定して入れています。
以上をふまえて24行目を、 app.findGrepPreferences.findWhat="(?<=, )("+myList[i][1].replace(/, /g,"|")+")(?=\\>)"+"|"+"(?<=\\t)("+myList[i][1].replace(/, /g,"|")+")(?=\\>)"; としてはいかがでしょうか。 それでも索引項目に同様の書式がある可能性はゼロではないので注意が必要ですね。
他にも問題点等ありましたらご指摘いただけると幸いです。
|
No.7187 2012/11/09(Fri) 22:33:57
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
|
|
Re: 索引の見出しで使用するページ番号のみ太字に / オメガ |
|
|
|
>杜王町民さん 項目が必ずしも英単語のみとも言い切れないですし、 InDesign CS 5 11, 12, 13 ならCSの後にタブが入ってしまいます...
他にも方法はあると思いますが、たとえば 1.カンマ+スペース(, )をカンマ2つ(,,)に置き換えます。 2.最初のページ番号から行末までは数字とカンマのみ(と改行)になるので、行末から最初に出てくるスペースを正規表現でタブに置き換えます。 検索:\s(?=[0-9,]+\r) 置換:\t 3.カンマ2つを元に戻します。 という手順でほぼ確実に置き換えられると思います。
あー、正規表現でもいけそうですね。 ページ番号が ・1つしかない場合 XXXX \d+\r ・2つ以上ある場合 XXXX (\d+, )+\d+\r ページ番号間のスペースの前は必ずカンマ→項目名の末尾はカンマではない とすると (?<!,)\s(?=(\d+, )*\d+\r) をタブに置き換えればいいのではないでしょうか。
|
No.7191 2012/11/10(Sat) 14:09:58
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
|
|