我有一个用普通英文引号编写的 LaTeX 文档,例如:
``This is a quoted text.''
现在,我想重新定义``
和''
,因此组合两个`
字符的 被替换为<
和>
。结果应该就像我写的一样:
<This is a quoted text.>
我发现我怀念用于描述和搜索问题的 Latex 词汇表。这``
到底是什么?两个字形字符?命令?宏?它与什么关系`
?
答案1
通常'
和`
是简单字符,当在普通文本中发现时,它们会不加改变地传递给 TeX 的胃段落被分成几行,框被构建,页面被形成。
当段落被分成几行时,TeX 会识别连字,比如将其更改fi
为单个字形(但会记住两个原始字形,以防需要在两个字母之间使用连字)。
组合也会发生同样的情况
`` ''
分别转换为“ 和 ”。例如,输入
``word''
当盒子成型时,会转化为
....\OT1/cmr/m/n/10 \ (ligature ``)
....\OT1/cmr/m/n/10 w
....\kern-0.27779
....\OT1/cmr/m/n/10 o
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 d
....\OT1/cmr/m/n/10 " (ligature '')
在同一阶段,根据字体信息进行自动字距调整。事实上,连字符是编入字体的,不受用户控制。
你可以制作`
并'
积极的字符,所以基本上与宏相同。
\documentclass{article}
\usepackage[T1]{fontenc}
\makeatletter
\protected\def\myleftquote{\futurelet\next\left@quote@check}
\protected\def\myrightquote{\futurelet\next\right@quote@check}
\begingroup\lccode`~=`` \lowercase{\endgroup
\def\left@quote@check{\ifx\next~<\expandafter\@gobble\else`\fi}
}
\begingroup\lccode`~=`' \lowercase{\endgroup
\def\right@quote@check{\ifx\next~>\expandafter\@gobble\else'\fi}
}
\begingroup\lccode`~=`` \lowercase{\endgroup\let~}\myleftquote
\begingroup\lccode`~=`' \lowercase{\endgroup\let~}\myrightquote
\AtBeginDocument{%
\catcode``=\active
\catcode`'=\active
}
\begin{document}
A ``word'' and more
A `word' and more
\end{document}
然而,这非常脆弱。如你所见,代码写得很间接,在最后一刻才激活,因为`
和'
也有句法意义。
例如,您将无法\symbol{'123}
在文档中使用(根据 TeX 语法的八进制数),因为'
在该上下文中,这将是一个意外的标记,处于活动状态。您还会丢失“西班牙语”连字`?
以及`!
¿ 和 ¡(这可能会通过更多测试进行安排)。
`
您还应该修复逐字模式中的行为。
答案2
如果您有能力并且愿意运行 LuaLaTeX,您可以 (a) 设置一个执行字符串替换工作的 Lua 函数,以及 (b) 将此函数分配给process_input_buffer
在非常早期阶段运行的回调,前TeX 的“眼睛”、“嘴巴”等开始工作。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage[T1]{fontenc} % handle "<" and ">" in text mode
\usepackage{luacode}
\begin{luacode*}
function change_quotes ( buff )
return ( string.gsub ( buff, "``(.-)''", "<%1>" ) )
end
luatexbase.add_to_callback( "process_input_buffer", change_quotes, "change_quotes")
\end{luacode*}
\begin{document}
``This is a quoted text.''
Here are ``three'' ``quoted'' ``words''.
This is an ``'' empty quote.
\end{document}
附录:如果字符替换不应该在verbatim
和环境中发生,则需要对 Lua 函数的代码进行一些扩展以进行检查。基本上,代码必须检查函数扫描的材料是否在逐字类型的环境中。这可以通过将上面和行Verbatim
之间的代码替换为以下代码来处理:\begin{luacode}
\end{luacode}
\begin{luacode}
in_verbatim = false -- Set up a Boolean variable
function change_quotes ( buff )
if string.find ( buff , "\\begin{[vV]erbatim}" ) then
in_verbatim = true
return buff
elseif string.find ( buff , "\\end{[vV]erbatim}" ) then
in_verbatim = false
return buff
elseif in_verbatim == false then
return string.gsub ( buff , "``(.-)''" , "<%1>" )
end
end
luatexbase.add_to_callback( "process_input_buffer", change_quotes, "change_quotes")
\end{luacode}