我想知道是否有可能编写一个命令来全局查找和替换某些单词,以便快速将文档设置为较旧的正字法约定。我找不到任何可以全局执行此操作的东西。虽然我可以\StrSubstitute
通过对整个文档执行此操作xstring
,但我觉得应该有一种方法可以做到这一点,即可以将命令(比如说\oldorthography
)放在文档的序言或开头,它会为您完成所有操作。我设想的 MWE 和想象的输出如下;我只是不知道如何让它工作。
\documentclass{article}
\usepackage{xstring}
\newcommand{\oldorthography}{
\StrSubstitute{main.tex}{dais}{daïs}[\nova]
\StrSubstitute{\nova}{cooperate}{coöperation}[\nova]
\StrSubstitute{\nova}{anasthesia}{anasthæsia}[\nova]
\StrSubstitute{\nova}{hotel}{hôtel}
}
\oldorthography
\begin{document}
\obeylines%just to save space
dais
cooperate
anasthesia
hotel
\end{document}
将输出
未启用该选项的代码与没有实际命令的代码完全相同\oldorthography
,并且将输出
我确信这是非常基础的东西,我只是不了解 TeX,但如果有人有任何见解,那将非常有帮助。谢谢!!
答案1
运行lualatex
:
\documentclass{article}
\usepackage{chickenize}
\addtosubstitutions{dais}{daïs}
\addtosubstitutions{cooperate}{coöperation}
\addtosubstitutions{anasthesia}{anasthæsia}
\addtosubstitutions{hotel}{hôtel}
% just to show how one can override the substitution in word parts
\addtosubstitutions{hôtels}{hotels}
\substitutewords % comment to disable substitutions
\begin{document}
dais
cooperate
anasthesia
hotel
hotels
\end{document}
请注意,替换也是在文字中部分,因此,如果要替换的单词可能是不可替换的单词的一部分,则需要小心,并且我添加了一个公认很愚蠢的例子。
答案2
您似乎希望 TeX 分析整个 .tex 源代码/.tex 输入文件并进行一些(正字法)调整,然后才以通常的方式进行实际处理。
这与传统 TeX 引擎的设计工作方式不同。
使用 Knuth 的类比,将 TeX 比作一只长着眼睛和消化道的野兽,你可以将事情简化一点,说 TeX 的设计工作原理如下:
TeX 的眼睛逐行查看 .tex 输入文件,并将对应于 .tex 输入行中看到的字符(还不是标记!)放入嘴中。
因此,TeX 的嘴接收的字符序列或多或少对应于“查看” .tex 输入行时看到的字符序列。TeX
的嘴将这些字符序列“咀嚼”成更小的位,即所谓的标记(字符标记/控制序列标记)。换句话说:TeX 的嘴将单个字符作为生成所谓标记(字符标记/控制序列标记)的指令序列。
嘴生成标记并将它们送入食道。
可扩展标记(例如宏标记)在通过食道时会扩展。 (除非触发了食道以抑制扩展,例如,使用标记形成根据 定义的宏的定义文本的情况就是如此\def
。LaTeX 的\newcommand
宏是基于 的\def
。)食道是扩展的地方。
通过食道后,标记到达胃部,可执行标记(例如\def
)在此执行/执行任务、构建框、将段落分成行、将行分成多页,并创建 .pdf 输出文件。
针对您的问题,所有这些(过度?)简化传统 TeX 引擎工作方式的要点是:
TeX 的眼睛按行处理 .tex 输入文件,而 TeX 的嘴按字符处理 .tex 输入的单行,这两个概念实际上与让 TeX 在以通常方式“消化”内容之前,将整个 .tex 输入文件作为一个整体或将 .tex 输入的整行作为一个整体来“查看”以进行任何调整(例如,替换或类似的)的想法相矛盾。
您可能可以使用基于 LuaTeX 的引擎,并让其通过 Lua 功能对内容进行预处理(从而可以进行替换),然后再将它们传递给 TeX 的 -eh- 通常的消化机制。(这是在egreg 的回答)或者,你也可以让 TeX 以 verbatim-catcode-régime 方式读取整个 .tex 输入文件,并让它对结果集进行替换(例如,通过 xstring 的\StrSubstitute
或 expl3 提供的例程),然后切换回正常的 catcode-régime 并将结果传递给\scantokens
。但是我的这个答案对于一个较老的问题,该问题也是关于替换文档中的内容,它对某些场景进行了简短的调查,在这些场景中,对 .tex 源代码中出现的短语进行简单的搜索替换(无论如何完成)可能不够用。
如何引入一个\if
-switch 来分叉正字法样式,并让 TeX 为每个单词定义宏,这取决于\if
-switch 为每个单词定义宏?
这种方法的一个问题可能是,在对控制字标记进行标记后,TeX 通常会忽略 .tex 输入中出现的空格。有些情况下这并不重要,例如,在句子或从句的末尾,当相关单词后面跟着某个标点符号或逗号时。还有些情况下,不应忽略尾随空格 - 例如,当后面有更多单词时。您可以使用 xspace 包。在很高比例的情况下,其命令会就\xspace
是否在单词后插入空格做出正确的决定。在下面的例子中,我选择了另一种方法:每个表示可能更改正字法的单词的控制字标记后面都必须跟着一个斜线,/
而斜线会被忽略。将斜线标记成字符标记意味着不会忽略斜线后的空格。但是,为每个正字法可变的单词定义一个宏的方法没有考虑到在 -environment 中发生的情况verbatim
或 -commands 参数中发生的情况\verb
等场景,即不展开而是逐字处理的场景。此外,您还需要注意,对于\uppercase
/之类的东西\lowercase
,宏在执行大小写更改程序之前会先展开。LaTeX 的\MakeUppercase
/\MakeLowercase
会为您完成这项工作。
我在以下示例中定义事物的方式还允许您在文档内/仅针对文档的部分内容更改/切换正字法。如果您这样做,请小心所谓的移动参数(即在文档的多个位置出现的参数,例如,在正文、目录中出现的章节标题,可能在页眉中,也可能在 .pdf 文件的书签中出现),以便在文档/.pdf 输出文件的正确位置获得正确的正字法变体。
\documentclass{article}
\newif\ifoldorthography
\makeatletter
\@ifdefinable\DefineOrthographyDependantCommand{%
\DeclareRobustCommand\DefineOrthographyDependantCommand[3]{%
\@ifdefinable#1{%
\def#1/{\ifoldorthography\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi{#2}{#3}}%
}%
}%
}%
\makeatother
\DefineOrthographyDependantCommand\dais{dais}{daïs}%
\DefineOrthographyDependantCommand\cooperate{cooperate}{coöperate}%
\DefineOrthographyDependantCommand\anasthesia{anasthesia}{anasthæsia}%
\DefineOrthographyDependantCommand\hotel{hotel}{hôtel}
\begin{document}
\oldorthographytrue
old orthography:
\dais/ \cooperate/ \anasthesia/ \hotel/
\dais/, \cooperate/, \anasthesia/, \hotel/.
\ifoldorthography
\begin{verbatim}
daïs
coöperate
anasthæsia
hôtel
\end{verbatim}
\else
\begin{verbatim}
dais
cooperate
anasthesia
hotel
\end{verbatim}
\fi
\bigskip\hrule\bigskip
\oldorthographyfalse
current orthography:
\dais/ \cooperate/ \anasthesia/ \hotel/
\dais/, \cooperate/, \anasthesia/, \hotel/.
\ifoldorthography
\begin{verbatim}
daïs
coöperate
anasthæsia
hôtel
\end{verbatim}
\else
\begin{verbatim}
dais
cooperate
anasthesia
hotel
\end{verbatim}
\fi
\end{document}
答案3
最初的答案是从我的答案中完全窃取的根据字典自动突出显示文本。唯一的区别是,我没有用颜色突出显示指定的字典单词,而是对它们进行了转换。
最近,我根据评论编辑了答案,允许将字母序列指定为转换的一部分。以前,只有与“转换词典”单词完全匹配的单词才会被转换。现在,该功能得到了扩展,例如,即使出现在单词中,每次出现的ai
都会被替换为aï
。从代码的角度来看,这意味着对 实施转换\autohighlightStyleB
,而原始答案中将其留空。
因此,突出显示的定义必须更改为
\newcommand\autohighlightStyleA{\transformword}% IS WORD
\newcommand\autohighlightStyleB{\transforminword}% INCLUDES WORD
\newcommand\transformword[1]{\csname T\detokenize{#1}\endcsname}
\newcommand\transforminword[1]{\readlist\dictcompB{#1}%
\foreachitem\z\in\dictcompB{%
\ifnum\zcnt=1\relax\else\csname T\detokenize
\expandafter\expandafter\expandafter
{\dictcompBsep[\zcnt-1]}\endcsname\fi
\z
}%
}
当然,我还必须提供搜索,然后为每个感兴趣的单词或字母序列定义转换:
\setsepchar{ai||oo||oe||anasthesia||hotel}
\def\Tai{aï}
\def\Too{oö}
\def\Toe{ö}
\def\Tanasthesia{anasthæsia}
\def\Thotel{hôtel}
这个新功能虽然功能更强大,但也更危险,因为它可能会转换您不想要的部分单词。对于规则的例外情况,您可以使用分隔符|...|
来防止对所包含的文本进行任何转换。
您可以在文档开头打开它,在文档结尾关闭它。唯一可能需要在之前退出并在之后重新输入的代码是更改 catcode 的代码。由于 tokencycle 在排版之前会消化并分析输入流中的每个标记,因此其 catcode 会在分析阶段设置,因此此后不会受到 catcode 更改的影响。
这是 MWE,它需要 2021-03-10 的版本tokcycle
。伪环境称为\transform...\endtransform
。请注意,使用 后,“toe” 已被排除在转换之外|toe|
:
\documentclass{article}
\usepackage{tokcycle}[2021-03-10]
\usepackage{listofitems}
\setsepchar{ai||oo||oe||anasthesia||hotel}
\def\Tai{aï}
\def\Too{oö}
\def\Toe{ö}
\def\Tanasthesia{anasthæsia}
\def\Thotel{hôtel}
\newcommand\testdict{%
\if\relax\detokenize\expandafter{\currentword}\relax\else
{\ignoreemptyitems
\greadlist\dictcompA{\currentword}}%
\readlist\dictcompB{\currentword}%
\ifnum\listlen\dictcompA[]=0\relax
\addcytoks[1]{\autohighlightStyleA}%
\addcytoks[1]{\expandafter{\currentword}}%
\else
\ifnum\listlen\dictcompB[]>1\relax
\addcytoks[1]{\autohighlightStyleB}%
\addcytoks[1]{\expandafter{\currentword}}%
\else
\addcytoks[1]{\currentword}%
\fi
\fi
\fi
\gdef\currentword{}%
}
\makeatletter
\xtokcycleenvironment\transform
{\tctestifcatnx A##1{\g@addto@macro\currentword{##1}}
{\testdict\addcytoks{##1}}}
{\testdict\groupedcytoks{\processtoks{##1}\testdict}}
{\g@addto@macro\currentword{##1}}
{\testdict\addcytoks{##1}}
{\stripgroupingtrue\def\currentword{}}
{}
\makeatother
\newcommand\autohighlightStyleA{\transformword}% IS WORD
\newcommand\autohighlightStyleB{\transforminword}% INCLUDES WORD
\newcommand\transformword[1]{\csname T\detokenize{#1}\endcsname}
\newcommand\transforminword[1]{\readlist\dictcompB{#1}%
\foreachitem\z\in\dictcompB{%
\ifnum\zcnt=1\relax\else\csname T\detokenize
\expandafter\expandafter\expandafter
{\dictcompBsep[\zcnt-1]}\endcsname\fi
\z
}%
}
\begin{document}
\transform
While speaking from the dais,
I decided to cooperate with Doctor Roentgen calling for help
on a patient with a broken |toe|.
He was asking for anasthesia
and so I directed him to the best hotel,
here in the city of many hotels.
\endtransform
\end{document}