自动填充 LaTeX 字符的重音符号/变音符号

自动填充 LaTeX 字符的重音符号/变音符号

我在编写 LaTeX 文档时,经常需要写出带有重音符号或变音符号的字符。例如,在写微积分课笔记时,我经常会用到“ô”来表示“L'Hôpital”(参考他的标题规则)。

当然,这也适用于其他带重音符号的字符等,通常用于姓名(例如 Paul Erdős、René Descartes、Otto Hölder)。有些可以看到这里

用 LaTeX 写这些对我来说有点麻烦,主要是因为我很难记住实际的代码,或者经常把它们弄混。我也用标准的英文键盘写字,所以“只需将字符输入文档”就会导致我必须从其他地方复制粘贴。所以不管怎样,我都必须查找一些东西——代码列表,或者里面有字符的东西。

如果我能编写一段代码自动检测相关字符串,并将其替换为带有正确口音的字符串,那么对我来说会更容易。例如,在生成的 PDF 中,它会识别出我输入的L'Hopital,并将其替换为。L'Hôpital

当然,定义一个宏来实现这一点很简单,比如

    \newcommand{\lhopital}{L'Hôpital}

但使用它感觉笨重且不自然,特别是对于几乎肯定会在数学模式之外呈现的东西。

根据我过去所做的一些搜索,我觉得这样的事情可能是可能的。例如,这个帖子对其进行更改,以便:=生成您期望的结果,但冒号相对于等号的垂直对齐效果更好。诚然,我很难分析这段代码到底在做什么……但无论如何,这段代码的工作原理与我预想的完全一样:除了输入代码之外,我不需要做任何额外的努力。

简而言之,我理想中想要的是可以自动将我在文档中输入的文本字符串替换为我想要替换的特定文本字符串的东西。因此,每当我输入时,我都会得到L'HopitalL'HôpitalErdos得到Erdős,等等 - 通常,我在输出中输入stringA和获得。stringB

谢谢你提供的所有帮助!

答案1

如果你愿意并且能够使用 LuaLaTeX,你可以使用它的process_input_buffer回调,它可以作为输入流的预处理器,TeX 甚至开始其正常工作。用户只需用name_table合适的搜索和替换字符串填充 Lua 表即可。

在此处输入图片描述

\documentclass{article}

\directlua{ 
% -- Set up a Lua table with search and replacement strings:
  name_table = {
     { "L'?Hopital" , "L'Hôpital" },
     { "Erdos"      , "Erdős"     },
     { "Holder"     , "Hölder"    }, 
     { "Godel"      , "Gödel"     },
     { "Rene"       , "René"      },
  }
% -- Next, define the Lua function that does the actual work:
  function change_table_vals ( s )
    for _,j in pairs ( name_table ) do 
      s = s:gsub ( j[1] , j[2] ) 
    end
    return s
  end
}
%% assign the Lua function to the 'process_input_buffer' callback
\AtBeginDocument{\directlua{luatexbase.add_to_callback ( 
   "process_input_buffer" , change_table_vals , "change" )}}

\begin{document}
L'Hopital LHopital Erdos Holder Rene Godel
\end{document}

答案2

由于 TeX 是一种可扩展的宏语言,Expl3 的正则表达式功能可以处理替换,比仅仅替换字符串更强大,因为它在标记列表级别工作并且可以看到内部控制序列。

各种输入快捷方式都可用,并且为了方便输入,整个document环境可以作为标记列表输入到正则表达式中:

正则表达式用法

困难的工作是保持查找(stringA)元素的唯一性(彼此之间以及与文本中的普通单词(部分)之间的唯一性)。

平均能量损失

\documentclass{article}
\usepackage{xcolor}
\pagecolor{green!3}
\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{fontspec}

\DeclareTextFontCommand{\textjp}{\fnippon}
\AtBeginEnvironment{document}{\myauto}
\AtEndEnvironment{document}{\endmyauto}

\setmainfont{Noto Serif}
\newfontfamily{\fnippon}{NotoSerifCJKjp}[
Extension=.otf,
UprightFont=*-Regular,
%BoldFont=NotoSerifCJKjp-Bold.otf,
]
%==============================


%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\ExplSyntaxOn

\tl_new:N \l_myab_tl

\NewDocumentEnvironment { myauto } { +b }
{
    \tl_set:Nn \l_myab_tl { #1 } 
    \domyauto 
    \tl_use:N \l_myab_tl 
}
{}

\newcommand\dmr[2]{
\regex_replace_all:nnN { #1 } { #2 } \l_myab_tl
%   \tl_replace_all:Nnn 
%                   \l_myab_tl 
%                   { #1 } 
%                   { #2 }

}

\newcommand{\domyauto}{
\dmr{lhopital} {L'Hôpital}
\dmr{hoelder}{Hölder}
\dmr{goedel}{Gödel}
\dmr{rened}{René}
\dmr{erdos}{Erdős}
\dmr{kazkur}{Kazimierz\ Kuratowski}
\dmr{waclaw}{Wacław\ Sierpiński}
\dmr{zyg}{Zygmunt\ Janiszewski}
\dmr{jerzy}{Jerzy\ Różycki}
\dmr{golab}{Stanisław\ Gołąb}
\dmr{ariege}{Ariège}
\dmr{bdrhone}{Bouches-du-Rhône}
\dmr{cotedor}{Côte-d'Or}
\dmr{isere}{Isère}
\dmr{upperaustria}{Oberösterreich}
\dmr{Carinthia}{Kärnten}
\dmr{kanagawa}{\c{textcolor}\cB\{blue\cE\}\cB\{\c{textjp}\cB\{神奈川県\cE\}\cE\}}
\dmr{toyama}{\c{textcolor}\cB\{blue\cE\}\cB\{\c{textjp}\cB\{富山県\cE\}\cE\}}
\dmr{hironaka}{\c{textjp}\cB\{広中\ 平祐\cE\}}
\dmr{yoneda}{\c{textjp}\cB\{米田\ 信夫\cE\}}
%\dmr{}{}
}

\ExplSyntaxOff


\begin{document}
%\begin{myauto}
\section{lhopital}
The cat sat on the lhopital rule.

erdos hoelder goedel rened fullerene

golab, jerzy, zyg, waclaw, kazkur.

ariege, bdrhone, cotedor, isere, upperaustria, Carinthia

\section{kanagawa, toyama}

Heisuke Hironaka (hironaka), Nobuo Yoneda (yoneda).


%\end{myauto}
\end{document}

答案3

这通常是文本编辑器甚至操作系统的一项功能。例如,在 MacOS 上,您可以转到“设置|键盘|文本”并进行设置,这样如果您输入,lhopital它会自动将其更改为L'Hôpital您正在输入的位置。

答案4

简单的替代方法是使用 AutoHotKey 或其他东西(vimabbrev 命令等)进行替换,正如其他答案中提到的。


请记住,TeX 只是一种编程语言。

想想对于像 Python 这样的“普通”编程语言你会如何做......

​ • 运行另一个脚本,用您想要的新序列替换旧脚本中的所有字符序列,然后
​ • 执行新脚本。

在 LaTeX 中也可以这样做:

​ • 读取文件内容(无论是字面上\ior_str_get:NN还是通过类似于逐字扫描向前的技术)
​ • 使用类似的方法\str_replace_all:Nnn用新字符串替换旧字符串
​ • 使用\scantokens重新解释(exec在 Python 中)为 TeX 源代码。

对于 LuaTeX 等引擎,已经可以通过 Lua 预处理源代码,而无需单独的步骤,请参阅其他答案。

不用说,用 TeX 编程不是很舒服,大多数人更喜欢编写一个 Python/Lua 或其他脚本来在源代码中查找和替换。

更准确地说,对于诸如 Python 之类的语言,您可以使用ast将源代码解析为解析树,然后仅替换字符串等中的部分内容,但据我所知,TeX 不会输出任何解析树(大多数时候解析树的概念在 TeX 中甚至没有意义。)


然而,在 TeX 中,您可以在普通(文本)模式下重新定义字符以向前扫描字符。这意味着您可以定义L向前扫描(参见 \peek_N_type:TF和类似内容)以确定下一个字符是否是'Hopital 并进行适当的替换;但现在这L是一个活动字符,它可能会破坏各种其他东西(例如您不能在控制序列名称中使用它)

另一种方法是定义一些字符来执行前向扫描,但是如果您想输入,◇L'Hopital您也可以只输入\LHopital


另一种方法是在字体文件中使用连字......

仅使用有限的字符集也可以有效地容纳欧洲语言。例如,我们再次考虑挪威语,但假设您想使用没有 æ 字符的键盘。您可以安排字体度量文件,以便 TEX 将 ae、o/、aa、AE、O/ 和 AA 解释为分别产生 æ、ø、˚a、Æ、Ø 和 ˚A 的连字符;您可以将字符 ˚a 和 ˚A 放入字体的 128 和 129 位置。

(TeXBook,第 45 页,第 8 章“您输入的字符”)

我不确定这种方法是否适用于新引擎(使用新字体格式),而且我绝对不知道如何创建这样的字体(即使你这样做,我认为你仍然需要输入L'Ho"pital或类似的东西?我猜没有太大的改进)。

相关内容