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

(DTPtechNote:323) Easy-Find-Replace



(*
Easy-Find-Replace
【InDesignドキュメント上のテキストの連続置換】
2002.10.08	(c)市川せうぞー	ym3s-ickw@asahi-net.or.jp
※使用OSAX
Dialog Director 0.7(http://www.hylight.demon.co.uk/)

このアップレットと同じ階層に「Easy-Find-Replace.pref」ちう名前の検索置換テキストを用意する。様式は
検索文字列(tab)置換文字列
でOK。あとは、処理対象ドキュメントを開いて置いてアップレットをダブルクリックするだけ
*)


--------------------------------------------------------●コントロールルーチン
--★警告
tell current application
	activate
	display dialog "このスクリプトはInDesignドキュメント上のテキストの連続置換をします。そのために組み版が変わる可能性があります。それでも続行しますか?"
end tell

--★起動チェック
my OpenProgress("起動チェック中", 6, "Starting up ...") --プログレスバー登場
try
	my DescribeProgress("Find osax ...")
	my UpdateProgress(1)
	my confirm_osax("Dialog Director", "http://www.hylight.demon.co.uk/";) --OSAXの確認1
	my DescribeProgress("Version check ...")
	my UpdateProgress(2)
	my ver() --バージョン確認
	my DescribeProgress("Document check ...")
	my UpdateProgress(3)
	my doc_exists() --ドキュメントが開かれているかどうか
	my DescribeProgress("story count ...")
	my UpdateProgress(4)
	set story_cun to my story_count() --story数のcount 
	my DescribeProgress("Read Preference file ...")
	my UpdateProgress(5)
	set pref_list to read_pref() --{{検索文字列, 置換文字列}, {検索文字列, 置換文字列}, .....}
	my UpdateProgress(6)
on error
	my CloseProgress()
	error number -128
end try
my CloseProgress() --これが正当な終わり方です

--★実行
set count_hit to my do_it(pref_list, story_cun)


--★終了ダイアログ
tell current application
	activate
	if count_hit > 0 then
		display dialog "とりあえず" & count_hit & "箇所の置換を実行しました"
	else
		display dialog "とりあえず、置換すべき箇所は見あたりませんでした。"
	end if
end tell


--------------------------------------------------------●置換実行ルーチン
to do_it(pref_list, story_cun)
	set count_hit to 0 --置換成功数
	set count_progress to 0 --プログレスバーのためのカウンタ
	my OpenProgress("置換実行中", ((length of pref_list) * story_cun), "処理開始 ...") --プログレスバー登場
	try
		repeat with i in pref_list
			set {find_text, change_text} to contents of i
			my DescribeProgress(find_text & " => " & change_text)
			tell application "InDesign 2.0.1J"
				set find preferences to nothing -- 既存の検索環境設定を初期化します。
				set find text of find preferences to find_text
				
				set change preferences to nothing -- 変更環境設定を初期化します。
				set change text of change preferences to change_text
				tell document 1
					repeat with i from 1 to story_cun
						set count_progress to count_progress + 1
						my UpdateProgress(count_progress)
						set hit_object to search story i with change attributes {change text:change_text}
						try --searchコマンドはなにもヒットしないとなにも返さない。ヴォ〜け!!!
							set count_hit to count_hit + (length of hit_object)
						end try
					end repeat
				end tell
			end tell
		end repeat
	on error
		my CloseProgress()
		error number -128
	end try
	my CloseProgress() --これが正当な終わり方です
	return count_hit
end do_it





--------------------------------------------------------●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 & osax_URL & return & " からダウンロードしてください" buttons {"キャンセル"} with icon 0
		end if
	end tell
end confirm_osax


--------------------------------------------------------●InDesignバージョン確認ルーチン
to ver()
	tell application "InDesign 2.0.1J"
		if version is not 2.01 then
			activate
			beep 10
			display dialog "このプログラムはInDesign2.0.1以外では動作しません" buttons {"キャンセル"} with icon 2
		end if
	end tell
end ver

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

--------------------------------------------------------●story 数を返す
to story_count()
	tell application "InDesign 2.0.1J"
		tell document 1
			set story_cun to count story
			if story_cun = 0 then
				activate
				beep
				display dialog "このドキュメントには文字が含まれていません" buttons "キャンセル" default button 1
			end if
		end tell
	end tell
	return story_cun
end story_count


--------------------------------------------------------●設定読み込み
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 {str_1, str_2} to my as_split(tab, my_str)
				set end of tmp_list to {str_1, str_2}
			end if
		end repeat
		set AppleScript's text item delimiters to oldDelim
		if tmp_list is {} then
			error number -128 --エラーを返して処理中止
		else
			set AppleScript's text item delimiters to oldDelim
			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