使用 包semantic
,可以很容易地通过连字符生成特殊数学符号(例如->
变成\rightarrow
)。然而,在 OpenType 中也有类似的东西。例如,Fira Code 字体为编程提供了连字符。如何在 TeX 方程式中实现这样的功能?
其实这个功能可能需要OpenType字体的支持,不过现有的OpenType数学字体好像没有这个功能,希望可以自己做一个。
答案1
既然您愿意使用 OpenType 字体,我假设您也愿意考虑基于 LuaLaTeX 的解决方案。以下代码设置了一个 Lua 函数,该函数 (a) 扫描所有输入行,(b) 自动“动态”用->
和分别替换和的所有实例。<-
\rightarrow
\leftarrow
我相信弄清楚如何定义额外的“智能连字符”很简单。
\SmartligOff
可以使用 LaTeX 宏和分别禁用 Lua 函数的操作,然后重新启用\SmartligOn
。如果您的参考书目包含可能具有包含子字符串->
和的 URL 字符串的 bib 条目,这可能会派上用场<-
:显然,人们不想用\rightarrow
和替换这些子字符串\leftarrow
,对吧?
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{unicode-math} % optional
\setmathfont{Asana Math} % optional
\usepackage{luacode}
\begin{luacode}
function smartlig ( s )
-- Use '%-' to search for '-'
-- Write '\\' to output a (single) backslash character
s = s:gsub ( "%->", "\\rightarrow " )
s = s:gsub ( "<%-", "\\leftarrow " )
return s
end
\end{luacode}
\newcommand\SmartligOn{\directlua{luatexbase.add_to_callback (
"process_input_buffer", smartlig, "smartlig" )}}
\newcommand\SmartligOff{\directlua{luatexbase.remove_from_callback (
"process_input_buffer", "smartlig" )}}
\AtBeginDocument{\SmartligOn} % enabled by default
\begin{document}
$a->b$, $c<-d$
\SmartligOff
$a->b$, $c<-d$
\SmartligOn
$a->b$, $c<-d$
\end{document}
答案2
ConTeXt 有一个功能叫做崩塌其中,多个预定义的字形组合被折叠成一个,可以通过字体连字(内部称为特价商品), 例如
′′′
(3次0x2032 PRIME
)至‴
(0x2034 TRIPLE PRIME
)
或者通过查找表数学列表,其中定义了箭头之类的东西。最近有一个相关问题,如何关闭这些
\starttext
$a->b$ $b<-a$
\stoptext
答案3
这是个不错的挑战。到目前为止,此解决方案仅适用于文本和显示样式,并且仅替换右箭头。
\directlua{
local rightarrow = node.new("noad",5) % subtype 5 = "rel"
rightarrow.nucleus = node.new("math_char")
rightarrow.nucleus.fam = 2
rightarrow.nucleus.char = 33
%
local function is_minus(v)
return v and v.nucleus and v.nucleus.fam == 2 and v.nucleus.char == 0
end
%
local function is_gt(v)
return v and v.nucleus and v.nucleus.fam == 1 and v.nucleus.char == 62
end
%
callback.register('mlist_to_hlist',
function(head,style,penalties)
local v = head
local delete_next = false
while v do
if delete_next then
node.insert_after(head, v, node.copy(rightarrow))
head = node.remove(head, v)
delete_next = false
end
if is_minus(v) and is_gt(v.next) then
head = node.remove(head, v)
delete_next = true
end
v = v.next
end
return node.mlist_to_hlist(head,style,penalties)
end)
}
$a->b$
\bye