読者です 読者をやめる 読者になる 読者になる

DTPオペレーター六夜のInDesignスクリプト備忘録

スクリプトを書き始めて1年足らずのDTPオペレーター六夜が、InDesign用スクリプトや食生活について書き綴ります

自動組版と謎の文字FEFF

最近はDTP作業以上に自動組版(DBパブリッシャー使用)案件の比重が増えてきて、社内で唯一の自動組版設計者としては日に日に求められることが増えてきて、やったこともないようなことや頭の中だけでうまくいってることを実務に取り入れることが多い。

テキスト文書を読み込ませて、ターゲットにその内容を流し込んでいくというスクリプトをDBパブリッシャードキュメント上で使用したところ、書き戻ししたテキストに奇妙な文字化けが…その文字化けのせいで、流し込みの結果もなんだかおかしなことに。
そしてこの文字化け、どうやっても触れない。ためしに正規表現で削ろうとしても削れない。ユニコードで検索しても引っかからない。さあ困った。


あれこれ調べてみたところ、どうやらこやつの正体はU+FEFFというコードのキャラクターで、またの名を「ノンブレークスペース」というらしい。文字ではなく制御記号ということなので、触れないし削れないのもなんとなく納得。
作業時に必ず走らせるスクリプトに以下の処理を付け加えることにした。FEFFを削除するスクリプト(といってもただ検索置換してるだけですが)

var myDoc = app.activeDocument;
    app.findTextPreferences.findWhat = "<FEFF>";
    app.changeTextPreferences.changeTo = ""
    myDoc.changeText (); //アクティブなドキュメントのみ検索対象

        app.findTextPreferences = NothingEnum.nothing;
        app.changeTextPreferences =NothingEnum.nothing; //検索置換を初期化

ニューラーメンショップ 桶川店

ラーメン

ラーメンショップは学生時代によく食べたこともあって、たまに食べるとノスタルジックな気持ちになってしまう。
時々訪れる「ラーショ行きたい発作」に負け、桶川まで車を走らせた。

ものすごく美味しいわけではないんだけど、時々無性に食べたくなる、それがラーショというもの。
とくに戸田にあったラーショ新曽店は、戸田に行くたびに立ち寄るくらいどストライクな味だった。
すべてがちょうどいい、というか自分好みの味のお気に入り店だったが、最近「イマイ帝国」という二郎インスパ系の店に変わり、私はすっかりラーショ難民になってしまった。
近くの大学に通ってた頃に埼大通り店を贔屓にしてた頃もあったけど、その店は割りと臨時休業が多く、ついでの用事でもない限りその店には行かなくなってしまった。

そんな矢先、年中無休のラーショが桶川にあるという話を聞き、行きつけラーショ候補として私の中で急浮上した。

店に着いたのが日曜の11時半くらい。混雑してるのを覚悟していたが客はほとんどいない。駐車場を共用している目の前の丸亀製麺所に客を取られているのではないか。
ニューラーメンショップ桶川店はラーショにしては広い店内で、一蘭のようにカウンターがついたてで仕切られている。一蘭ほどキッチリ仕切られているわけではないが、隣の席との間隔が広いのはうれしい。
ラーショはカウンターがゴチャゴチャしてて狭い店が多いのだ(おまけにカウンターの下の棚には漫画や新聞がつまっている。それもラーショの味わいなのだが)。

注文したのは「ネギチャーシュー小 1000円」「ネギ丼 350円」。ネギ丼て250円じゃなかったっけ? と思いつつも、頭がネギ丼になっていたのでそのまま注文。
割りとすぐに注文の品がやってきた。
ラーショの象徴である藤色の平たい丼から一口スープをすすって「これだ!」と心の中で叫ぶ。これぞラーショの味。


◆麺
あまりラーショっぽくない麺。つるつる感が強い。スーパーで売ってる生麺のような感じ。慣れの問題かもしれないがラーショにはつるつる感のない中太ストレートが合うと思った。

◆スープ
ラーショのスープはしょっぱいものが多いが、ここのはその中でもしょっぱい部類かも。スープを飲みながら食べると後半きつくなる。

◆チャーシュー
ラーショのチャーシューは割りとパサッとしたものが多いが、ここのはトロトロしている。結構好きな味。

◆その他の具
ネギはまさしくラーショのネギ。ただ意外と量が少ない

◆ネギ丼
結構量が多くてビックリ。100円値上げして量を増やしたのか? 気軽に注文できる量ではないな。とにかくしょっぱく、常食したらヤバそうなレベル。
ネギが山盛りで、ラーメンに移せばよかったかもしれない。


食べ終わる頃には塩分過多で体が悲鳴を上げていた気がする。夏場、運動をした後にはいいかもしれないな。
次に行くことがあったらネギ丼はやめて、ラーメンは味薄めにしてもらおう。

f:id:rokuyaN:20170219153131j:plain
f:id:rokuyaN:20170219153137j:plain

中浦和 つむじ

ラーメン

中浦和のつむじにてラーメンを食べました。
もともと北浦和にあったお店(当時の屋号は旋)で、その当時はいつ行ってもすんなり入店できることはほぼないほどの人気店でした。

しかし、いまは店が広くなったことを差し引いても客の入りはいまひとつ。
中浦和という立地もあるのかな? 利用する側としては空いてる方がありがたいですが。
カウンター席の間隔もゆったりめで、足元には手荷物を入れておけるカゴが置いてあります。

北浦和時代と比べるととにかく店内が広く、店員さんも四人くらいいたり…
店員さんは平均年齢が若そう。北浦和時代は創業者夫妻の家族経営みたいな感じだった気が?
とはいえ、北浦和時代にこの店に入ったことは数回しかないので、記憶に自信はありません。

入店し、券売機で「特製ラーメン 1000円」と「ミニサイズのチャーシュー丼 200円」を購入。
で、当時の記憶を呼び起こしながら味わってみました。

スープ
スープはあっさりめのダブルスープ(説明書きには「鶏」と「魚介」とある)で、ほんのり鰹節っぽい香り。
味は甘みを強く感じる。北浦和時代はもっとコクがあってクリーミーな感じだった気が…


麺の茹で加減は硬めでプリプリ感があった。あまりスープと馴染んでない印象。
おそらくこの麺はもう少し茹でた方が美味しく味わえそう。


具のチャーシューは厚みのあるやわらか肉で美味。

サイドメニュー
チャーシュー丼は鶏肉と豚肉がゴロゴロ載っているが、少し固い。
何より、香水のような人工的な風味がして少し苦手な感じだった。
なんの匂いだろう?

全体的にあまり好みではない感じでネガティブなことばかり書いてしまったが、
お店は広くて明るくていい雰囲気なので、期待しています。

f:id:rokuyaN:20170218174609j:plain

自己紹介

一応、このブログを書いてる人間についても記しておきます。

InDesign歴…CSが付く前から使っています
スクリプト歴…1年前から勉強し始めました。それ以前は「プログラムって何? うまいの?」な人間でした。VBAも少し書けるように。
仕事…DTPオペレータ、グラフィックデザイン、イラストレーション、自動組版設計、スクリプト開発
使用アプリ…InDesign(CC)、ほかアドビアプリ、Office系アプリの扱いも得意です。
対応OS…WindowsMacintoshもイケますが、Windowsの方が慣れています。このブログのコードもWindows環境で書いています。
趣味…料理、食べ歩き、ドライブ、楽器(エレキベース)も少しだけ

こんなところでしょうか。

InDesignドキュメント上の文字情報と、テキストデータの情報の比較

スクリプト関係

InDesignドキュメント上の情報と、テキストデータの内容の比較(たとえばチラシ上のすべての商品名が間違っていないかを、元データと比べっこ)して答え合わせをするスクリプトを書いてみました。
チェックする点数が多いほど、スクリプトを使うメリットがあるかも。
スクリプト歴1年の人間の書いたものなので、無駄があるのはご愛嬌。

処理としては、
 1 紙面上のすべての品名を配列に格納
 2 元データ(タブ区切りテキスト)を配列に格納
を用意し、1の中身が2の中にも存在するかをループで調べていく。仮に1の品名に誤字脱字があれば、2に存在しない品名としてアラートが出る。
アラートではなく、ログを吐き出させる処理でもいいかもしれない。

var myDoc = app.activeDocument;
var myFrame = myDoc.allPageItems;//グループ化されている可能性を考慮してall~で処理
var nameArray = [];//紙面上の品名を格納する配列
var ristArray = [];//元データの情報を格納する配列

    app.findGrepPreferences.findWhat = "\\r"; //紙面上の品名に改行があればいったん取ってしまう
    app.findGrepPreferences.appliedParagraphStyle.name == "品名の段落スタイル"
    app.changeGrepPreferences.changeTo = ""
    myDoc.changeGrep ();


for (var i=0; i<myFrame.length; i++) 
    {
        if (myFrame[i].constructor.name === "TextFrame") { //アイテムがTextFrameなら処理する 
            if (myFrame[i].parentStory.appliedParagraphStyle.name == "品名の段落スタイル") { //条件分で品名だけを処理。段落スタイルを条件にしてみた
        {
     nameArray.push (myFrame[i].contents); //格納にプッシュ
    }}}}


/////ここからはテキストデータを配列に入れていく処理
var TAB = String.fromCharCode(9); // タブコード
var fileObj = new File(File.openDialog("原稿(タブ区切りテキスト)を指定してください"));
var flag = fileObj.open("r");//読み専用
     if (flag)
      {
         var pageObj = app.activeDocument;
         count = 0;
         while(!fileObj.eof)
      {
        text = fileObj.readln(); // 1行読み込む
        ristArray = text.split(TAB); // タブコードで分割
     }}

var myList = ristArray.join ("/");//ristArrayの中身を全角スラッシュ区切りで連結

for (var k=0; k<nameArray.length; k++) {
        if (myList.indexOf (nameArray[k]) == -1) {//indexOfでリスト内に品名があるか探していく
               alert ("『" + nameArray[k] +"』 は点検リスト内に見つかりませんでした") // 見つからなければアラートを出す   
        }
}

実際には再帰処理の中に組み込んで、複数のInDesignドキュメントをまとめてチェックしています。
(改行を取る処理をしているので、saveOptionはNOで)
私の仕事では、色々使い途がありそうなスクリプトです。

[InDesignスクリプト]基本的な文字設定

スクリプト関係

テキストフレーム内の文字列に対する操作をまとめてみました。

var myDoc = app.activeDocument; //アクティブなドキュメントが対象
var myTF = myDoc.textFrames[0]; //アクティブドキュメントのテキストフレーム[1個目]が対象

/////テキストフレームの『何』を対象にするか//////////
    myTF.characters[0]; //テキストフレーム内の文字[1文字目]が対象
    myTF.paragraphs[0]; //テキストフレーム内の段落[1段落目]が対象
    myTF.contents; //テキストフレーム内の内容が対象
    myTF.parentStory; //テキストフレーム内のストーリーが対象

/////上のストーリーを変数に入れてみましょう//////////
var myStory = myTF.parentStory; //テキストフレーム内のストーリーが対象

/////以下、変数myStory内のテキストを対象に設定//////////
    myStory.appliedFont = "こぶりなゴシック Std "; //フォントを指定
    myStory.fontStyle = "W6"; //ウェイトを指定
    myStory.strokeWeight = "1 mm"; //文字の線幅を指定
    myStory.endJoin = EndJoin.ROUND_END_JOIN; //線のラウンド結合
    myStory.strokeColor = "C=100 M=0 Y=0 K=0"; //文字の線カラー
    myStory.fillColor = "Paper"; //文字の塗りカラー
    myStory.pointSize = "16Q"; //文字のサイズ
    myStory.horizontalScale = 70; //文字の長体率
    myStory.verticalScale = 50; //文字の平体率
    myStory.baselineShift = 5; //ベースラインシフト
    
/////同じ変数が何度も出てくるときにはこんな書き方も//////////
    with (myStory) {
        appliedFont = "こぶりなゴシック Std "; //フォントを指定
        fontStyle = "W6"; //ウェイトを指定
        strokeWeight = "1 mm"; //文字の線幅を指定
        endJoin = EndJoin.ROUND_END_JOIN; //線のラウンド結合
        strokeColor = "C=100 M=0 Y=0 K=0"; //文字の線カラー
        fillColor = "Paper"; //文字の塗りカラー
        pointSize = "16Q"; //文字のサイズ
        horizontalScale = 70; //文字の長体率
        verticalScale = 50; //文字の平体率
        baselineShift = 5; //ベースラインシフト
        }

[InDesignスクリプト]特定のレイヤー上のオブジェクトのみ処理対象にしたいの巻

スクリプト関係

一年前にスクリプトの勉強を始めた頃に、いきなりつまづいた部分を書いてみる。
for使ったりif使ったりしてみるもうまく行かず……答えは至ってシンプルだった。
itemByNameでレイヤーさえ指定してしまえばこっちのもん。
同じ場所でつまづくかもしれない、未来の初心者のために。

var myDoc = app.activeDocument; //アクティブなドキュメントが対象

////////////処理したいレイヤー名を代入。以降変数名でレイヤー指定ができて楽。
var targetLay = myDoc.layers.itemByName ("レイヤー 2"); 

for (var i=0; i<targetLay.pageItems.length; i++) {
     //ここにこんな風に処理を書けば指定したレイヤー上のオブジェクトのみ対象になる。
        targetLay.pageItems[i].select (SelectionOptions.addTo)//選択でもしてみる
    }


ループの条件を全ページアイテムにして、あまった分はtry catchで適当にすっとばすという横着な書き方も。

var myDoc = app.activeDocument; //アクティブなドキュメントが対象
var myFrame = myDoc.pageItems; //テキストフレームも画像フレームもただの四角も 


////////////処理したいレイヤー名を代入。以降変数名でレイヤー指定ができて楽。
var targetLay = myDoc.layers.itemByName ("レイヤー 2"); 

for (var i=0; i<myFrame.length; i++) {
    try {
     //ここにこんな風に処理を書けば指定したレイヤー上のオブジェクトのみ対象になる。
        targetLay.pageItems[i].select (SelectionOptions.addTo)//選択でもしてみる
        } catch (e) {}
    }