[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(DTPtechNote:207) Re: regex_kerning



大きな声では言えませんが、バグってました(爆)
で、バグを覆い隠すような見た目の仕掛けも用意して。。。と

さあ、不具合を見つけた人は手を挙げて〜

(*
regex_kerning
【QXPドキュメント上の任意の文字間をカーニングします。】
2002.06.10	(c)市川せうぞー	ym3s-ickw@asahi-net.or.jp
※使用OSAX
mgrep OSAX 1.7.1(http://www.bekkoame.ne.jp/~iimori/)を使用します。
Dialog Director 0.7(http://www.hylight.demon.co.uk/)
難波師匠のご指導をいただきました。

・設定テキストは「(正規表現)(正規表現)Tabカーニング量」のタブ区切りテキストであり、グループ1とグループ2の間をカーニングします。3カラム目以上は無視されます
例)
([^’”)〕]}〉》」』】・\r\n])([‘“(〔[{〈《「『【])	-100	起こし括弧類を半角に
([’”)〕]}〉》」』】])([^、。,.‘“(〔[{〈《「『【\r\n])	-100	閉じ括弧類を半角に
*)


--------------------------------------------------------●コントロールルーチン
tell current application
	activate
	display dialog "このスクリプトはQXPドキュメント上の任意の文字間をカーニングします。そのために組み版が変わる可能性があります。それでも続行しますか?"
end tell
my OpenProgress("起動チェック中", 6, "Starting up ...") --プログレスバー登場
try
	my DescribeProgress("Find osax ...")
	my UpdateProgress(1)
	my confirm_osax("mgrep.PPC", "http://www.bekkoame.ne.jp/~iimori/";) --OSAXの確認1
	my UpdateProgress(2)
	my confirm_osax("Dialog Director", "http://www.hylight.demon.co.uk/";) --OSAXの確認2
	my DescribeProgress("Version check ...")
	my UpdateProgress(3)
	my ver() --QXPバージョンのチェック
	my DescribeProgress("Document check ...")
	my UpdateProgress(4)
	my doc_open() --ドキュメントが開いてるかどうか
	my DescribeProgress("Read Preference file ...")
	my UpdateProgress(5)
	set reg_list to my read_pref() --設定の読み込み
	my UpdateProgress(6)
on error
	my CloseProgress()
	error number -128
end try
my CloseProgress() --これが正当な終わり方です
set G_counter to my do_it(reg_list)

tell current application
	activate
	if G_counter > 0 then
		display dialog "とりあえず" & G_counter & "箇所のカーニング値を変更しました。かならず確認を行ってください。"
	else
		display dialog "とりあえず、カーニング値を変更すべき箇所は見あたりませんでした。"
	end if
end tell


--------------------------------------------------------●実行ルーチン
to do_it(reg_list)
	set G_counter to 0
	tell application "QuarkXPress 3.3"
		activate
		tell document 1
			set count_box to count text box --プログレスバーのため
			set count_Len to length of reg_list --プログレスバーのため
			set count_progress to 0 --プログレスバーの初期値
			tell me to activate
			my OpenProgress("カーニング処理中", (count_box * count_Len), "Starting up ...") --プログレスバー登場
			try
				repeat with i from 1 to (count of page)
					show page i
					tell page i
						my DescribeProgress("Page" & i & "を処理中...") --プログレスバーの進捗状況
						repeat with ii from 1 to (count of text box)
							tell text box ii
								set selected to true
								repeat with iii in reg_list
									my UpdateProgress(count_progress) --プログレスバーのアップデート
									set {reg_str, my_kerning} to contents of iii
									set TXT to contents of text 1
									if TXT is not "" then --カラテキストボックスは無視する
										set ans_list to my GetPos(TXT, reg_str)
										repeat with iiii in ans_list
											set {s, e} to contents of iiii
											set properties of text from character s to character e to {kern:my_kerning}
											set G_counter to G_counter + 1
										end repeat
									end if
									set count_progress to count_progress + 1 --プログレスバーのカウンタ
								end repeat
							end tell
						end repeat
					end tell
				end repeat
			on error
				my CloseProgress()
				beep
				display dialog "QXPドキュメント処理中(do_it)にエラーがおこりました" buttons "キャンセル" default button 1
			end try
			my CloseProgress() --正当なおわり
		end tell
	end tell
	
	return G_counter
end do_it


--------------------------------------------------------★検索ルーチン(なんの汎用性もありません。。。っていうかね、こんなことしなくちゃいけないのは誰のせいなの?)
to GetPos(TXT, reg_str)
	set byte_list to {} --このサブルーチンの返り血{{スタートバイト数, 終わりバイト数}, ...}
	set start_byte to 0 --次の検索のバイト数
	repeat --無限・野本ルーチン
		set Sms to {}
		try --subMatchStrがないときでも、こうすると他のふたつは得られる。こうしないとエラーで止まる
			set {matchLen:MatchL, matchPos:MatchP, subMatchStr:Sms} to mgrep TXT regex reg_str scriptCode 1 with byteCount
		end try
		if MatchL = -1 then exit repeat --マッチなし。
		
		--ヒットした最初のグループの中の最後の文字の開始位置とバイト数を返す
		set {matchLen:chara_Len, matchPos:first_Len} to mgrep (contents of item 1 of Sms) regex ".$" scriptCode 1 with byteCount
		
		set start_byte to (start_byte + MatchP + first_Len - 1) --スタートバイト(ここから)
		set end_byte to (start_byte + chara_Len - 1) --エンドバイト(ここまで)
		set beginning of byte_list to {start_byte, end_byte} --ケツから入れテクぜ!
		set start_byte to start_byte + MatchL - first_Len --次の検索のための調整
		
		set {matchLen:MatchL2, matchPos:MatchP2} to mgrep TXT regex reg_str scriptCode 1 --こっちは文字数でのお返事。日本語の文字数としてTXTを再セット
		set TXT to text (MatchP2 + MatchL2) thru -1 of TXT --元テキストの再設定
	end repeat
	
	return byte_list
end GetPos

--------------------------------------------------------●osaxがインストールされているかどうかの確認。
to confirm_osax(osax_name, osax_URL)
	tell application "Finder"
		if not ((exists file osax_name of (path to scripting additions)) or (exists file osax_name of folder "スクリプティング機能追加" of (path to extensions folder))) then
			activate
			display dialog osax_name & "がインストールされていません" & return & "(http://www.bekkoame.ne.jp/~iimori/)"; & return & "からダウンロードしてください" with icon 0
		end if
	end tell
end confirm_osax

--------------------------------------------------------●QuarkXPress 3.3Jバージョン確認ルーチン
to ver()
	tell application "QuarkXPress 3.3"
		set QXP_ver to version
		if (QXP_ver as text) is not "3.31J" then
			activate
			beep 10
			display dialog "ゴラア!" & return & "このプログラムはVer. 3.31J以外では動作しません" buttons {"キャンセル"} with icon 2
		end if
	end tell
end ver

--------------------------------------------------------●ドキュメントが開かれているかどうか
to doc_open()
	tell application "QuarkXPress 3.3"
		if not (exists document 1) then
			activate
			beep
			display dialog "ドキュメントが開かれていません" buttons "キャンセル" default button 1
		end if
	end tell
end doc_open

--------------------------------------------------------●設定読み込み
to read_pref()
	set tmp_list to {} --{{"正規表現strings", カーニング量real}, ...}
	set F_path to (path to me) as string
	try --text fileにアクセスして情報をgetします
		set fh to open for access alias {F_path & ".pref"} --こういうトリッキーなやり方って...
		set read_list to (read fh as text using delimiter {return}) --段落を区切りにリストとして読み込み
	on error errMsg number ERRNO --ここからエラー処理
		close access fh
		if ERRNO = -39 then
			display dialog "このアップレットと同じフォルダに設定を記述したTEXTファイルが必要です" & return & errMsg & ERRNO with icon 2
			error number ERRNO
		else
			display dialog "処理は中止されました(設定読み込み中)" & return & errMsg & ERRNO with icon 2
			error number ERRNO
		end if
	end try
	close access fh
	
	--ここからさらにリスト処理
	try
		set oldDelim to AppleScript's text item delimiters --デリミッタのリストアはここで
		repeat with i in read_list
			set my_str to contents of i
			if not (my_str is "" or my_str starts with tab) then
				set {reg_str, my_kerning} to my as_split(tab, my_str)
				set end of tmp_list to {reg_str, (my_kerning) as number}
			end if
		end repeat
		set AppleScript's text item delimiters to oldDelim
		if tmp_list is {} then
			error number -128 --エラーを返して処理中止
		else
			return tmp_list
		end if
	on error
		set AppleScript's text item delimiters to oldDelim
		beep
		display dialog "設定読み込み時のリスト処理エラー" buttons "キャンセル" default button 1
	end try
end read_pref

--------------------------------------------------------★リスト化
to as_split(thedelimit, theText)
	--	set oldDelim to AppleScript's text item delimiters
	set AppleScript's text item delimiters to thedelimit
	set tmpList to every text item of theText
	--	set AppleScript's text item delimiters to oldDelim
	return tmpList
end as_split

--------------------------------------------------------●以下プログレスバー用
to OpenProgress(theTitle, theMax, aDescription) -----★プログレスバー生成(1個以上開かないようにしましょう。混乱します)
	dd install with grayscale
	dd make dialog {size:[300, 50], style:movable dialog, name:theTitle, contents:[ツ
		{class:static text, contents:aDescription, bounds:[8, 4, 290, 20]}, ツ
		{class:gauge, bounds:[10, 25, 290, 25 + 12], value:0, max value:theMax} ツ
			]}
end OpenProgress

to UpdateProgress(aValue) -----★プログレスバーのアップデート
	dd set value of item 2 of dialog 1 to aValue
	dd interact with user for max ticks 0
end UpdateProgress

to DescribeProgress(aDescription) -----★カレントワーク(進捗状況)の表示
	dd set contents of item 1 of dialog 1 to aDescription
end DescribeProgress

to CloseProgress() -----★プログレスバー後かたづけ(どんなときも必ずすること!!!特にエラーで落ちたときとか)
	dd delete dialog 1
	if (dd count dialogs) = 0 then dd uninstall
end CloseProgress