
文字列を個々の文字に分割し、各文字を個別に変換してから、それらを再び結合したいと考えています。
このようなもの:
\newcommand{\drawaboxaroundit}[1]{...}
\newcommand{\glue}{+}
\explodethenjoin{abcdef}{\drawaboxaroundit}{\glue}
どのように機能するかを簡単に説明すると\drawaboxaroundit
(これは単なる説明であり、実際に行っていることではありません)、この例の結果は次のようになります。
意図は\explodethenjoin{abc}{\drawaboxaroundit}{\glue}
拡大する
\drawaboxaroundit{a}\glue\drawaboxaroundit{b}\glue\drawaboxaroundit{c}
私の問題はほぼ解決しましたこの答え(私は expl について基本的に何も知らないので、それがどのように機能するか理解していませんが) -- これは各文字を個別に処理しますが、文字間に接着剤を配置しません。
一つのアプローチ(私には良いデザインとは思えないが)は、その位置を意識することだ。\drawaboxaroundit
つまり、上記のabc
例は次のように展開される。
\drawaboxarounditwrapper{0}{\glue}{a}\drawaboxarounditwrapper{1}{\glue}{b}\drawaboxarounditwrapper{2}{\glue}{c}
\drawaboxarounditwrapper
次のように定義されます
\newcommand{\drawaboxarounditwrapper}[2]{
\ifthenelse{\equal{#1}{0}}{}{\glue}
\drawaboxaroundit{#2}
}
もう一つの選択肢は、文字列を先頭の文字と末尾の文字列に分割することです。次のようになります。
\witheachcharacterinheadandtail{abcdef}{\drawaboxaroundit}{\glue\drawaboxaroundit}
\witheachcharacterinheadandtail{abcdef}{\foo}{\bar}
拡大する場所
\foo{a}\bar{b}\bar{c}\bar{d}\bar{e}\bar{f}
この 2 番目のアプローチの方が優れているように思えますが、どちらのアプローチを実現するか、あるいは、どちらがそもそも良いアイデアなのかはわかりません。
文字列を分解、変換、結合するにはどうすればいいですか?問題の文字列は ASCII であり、LaTeX コマンドは含まれておらず、すべての文字列には少なくとも 2 つの文字 (末尾の長さは常に 0 以外) が含まれていると想定できます。
答え1
\documentclass{article}
\def\xloop#1{\ifx\relax#1\else\xloopbody{#1}\expandafter\xloop\fi}
\newcommand\explodethenjoin[3]%
{\def\inter{\def\inter{#3}}%
\def\xloopbody##1{\inter#2{##1}}%
\xloop#1\relax
}
\begin{document}
\explodethenjoin{abcdef}{\fbox}{+}
\end{document}
マクロは\xloop
、に出会うまで、それに続くトークンを反復します\relax
。これは、このサイトで何度もトークンごとにマクロ\xloopbody
が実行され、適切に定義することで、必要に応じてトークンを処理できます。
答え2
TeX には実際には文字列がないので、トークン リストを分割するための特別なコマンドは必要ありません。トークン リストはすでに個別のトークンのリストになっています。同様に、トークン リストを反復処理するのは通常の tex の動作であるため、明示的なループ マクロを使用する必要はありません。
\documentclass{article}
\def\zz#1{\def\zzsep{}\zzz#1\relax}
\def\zzz#1{\ifx\relax#1\else\zzsep\def\zzsep{+}\fbox{#1}\expandafter\zzz\fi}
\begin{document}
\zz{abcdef}
\end{document}
答え3
簡単ですxparse
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\splitstring}{mmO{}}
{
\spraff_string_split:nnn { #1 } { #2 } { #3 }
}
\seq_new:N \l_spraff_string_in_seq
\seq_new:N \l_spraff_string_out_seq
\cs_new_protected:Nn \spraff_string_split:nnn
{
% split the string at 'nothing'
\seq_set_split:Nnn \l_spraff_string_in_seq { } { #1 }
% change each item into '#2{<item>}'
\seq_set_map:NNn \l_spraff_string_out_seq \l_spraff_string_in_seq { #2 { ##1 } }
% use the sequence with '#3' in between items
\seq_use:Nn \l_spraff_string_out_seq { #3 }
}
\ExplSyntaxOff
\NewDocumentCommand{\boxit}{m}{\fbox{\strut#1}}
\begin{document}
\splitstring{abcdef}{\boxit}
\splitstring{abcdef}{\boxit}[${}+{}$]
\end{document}
の 2 番目の引数として使用されるマクロは\splitstring
で定義する必要があることに注意してください\NewDocumentCommand
。