答案1
全自动,得益于 LuaTeX。
\documentclass{article}
\usepackage{amsmath}
\usepackage{luacode}
\begin{luacode*}
local muglue_subtype
do
for num, name in pairs(node.subtypes(node.id("glue"))) do
if name == "muglue" then
muglue_subtype = num
break
end
end
end
assert(muglue_subtype, "No such subtype!")
function table.contains(haystack, needle)
for _, straw in next, haystack do
if straw == needle then
return true
end
end
return false
end
local glue_fields = { "width", "stretch", "stretch_order", "shrink", "shrink_order" }
local function binordspacing(head,style,penalties)
local cur = head
local match = 0
while cur do
local subtype = node.subtypes(cur.id)[cur.subtype]
if match == 0 and table.contains({"op", "bin", "rel", "open", "punct"}, subtype) then
match = 1
elseif match == 1 and subtype == "bin" then
match = 2
elseif match == 2 and subtype == "ord" then
local binordspacing = tex.getmath("binordspacing", style)
local n = node.new("glue", muglue_subtype)
for _, field in ipairs(glue_fields) do
n[field] = binordspacing[field]
end
head = node.insert_before(head, cur, n)
match = 0
else
match = 0
end
cur = cur.next
end
return true
end
luatexbase.add_to_callback("pre_mlist_to_hlist_filter", binordspacing, "binordspacing")
\end{luacode*}
\begin{document}
\begin{equation*}
\alpha = -p(-w_1-v_0) - g(w_1)
\end{equation*}
\begin{center}
$\alpha = -p(-w_1-v_0) - g(w_1)$
\end{center}
\end{document}
啊啊啊我的眼睛!
在评论中,您提到您还想在左括号和减号之间留出空格(天哪,为什么?),所以我想出了一个更可配置的方法。这允许您在 TeX 不会考虑的地方插入随机空格(出于充分的理由)。
\documentclass{article}
\usepackage{amsmath}
\usepackage{luacode}
\begin{luacode*}
local muglue_subtype
do
for num, name in pairs(node.subtypes(node.id("glue"))) do
if name == "muglue" then
muglue_subtype = num
break
end
end
end
assert(muglue_subtype, "No such subtype!")
local glue = glue or {}
function glue.copy(src)
local glue_fields = { "width", "stretch", "stretch_order", "shrink", "shrink_order" }
local g = node.new("glue", muglue_subtype)
for _, field in ipairs(glue_fields) do
g[field] = src[field]
end
return g
end
local knuth_table = {
ord = { ord = "0" , op = "1" , bin = "(2)", rel = "(3)", open = "0" , close = "0" , punct = "0" , inner = "(1)" },
op = { ord = "1" , op = "1" , bin = "*" , rel = "(3)", open = "0" , close = "0" , punct = "0" , inner = "(1)" },
bin = { ord = "(2)", op = "(2)", bin = "*" , rel = "*" , open = "(2)", close = "*" , punct = "*" , inner = "(2)" },
rel = { ord = "(3)", op = "(3)", bin = "*" , rel = "0" , open = "(3)", close = "0" , punct = "0" , inner = "(3)" },
open = { ord = "0" , op = "0" , bin = "*" , rel = "0" , open = "0" , close = "0" , punct = "0" , inner = "0 " },
close = { ord = "0" , op = "1" , bin = "(2)", rel = "(3)", open = "0" , close = "0" , punct = "0" , inner = "(1)" },
punct = { ord = "(1)", op = "(1)", bin = "*" , rel = "(1)", open = "(1)", close = "(1)", punct = "(1)", inner = "(1)" },
inner = { ord = "(1)", op = "1" , bin = "(2)", rel = "(3)", open = "(1)", close = "0" , punct = "(1)", inner = "(1)" }
}
local function subtype(n)
if not n then
return nil
end
return node.subtypes(n.id)[n.subtype]
end
local function traverse(head, style)
for n in node.traverse(head) do
if n.id == node.id("sub_mlist") then
traverse(n.list, style)
else
if subtype(n) == "bin" then
local undefined = false
-- look at the previous
local prevtype = subtype(n.prev)
if knuth_table[prevtype] and knuth_table[prevtype].bin == "*" then
undefined = true
local g = glue.copy(tex.getmath(prevtype .. "binspacing", style))
head = node.insert_before(head, n, g)
end
-- look at the next
local nexttype = subtype(n.next)
if undefined or knuth_table.bin[nexttype] == "*" then
local g = glue.copy(tex.getmath("bin" .. nexttype .. "spacing", style))
head = node.insert_after(head, n, g)
end
undefined = false
end
end
end
end
local function binordspacing(head,style,penalties)
traverse(head, style)
return true
end
luatexbase.add_to_callback("pre_mlist_to_hlist_filter", binordspacing, "binordspacing")
\end{luacode*}
% Add further abominations to this list
\Umathopenbinspacing\displaystyle=\thinmuskip
\Umathopenbinspacing\textstyle=\thinmuskip
\Umathbinordspacing\displaystyle=\thinmuskip
\Umathbinordspacing\textstyle=\thinmuskip
\begin{document}
\begin{equation*}
\alpha = -p(-w_1-v_0) - g(w_1)
\end{equation*}
\begin{center}
$\alpha = -p(-w_1-v_0) - g(w_1)$
\end{center}
\end{document}
答案2
你问,
这些间距不同的原因是什么?
确实有!你(重新)发现了-
作为+
或操作unary
员之间的区别binary
。
如果两种类型的运算符的间距相同,您可能会对它们相同感到恼火。
本质上,您所观察到的是数百年精细数学排版的结果,它已经确定使一元和二元运算符周围的间距相同并不是最佳的。
下面是一元和二元运算符的间距规则应用的一些实际例子。
\documentclass{article}
\begin{document}
\obeylines % just for this example
``$-$'' and ``$+$'' treated as unary operators:
$\dots,-3,-2,-1,0,+1,+2,+3,\dots$
$-1 \ne +1$
\bigskip
``$-$'' and ``$+$'' treated as binary operators:
$\dots,{}-3,{}-2,{}-1,0,{}+1,{}+2,{}+3,\dots$ --- looks awful!
$1+1=2$ \quad $2-2=0$
\bigskip
Mixed use:
$-1=5-6$ \quad $-5+6=+1$
\end{document}