他所にあるすこし古いMacOS(開発環境なし)でワンライナーを使ってUTF-16LE with BOMを生成(タイトルなげーよ)

都内某所の制作事務所での要望:
InDesignのタグテキストをUnicodeネイティブで取り込みたいんだけど、どうすればいいの?

 InDesignのタグテキストでUnicodeネイティブで取り込むには、UTF-16LE(あるいはUTF-16BE) with BOMである必要があります。

 ですから、nkfコマンドを使って

$ nkf -w16L original.txt > output.txt

でよいのでは? はい終了。

 え? nkfないですって? じゃあApple Developers Toolsをインストールすると自動的にgccなんかの開発環境も入るからソースからコンパイルしてください*1 ん? 管理者の許可? そ、そんなこと自分で言ってくださいよ。ぼくは部長さん怖いので言い出す勇気ないですよ。第一、MacOS10.5.8とかってどのバージョンのDevTools入れればいいかわかんないし...(逃げ腰)。

 そうだiconvコマンドを使いましょう。iconvならMacOSのデフォルトで入ってるから、怒られる心配ありません! ←重要

$ iconv -f UTF-8 -t UTF-16LE original.txt > output.txt

 これでいいんじゃないですか? え?BOMがついてない? BOMがついてないとInDesignのバージョンによってはタグテキストとして認識されない、と。*2

 むう... ついてないならsedで後付けすればいいじゃん!

$ iconv -f UTF-8 -t UTF-16LE original.txt | sed '1s/^/\xfe\xff/' > output.txt

 おお、ストリームエディタの面目にゃくにょ(いえてない)。んが、BOMじゃなくファイル先頭に文字として「xfexff」が付いちゃってますがな。引用符をシングルクォーテーションからダブルクォーテーションに変えても制御文字に展開してくれない。よくよく調べたら、bashのクォートってそういうものらしい。すなわち、

$ iconv -f UTF-8 -t UTF-16LE original.txt | sed $'1s/^/\xfe\xff/' > output.txt

と書けばよいわけですね。


 そもそものタグ付けやテキスト処理をrubyでやるなら、こんな感じのシェル芸でワンライナーになります。よき!

$ ruby thisfile.rb original.txt | iconv -f UTF-8 -t UTF-16LE | sed $'1s/^/\xff\xfe/' > tag.txt

 最後に...

 このブログほったらかしでぜんぜん更新してないですが、とりあえずせうぞー死亡説だけは否定しておきます。

*1:パッケージとか使ってる人は macにnkfコマンドがないだと!?じゃあ入れよう! - Qiita あたりを参考にしてください

*2:InDesign CS6だと、iconvの書き出したUTF-16LEでも取り込めました

ブログ用の高圧縮(低品質)、Exifなし画像を生成する

 最近は携帯電話のカメラ画質がよくなって、iPhoneとかで撮った画像ってそのままだと3MB〜5MBくらいあります。結構重いですよね。さらに、位置情報などのExif情報が’ついたままブログやSNSにアップロードするのはセキュリティ上好ましくありません。*1

 印刷・デザイン・Web関係者だったら、手持ちのPhotoshopを使ってこういう処理をするためのドロップレットとかを作れますよね。じゃあ、Photoshopをもっていない人はどうすればいいの? GIMPとかでひとつづつチマチマ再保存するしかないんでしょうか?

 今回はImageMagickAppleScriptを使って、ドラッグ&ドロップするだけで画像の再圧縮とExif削除をさせてみたいと思います。原理としては

$ convert -quality 20 -strip orginal.jpg new.jpg

みたいな感じのコマンドをドラッグ&ドロップでできるようにAppleScriptで包みました。*2

 このままでもいいんですが、もうひと工夫。はてなブログは専用のメールアドレスに添付ファイルとして送るとFotolifeにアップロードできます*3。生成した画像をMail.appで送るところまでやってみました。最初のsend_toにメールアドレスを書き込めば添付ファイルにしてくれます。

(*
MakeBlogImage.app
ドラッグ&ドロップで、ブログ用の低クオリティexif無し画像を生成する
要:ImageMagick
具体的にはImageMagickで
convert -quality 20 -strip orginal.jpg new.jpg
を実行する感じ。
メールアドレスを設定すれば、生成画像をそこへ送りつける。(はてなブログのFotolifeでメールアップロード)


2017-02-15	macOS Sierra(10.12.3)とりあえず
*)


--ドラッグ&ドロップで実行
on open of drop_files
	--設定
	set imagemagick_path to "/usr/local/bin/convert" --convertコマンドのフルパス
	set my_quality to "20" --クオリティ(1-100)
	set other_option to "" --その他オプション(最後はスペースを入れること)
	set send_to to "" --送り先メールアドレスが書かれていれば、Mail.appを使って生成した画像を送る(主にはてな用)
	set send_from to "" --Mail.appに設定してある送り主のメールアドレス(意味のない文字列の場合、最初に設定されているメールアドレスが使われる)
	set attachmentFile_list to {} --初期化してるだけ
	
	--ImageMagickがインストールされているかどうか
	try
		do shell script imagemagick_path & " --version"
	on error errMsg number errNo
		display dialog "ImageMagickがインストールされていません" & return & errMsg & return & errNo buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
	end try
	
	--ファイルのフィルタリング(特定の拡張子を持ったファイルだけを処理)
	set my_files to my file_kind({"jpg", "jpeg", "png"}, drop_files) --拡張子のリスト、処理ファイル	
	set save_folder to choose folder with prompt "保存先フォルダを選んでください"
	
	repeat with i in my_files
		my violation_name(i as alias)
		set path_info to my split_path(i as alias)
		set org_path to POSIX path of (i as alias)
		set new_path to (POSIX path of save_folder) & (name_ext of path_info)
		if org_path is new_path then
			display dialog "同じフォルダには上書き保存できません。" buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
		end if
		my alert_same_name(new_path)
		
		--画像生成
		try
			do shell script imagemagick_path & " -quality " & my_quality & " -strip " & other_option & (quoted form of org_path) & " " & (quoted form of new_path) --実行
		on error errMsg number errNo
			display dialog "実行エラーです" & return & errMsg & return & errNo buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了
		end try
		tell application "Finder"
			set end of attachmentFile_list to new_path
		end tell		
	end repeat
	
	--メール送信
	--はてなFotolifeは連続2通までしか受信できないっぽい
	if send_to is not "" then
		set my_subject to (do shell script "date '+%Y-%m-%d-%H%M'") --現在の日時をsubjectにしてる
		set my_body to ""
		my send_mail(send_to, send_from, my_subject, my_body, attachmentFile_list)
	end if
	
	
	--終了の合図
	tell application "Finder"
		activate
		display dialog ((count my_files) as Unicode text) & "個のファイルを処理しました。" buttons {"OK"} default button 1
	end tell
end open


----------------------------------------------●必要なファイルだけをフィルタして返します
to file_kind(extention_list, theFiles)
	set my_files to {}
	
	ignoring case
		tell application "Finder"
			repeat with i in theFiles
				if extention_list contains ((name extension of i) as Unicode text) then
					set end of my_files to contents of i
				else if (kind of i) is "フォルダ" as Unicode text then
					--activate
					--display dialog "フォルダ「" & (name of i) & "」の中の全ファイルを処理します" buttons {"キャンセル", "OK"} default button 2 with icon 0
					set my_files to my_files & my file_kind(extention_list, every file in folder i)
				else
					--activate
					--display dialog "ファイル「" & (name of i) & "」は処理ファイルとして不適当です" buttons {"キャンセル", "OK"} default button 2 with icon 0
				end if
			end repeat
		end tell
	end ignoring
	return my_files
end file_kind

----------------------------------------------●
--フルパス名を、コンテナディレクトリ・ファイル名+拡張子・ファイル名・拡張子に分割する
--返値はPOSIX pathのレコード {dir:"", name_ext:"", f_name:"", ext:""}
to split_path(f)
	set f to quoted form of ((POSIX path of f) as Unicode text) --まずPOSIX pathにする
	set d to do shell script "echo " & f & " | perl -pe 's/^(.+\\/).+$/$1/;'" --コンテナディレクトリ
	set ne to do shell script "echo " & f & " | perl -pe 's/^.+\\/(.)/$1/;'" --ファイル名+拡張子
	if f ends with "/'" then --フォルダの場合
		set n to text 1 thru -2 of ne
		set e to ""
	else
		set e to do shell script "echo '" & ne & "' | perl -pe 's/^.+(\\..+)$/$1/;'"
		if e is not "" then
			set n to do shell script "echo '" & ne & "' | perl -pe 's/" & e & "$//;'"
		end if
	end if
	
	return {dir:d, name_ext:ne, f_name:n, ext:e}
end split_path

----------------------------------------------●
--同名ファイルの警告
to alert_same_name(file_path)
	tell application "Finder"
		if (exists (file_path as POSIX file)) then
			display dialog file_path & " は同名のファイルがあります" & return & "上書きしますか?" buttons {"キャンセル", "上書き"} default button 1 with icon 1 --キャンセルで終了
		end if
	end tell
end alert_same_name

----------------------------------------------●
--ファイル名の警告
to violation_name(file_path)
	set file_path to quoted form of ((POSIX path of file_path) as Unicode text) --まずPOSIX pathにする
	set file_path_test to do shell script "echo " & file_path & " | perl -pe 's/[\\/\\.0-9A-Za-z _-]+//;'"
	if (file_path_test is not "") then
		display dialog file_path & " のファイルパスに英数字以外の文字が使われています。" & return & "処理トラブルになるかもしれません。続行しますか?" buttons {"キャンセル", "続行"} default button 1 with icon 1 --キャンセルで終了
	end if
end violation_name

----------------------------------------------●
--メール送信
to send_mail(send_to, send_from, my_subject, my_body, my_attachmentFile)
	tell application "Mail"
		--activate
		set my_Message to make new outgoing message with properties {subject:my_subject, content:my_body & return & return, visible:false}
		tell my_Message
			set sender to send_from
			try
				make new to recipient at end of to recipients with properties {address:send_to}
				if class of my_attachmentFile is list then --複数の添付ファイル
					repeat with aFile in my_attachmentFile
						make new attachment with properties {file name:aFile} at after the last word of the last paragraph
						delay 3 --待ち時間を入れないとファイルが添付されない。
					end repeat
				else
					make new attachment with properties {file name:my_attachmentFile} at after the last word of the last paragraph
					
					delay 3
				end if
				send
			on error errmess
				display dialog my_subject & "の送信に失敗しました。" buttons {"キャンセル"} default button 1 with icon 1 --キャンセルで終了 
			end try
		end tell
	end tell
end send_mail

 AppleScriptでMail.appの添付書類を送る時、リストで渡せない。1ファイルづつrepeatしてattachmentを生成しないといけないっぽい。さらに添付してすぐにsendすると添付されてないまま送られちゃうのだ。ぐぬぬ...

*1:サービスによってはExif削除してくれるものもあるけど、そのまま垂れ流してるものあるよね... 大丈夫なの。あれ?

*2:ターミナルでImageMagickのmogrifyコマンド使うっていう方法もありますけど、まあ、コマンド打ちたくない... 省力化ですよ^^

*3:Web上からのアップロードってファイル数の制限があってやたら待たされるんですよね...

パスワードをそのままメールで送らないでください。

 FTPサーバーなどを使うとき、パスワードなどのログイン情報がメールで送られてきたりしますよね。あれ、あまり感心できることじゃないんです。メールって「はがき」みたいなものだから、配達してる人たちには読めてしまうシステムなんです。そしてメールを配達してる人は郵便とちがって公務員に準じた身分ではありませんし、(すべての配達員に)秘守義務もありません。重要なビジネスメールがこっそり覗き見られて、2chなどに書き込まれてしまうことも(原理上)あり得るんです。
 じゃあ、どうしたら通信の秘密を守れるの? パスワードをメールで安全に伝える方法はあるの? という疑問が浮かびますよね。もちろんあります。公開鍵暗号と呼ばれる暗号方式で、メールの内容を暗号化しちゃえばいいのです。


 前段はこれぐらいにして、いきなり本題に移ります。
 今年の年始にマシンをリプレイスしまして、以前から使っていたGPG*1を再導入するのに「GPGTools」を使いました。GPGToolsの「GPG Suite」はMac OS X上でGPG環境を整備するパッケージになっています。

 ぼくが知らなかっただけなのかもしれませんが、これがもうめちゃくちゃ簡単なんです。ビックリしました。GPGってターミナル上でコマンドを使った操作が多かった(それゆえに敬遠されていた)んですが、ターミナルもコマンドも一切使いません。普通のアプリケーションのように「GPG Suite」をダウンロードしてインストールするだけです。導入から普段使いまですべてGUIで操作できます。「GPGってムツカシイ(めんどくさい)んでしょ」って言葉はもう過去の言い訳になっています。簡単な導入方法と使い方は下記のページを参照してください。

 パッケージのインストールが完了すると、いきなり鍵生成が始まりますが、ここでひとつ設定しておきたい箇所があります。新しい鍵を作るダイアログの下に「▶Advanced options」の「▶」部分をクリックして「Length:」を「4096」にしておきましょう*2。また、公開鍵をキーサーバーに登録して検索して使ってほしいひとは「Uplode public key after generation」にチェックを入れておきましょう*3


 GPGToolsがすごいのは、導入が簡単なだけじゃありません。Mac OS標準のMail.appにプラグインがインストールされて、メッセージの暗号化がクリックひとつでできます。

 暗号化されたメッセージを受け取ると、パスフレーズを入力ダイアログが開いて復号化します。

 Mail.appだけじゃなく、Gmailなどでもメッセージを選択してコンテキストメニューから暗号化/復号化ができます。


 システム環境設定には「GPGPreferences」があり、ツールのアップデートも自動的に行えるようになっています。
 このように導入・運用・保守が簡単に行える「GPGTools」を導入しない理由はありません。もしむりむり問題を見つけるとするなら、「秘密のメッセージ」をやりとりできる友達がいないということだけでしょう。
 …ということで、ぼくの新しい公開鍵はこちらになります。

fingerprint(指紋) = E000 1AC4 AD58 34C6 6C8F B1E1 999D 20A7 2B4A D3C9


キーサインパーティ

 GPG/PGPには公的な認証局がないので、キーサーバーで検索した公開鍵をそのまま信用できるとは言えません。もちろん、身内でよく知ってる人同士でやり取りする分には差し支えないのですが、ネット上では「顔も見たことがない人」とビジネスすることもあり得ます。そこでオフラインで(リアルに会って)鍵交換を行う「キーサインパーティ」が開かれ、信頼のチェーンをたくさんつないでいく「Web of Trust」が広がっています。

 キーサインパーティの流儀として、印刷されたfingerprintや、政府が発行する顔写真入りの運転免許証(またはパスポートなど)が必要になります。事前によく確かめて、機会があればいってみたいと思っています。

*1:公開鍵暗号方式PGPやGPGといった実装で呼ばれています

*2:鍵の長さが暗号の強さを表します。以前は1024が主流でしたが、キーサインパーティなどでは2048以上が推奨されており、現在は4096が主流のようです。

*3:キーサーバーへの登録はあとからでもできます

xreaサーバーでrubyのTwitterライブラリを使ってSSLエラーの対処メモ

 昨日、xreaのサーバーにruby1.9.3をインストールしたのは、Twitter API 1.1対応のTwitterライブラリを使いたかったからなんです。で、ふつーにgem install twitterで入れて、さあここからつぶやき放題だぜ...と思ったらこんなエラーにお出迎えされました。じぇじぇじぇ。

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (Twitter::Error::ClientError)

 で、ふつーの対処法ならこれだと思います。

 xreaのサーバーですと...

ruby19 -ropenssl -e 'p OpenSSL::X509::DEFAULT_CERT_FILE'
"/usr/local/openssl/cert.pem"

ってことになってます。ちなみに指し示されたファイルはありません。うちは間借りしてるだけのユーザーなので、この場所になにかを入れたり出したりできません!
 以下、苦し紛れの対処法です。流儀としてすごく間違ってるかもしれません。net/httpsでちゃんと書くべきなのかも。

~/.bashrcに書き込む

 TwitterのCA証明書ファイルの取得方法は以下を参考にしました。

 この証明書ファイルを~/.bashrcに環境変数SSL_CERT_FILEとして書き込むことでエラーを回避できました。下記の1行を~/.bashrcに追加します。

export SSL_CERT_FILE=/virtual/ユーザー名/パス/twitter.pem

 参考にしたのはこちら

 だが、しかし...

cronを使う時は

 cronを使う時は~/.bashrcを読みません。定期的に何度も犯している間違いでデジャヴ感まんさい。
 なのでcrontabで指定しているshell script内で

env SSL_CERT_FILE=/virtual/ユーザー名/パス/twitter.pem スクリプトの呼び出し

としてみました。やれやれ。

xreaのサーバーにruby1.9.3をインストールしたメモ

 xreaさんのrubyのバージョンは1.8.5ですね。使いたいライブラリ関係もあってちょっと窮屈に思っていました。もしかしてコンパイルできる? と思ってやってみたらできちゃったコンみたいなのでメモしておきます。CORESERVERでもないし、たぶん推奨されていないことだと思うので自己責任でお願いします。*1
 インストール場所は~/local/bin/ruby19みたいな感じになるようにします。

yamlをインストール

 まず、 LibYAMLをインストールします。

mkdir ~/src
cd ~/src #ソースをダウンロードしたりコンパイルしたりする場所
wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
tar zxf yaml-0.1.4.tar.gz
cd yaml-0.1.4
./configure --prefix=$HOME/local/yaml/ #./configureやmakeの途中でKilledされることがあります。挫けずにぶつかっていきまっしょい。
make
make install

 yamlが未インストールのままrubyコンパイルをしてしまうと、のちのち

It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.

と怒られてしまうので、先にインストールしました。

rubyのインストール
cd ~/src
wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p429.tar.gz
tar zxf ruby-1.9.3-p429.tar.gz
cd ruby-1.9.3-p429
./configure -prefix=$HOME/local --program-suffix=19 --disable-install-rdoc --with-opt-dir=$HOME/local/yaml/
make
make install

 --disable-install-rdocとしないと、

Directory .ext/rdoc already exists, but it looks like it isn't an RDoc directory.

Because RDoc doesn't want to risk destroying any of your existing files,
you'll need to specify a different output directory name (using the --op

option)

と怒られてしまいましたので、断念しました。
 --program-suffix=19 としているので、今回インストールしたrubyは「ruby19」「gem19」などとなります。

パスを通す

 ~/.bashrcを編集してパスを通しておきます。実際にはviでやってますが下記のように追記してもかまいません。

echo "PATH=$HOME/local/bin:$HOME/local/lib/ruby/1.9.1" >> ~/.bashrc
source ~/.bashrc #更新

 下記のようにバージョンが返ればインストール完了です。

xxxxx~> ruby19 -v
ruby 1.9.3p429 (2013-05-15 revision 40747) [i686-linux]
xxxxx~> gem19 -v
2.0.3

*1:ちょっと前だと60秒以上のプロセスはkillされてたような気が...

rubyの正規表現の複数行モード

 きょうふと、自分がへんな思い込みをしていることに気がつきました。
 恥ずかしいったらないんだけど、もしかして同じことを思ってる人がいるかもしれないので書いておきます。


 どんな思い込みかというと...
改行を含む複数行の文字列に対してruby正規表現で検索置換をする時、改行文字で区切られた行の行頭「^」や行末「$」を使うには、m修飾子が必要だという誤解です。ワンライナーで書くと

ruby -e 'puts "aa\nbb\ncc\n".gsub(/^/, "M")'

の結果が

Maa
bb
cc

だと思ってた。

Maa
Mbb
Mcc

という結果を得るには

ruby -e 'puts "aa\nbb\ncc\n".gsub(/^/m, "M")'

と書かないといけないと思っていたんです。まじすいません。
 そういう誤解を醸成したのは、perlの複数行モードをイメージしていたからでしょう。perlでは文字列に含まれる改行文字の直前の行頭にマッチさせるにはm修飾子が必要なんだよね。上記の例でいうと

perl -e '$_ = "aa\nbb\ncc\n";s/^/M/mg; print $_;'

と書かなければいけません。と、とりあえず他人のせいにしておくモード^^


 じゃあ、rubyのm修飾子ってなんなの? と思う方もおられるでしょう。
 リファレンスマニュアルに書かれている通りですが、rubyのm修飾子は正規表現で「.」が改行を含むようになるオプションです。*1

ruby -e 'puts "<p>\nhogehoge\n</p>\n".sub(/^<p>(.+)<\/p>/m){$1}'

 つまり、行頭「^」や行末「$」の位置とはまるで関係ないんですな。m修飾子とは関係なく、文字列全体の先頭にマッチさせたければ「\A」を、最終にマッチさせたければ「\z」または「\Z」(文字列が改行で終っていればその改行の直前)を使います。


 もうひとつ生き恥を晒しておきますと、この思い込みに気がついたきっかけは、下記のようなスクリプトを書いてる途中に、なぜか2行目(あとで消そうと思ってた)がマッチしてしまっていたからです。じぇじぇ!

$_.sub!(/^(<h\d)/){"<!-- 見出し -->\n#{$1}"}
$_.sub!(/^<h1.*?>(.+)<\/h1>$/){"= #{$1}"}

 いままで、なぜ気がつかなかったのか、つくづく情けないことだなあ(詠嘆)。


参照

詳説 正規表現 第3版 p107「3.3.4.3 ドット全マッチモード(単一行モード)」、p.108 「3.3.4.4 拡張行アンカーマッチモード(複数行モード)」
Rubyist Magazine - 標準添付ライブラリ紹介 【第 14 回】 正規表現 (3)

*1:ちなみに(混乱するかもしれませんが)、同じ結果を得るためにはperlだとs修飾子(単一行モード)を使います。perl -e '$_ = "

\nhogehoge\n

\n";s/^

(.+)<\/p>/$1/s; print $_;'

正規表現スタイル由来の文字スタイルをリアル文字スタイルとして適用する

 緊デジ対応の電子書籍(データ有)を作成する時、IDML経由にしろ、タグマッピングでXML経由にしろ、InDesign上の正規表現スタイルは全無視されてしまいます。そこで、段落スタイルで設定されている正規表現スタイルを順番に検索置換し、リアル文字スタイルを適用します。
 コードを見ればわかるとおり、段落スタイルの中の正規表現スタイルだけを見ます(段落スタイルに書かれていない正規表現スタイルは無視します)。オーバーライドされた文字スタイルは考慮しません。正規表現スタイルが重複している場合は、最後のスタイルだけを適用します。なお、このスクリプトはドキュメントを破壊的に変更しますので、適用後のドキュメントは保存しないようにしてください。

/*
    Apply_CharStyle_of_RegexStyle_origin.jsx
    段落スタイルに設定されている正規表現スタイル由来の文字スタイルをリアル文字列に適用します。
    段落スタイルに書かれていない正規表現スタイルは無視します(段落スタイルの中の正規表現スタイルだけを見ます)。オーバーライドされた文字スタイルは考慮しません。
    正規表現スタイルが重複している場合は、最後のスタイルだけを適用します。
    いうまでもなく、このスクリプトはドキュメントを破壊的に変更します。
    
   
    2012-06-24  とりあえず
*/

#target "InDesign"

////////////////////////////////////////////エラー処理 
function myerror(mess) { 
  if (arguments.length > 0) { alert(mess); }
  exit();
}

////////////////////////////////////////////正規表現検索置換
/*
my_range	検索置換の範囲
my_find	検索オブジェクト ex.) {findWhat:"(わたく?し|私)"}
my_change	置換オブジェクト ex.)  {changeTo:"ぼく"}

my_changeが渡されない時は検索のみ、マッチしたオブジェクトを返す。
my_changeが渡されると置換が実行されて、返値はなし。
*/
function my_RegexFindChange(my_range, my_find, my_change) {
    //検索の初期化
    app.findGrepPreferences = 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;//全角半角を区別するかどうか

    app.findGrepPreferences.properties = my_find;//検索の設定
    if (my_change == null) {
        return my_range.findGrep();//検索のみの場合:マッチしたオブジェクトを返す
    } else {
        app.changeGrepPreferences.properties = my_change;//置換の設定
        my_range.changeGrep();//検索と置換の実行
    }
}



/////実行
    var my_attention = confirm("Apply_CharStyle_of_RegexStyle_origin.jsx\r    段落スタイルに設定されている正規表現スタイル由来の文字スタイルをリアル文字列に適用します。\r    段落スタイルに書かれていない正規表現スタイルは無視します(段落スタイルの中の正規表現スタイルだけを見ます)。オーバーライドされた文字スタイルは考慮しません。\r    正規表現スタイルが重複している場合は、最後のスタイルだけを適用します。\r    いうまでもなく、このスクリプトはドキュメントを破壊的に変更します。");
    if (my_attention === false){exit()};//「いいえ」ボタンで終了

if (app.documents.length === 0) {myerror("ドキュメントが開かれていません")}
var my_doc = app.documents[0];

var my_paragraph_styles = my_doc.allParagraphStyles;
for (var i = 1; i< my_paragraph_styles.length; i++) {//0番地は、「[段落スタイルなし]」
    if (my_paragraph_styles[i].nestedGrepStyles.length >0) {
        for (var ii =0; ii < my_paragraph_styles[i].nestedGrepStyles.length; ii++) {
            var my_regex_style = my_paragraph_styles[i].nestedGrepStyles[ii];//正規表現スタイル
            var my_regex = my_regex_style.grepExpression;//正規表現
            var my_char_style = my_regex_style.appliedCharacterStyle//文字スタイル
            my_RegexFindChange(my_doc, {findWhat:my_regex, appliedParagraphStyle:my_paragraph_styles[i]},{appliedCharacterStyle:my_char_style});
        }
    }
}

先頭文字スタイル*1とか、先頭行スタイルとか、どうするんだ... って思いません? ぼくも思います。「繰り返し」がなかったらできると思います*2。思うだけ。

*1:(追記:2012-07-09T11:38:52+0900)先頭文字スタイルについては、スタイルをタグにマップでタグづけできるようす。see also. http://densyodamasii.com/先頭文字/先頭行/正規表現スタイルの処理を考/

*2:あ、先頭文字スタイルは(テキスト検索の)ワイルドカード表現互換だからそれも痛いです