再び 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