再び TeX 言語の練習問題を出してみる。
以下の要件を満たすマクロ
\replaceWordAll
を実装せよ。
実行例(LaTeX の場合)
[規約 (a) の場合] \replaceWordAll{people}{idiots} {government-of-the-people-by-the-people-for-the-people} \typeout{\result} [規約 (b) の場合] \typeout{\replaceWordAll{people}{idiots} {government-of-the-people-by-the-people-for-the-people}} % いすれの場合も次の文字列が表示されればよい. % government-of-the-idiots-by-the-idiots-for-the-idiots
解く人にとって意味があるのならば、何を使っても構わないだろう。
…といっても、LuaTeX で Lua 呼出を使うのは面白くないので、この方面の回答はさっさと済ませてしまおう。
% プレアンブル部 \usepackage{luacode} %%<*> \replaceWordAll ; 規約(b)に従う \newcommand\replaceWordAll[3]{\directlua{ zrpuz_replace_word_all(% エスケープを忘れずに \zrpuz@esc{#1}, \zrpuz@esc{#2}, \zrpuz@esc{#3}) }} \def\zrpuz@esc#1{"\luatexluaescapestring{#1}"} \begin{luacode*} -- Lua コード function zrpuz_replace_word_all (from, to, str) from = from:gsub("%W", "%%%0") -- quotemeta する -- 余分の括弧は gsub() 戻り値を単一値に限定するため tex.sprint((str:gsub(from, to))) end \end{luacode*}
expl3 で l3regex を使うのも面白くないので済ませてしまおう。*3
% プレアンブル部 \usepackage{xparse,l3regex} \ExplSyntaxOn \tl_clear_new:N \result % 結果格納変数 \tl_new:N \l_zrpuz_from_tl % from を quotemeta した結果 \tl_new:N \l_zrpuz_rxqm_tl % quotemeta 用の正規表現(コンパイル済) %% \l_zrpuz_rxqm を用意する \regex_set:Nn \l_zrpuz_rxqm_tl { \W } %%<*> \replaceWordAll ; 規約(a)に従う \cs_new:Npn \replaceWordAll #1#2#3 {% % quotemeta の処理 \tl_set:Nn \l_zrpuz_from_tl {#1} \regex_replace_all:NnN \l_zrpuz_rxqm_tl { \\\0 } \l_zrpuz_from_tl % 対象文字列の処理 \tl_set:Nn \result {#3} \exp_args:No \regex_replace_all:nnN { \l_zrpuz_from_tl } {#2} \result } \ExplSyntaxOff