对每个单词应用宏

对每个单词应用宏

为了改进\samewordreledmac 的功能,我想找到一种方法来自动将命令应用于每个单词。例如,在纯 TeX 中,

\def\foo#1{#1 (#1)}
foo bar foo bar foo bar foo, foo? foo. foo;
\end

应自动转换为

\def\foo#1{#1 (#1)}
\foo{foo} \foo{bar} \foo{foo} \foo{bar} \foo{foo} \foo{bar} \foo{foo}, \foo{foo}? \foo{foo}. \foo{foo};
\end

我的限制是:

  • 不包括标点符号
  • 排除某些命令(例如foo\footnote{bar}should become\foo{foo}\footnote{bar}和 not \foo{foo\footnote{bar}}
  • 如果可能的话,使用 pdfTeX、XeTeX 和 LuaTeX,但仅使用 LuaTeX 的解决方案会更好。
  • 使用任何现有的 LaTeX 包(但也接受纯 plainTeX)

答案1

这将是所以很容易打破这个,但是......

在此处输入图片描述

\def\foo#1{#1 (#1)}
\def\xfoo#1 {%
\def\tmp{#1}%
\ifx\tmp\endfoo
\let\next\relax
\else
\ftnfoo#1\footnote\empty\empty\empty\relax
\let\next\xfoo
\fi
\next}
\def\ftnfoo#1\footnote#2#3#4\relax{%
\ifx\footnote#4\foo{#1}\footnote{#2}{#3} \else\afoo#1?\relax\fi}
\def\afoo#1?#2\relax{\ifx?#2\foo{#1}? \else\bfoo#1,\relax\fi}
\def\bfoo#1,#2\relax{\ifx,#2\foo{#1}, \else\cfoo#1;\relax\fi}
\def\cfoo#1;#2\relax{\ifx;#2\foo{#1}; \else\dfoo#1.\relax\fi}
\def\dfoo#1.#2\relax{\ifx.#2\foo{#1}. \else\foo{#1} \relax\fi}


\vsize=5\baselineskip

% assumes a space before the par
\def\yfoo#1\par{\xfoo#1!@ \par}

\def\endfoo{!@}

\yfoo
foo bar foo bar foo\footnote{$^1$}{bar} bar foo, foo? foo. foo;

\bye

答案2

恕我直言,你需要这样的东西:

\def\everyword#1#2{\let\domacro=#1\everywordA#2 {} }
\def\everywordA#1 {\ifx^#1^\else
   \def\tmp{}\everywordB #1\end
   \expandafter\everywordA \fi
}
\def\everywordB{\futurelet\next\everywordC}
\def\everywordC{\ifcat\noexpand\next A\expandafter\everywordD
                \else \expandafter\everywordE \fi}
\def\everywordD#1{\edef\tmp{\tmp#1}\everywordB}
\def\everywordE#1\end{\expandafter\domacro\expandafter{\tmp}#1}

\def\foo#1{#1 (#1)}
\everyword\foo{foo bar foo bar foo bar foo, foo? foo. foo;}
\end

这个宏的主要思想是:我们首先处理每个用空格分隔的单词,然后将每个这样的单词分为两部分:第一部分是字母标记(catcode 11),第二部分是所有其他类型的标记。

答案3

使用xparsel3regex模块的实现expl3;首先, 的出现\footnote被排除在外,然后在每个部分中,将不是空格或标点符号的字符作为宏的参数给出,该宏的含义可以使用 来设置\setxsamewordformat

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\xsameword}{m}
 {
  \maieul_xsameword:n { #1 }
 }

\tl_new:N \l__maieul_xsameword_list_tl

\cs_new_protected:Nn \maieul_xsameword:n
 {
  \tl_set:Nn \l__maieul_xsameword_list_tl
   {
    \__maieul_xsameword_start:n { #1 }
   }
  \regex_replace_all:nnN
   { (\c{footnote}\cB..*?\cE.) }
   { \cE\} \1 \c{__maieul_xsameword_start:n} \cB\{ }
   \l__maieul_xsameword_list_tl
  \tl_use:N \l__maieul_xsameword_list_tl
 }
\cs_new_protected:Nn \__maieul_xsameword_start:n
 {
  \tl_set:Nn \l__maieul_xsameword_list_tl { #1 }
  \regex_replace_all:nnN
   { ([^\s,.!?]+) }
   { \c{maieul_xsameword_format:n} \cB\{ \1 \cE\} }
   \l__maieul_xsameword_list_tl
  \tl_use:N \l__maieul_xsameword_list_tl
 }

\NewDocumentCommand{\setxsamewordformat}{m}
 {
  \cs_set_protected:Nn \maieul_xsameword_format:n { #1 }
 }
\ExplSyntaxOff

\setxsamewordformat{#1 (#1)}

\textheight=3cm

\begin{document}

\xsameword{foo \textit{bar} baz? foo\footnote{footnote footnote} bar}

\setxsamewordformat{\textbf{#1}}

\xsameword{foo \textit{bar} baz? foo\footnote{footnote footnote} bar}

\end{document}

在此处输入图片描述

请注意,非 ASCII 字符也在管理范围内。

相关内容