为了改进\sameword
reledmac 的功能,我想找到一种方法来自动将命令应用于每个单词。例如,在纯 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
使用xparse
和l3regex
模块的实现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 字符也在管理范围内。