有没有办法定义一个宏来{#1}/{#2}
缩写命令\frac{#1}{#2}
?
答案1
原作者表示他更喜欢基于 pdfLaTeX 的解决方案。但是,由于我不知道如何提供这样的解决方案,所以我提供了一个基于 LuaLaTeX 的解决方案。也许那些不介意使用(或者实际上更喜欢使用!)LuaLaTeX 的读者会发现它很有用。
Lua 函数用于捕获和处理以下形式的表达式
{...}/{...}
模式匹配必须包含以下元素:(a) 两对匹配的花括号、(b) 符号/
和 (c)没有空格在 的左边和右边/
。如果未找到这三个元素,则不会发生模式匹配,也不会产生 `\frac{...}{...} 表达式。
编辑:该函数现在可以处理嵌套表达式,例如{{a}/{b}}/{{c}/{d}}
;它将产生\frac{\frac{a}{b}}{\frac{c}{d}}
。
下面的代码还设置了两个 LaTeX 宏:\InlineToFracStart
和\InlineToFracStop
。前者激活 Lua 函数,后者禁用它。拥有这些宏可能很有用,因为运行 Lua 函数会在扫描和处理输入行方面带来一些开销。例如,如果已知文档包含第{a}/{b}
2 节和第 3 节中的形式的表达式,但不包含其他地方,则可以\InlineToFracStart
在第 2 节的开头运行,\InlineToFracStop
在第 3 节的结尾运行。(当然,如果您不介意或不关心产生开销,只想让 Lua 函数覆盖整个文档,只需在语句\InlineToFracStart
之前或之后运行即可\begin{document}
。)
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
%% Lua-side code
\begin{luacode}
function inline2frac ( s )
s = s:gsub ( "(%b{})/(%b{})" , function (x,y)
x = inline2frac ( x )
y = inline2frac ( y )
return "\\frac{"..x.."}{"..y.."}"
end )
return s
end
\end{luacode}
%% TeX-side code: macros to enable and disable the Lua function
\newcommand\InlineToFracStart{\directlua{luatexbase.add_to_callback(
"process_input_buffer", inline2frac, "inline2frac" )}}
\newcommand\InlineToFracStop{\directlua{luatexbase.remove_from_callback(
"process_input_buffer", "inline2frac" )}}
\begin{document}
\InlineToFracStart % enable the Lua function
$\displaystyle {a}/{b} \quad {{a}/{c}}/{b}
\quad {{a}/{b}}/{{u}/{{v}/{{w}/{{x}/{y}}}}} \quad a/b$
\end{document}
答案2
没有LuaTeX,正如 OP 所指出的偏好,您可以使用原始\over
命令:{a\over b}
。然后您可以使用它来(几乎)完全按照您的建议去做:
编辑:@Manuel 指出,使其具有数学活性更好:
\documentclass{article}
\begin{document}
\mathcode`\/="8000
{\catcode`/=13\global\let/\over}
A/B % <- no effect
\[ {over the line/under the line} \]
\end{document}
请记住用括号将斜线括起来:{}
。例如可以{abc/def}
工作,但abc/def
可能不会按预期工作,因为现在数学模式中右边的所有内容/
都会变成分数,除非您使用括号{./.}
。
上一个答案:
\documentclass{article}
\begin{document}
\catcode`/=13
\def/{\ifmmode\over\else\char`\/\fi}
A/B \[ {over the line/under the line} \]
\end{document}
注意。在这两种情况下,在数学模式下使用斜线运算符总会得到分数。
答案3
除了 Mico 的版本,还有另一种使用 LuaTeX 的方法:无需操作输入,而是可以在排版之前修改实际的数学节点。这里括号的规则类似于下标:如果只有一个数学节点,则不需要括号。可以使用 插入普通斜线//
。
\documentclass{article}
\usepackage{luacode,amsmath}
\begin{luacode*}
local mathchar = node.id'math_char'
local transform
local function kernel_transform(list)
if list and list.id == 25 then
list.head = transform(list.head)
end
end
function transform(list)
node.slide(list)
for n in node.traverse(list) do
local cur = n
if n.nucleus and n.nucleus.id == mathchar and n.nucleus.fam == 1 and n.nucleus.char == 61 then
local prev, next = node.getboth(n)
if prev and next then
if next.nucleus and next.nucleus.id == mathchar and next.nucleus.fam == 1 and next.nucleus.char == 61 then
prev.next = next
n.next = next.next
else
local new = node.new'fraction'
new.num = node.new'sub_mlist'
new.denom = node.new'sub_mlist'
new.num.head = prev
new.denom.head = next
new.width = 0x40000000
new.attr = node.copy_list(n.attr)
local noad = new
noad.prev = n.prev.prev
noad.next = n.next.next
if prev.prev then
prev.prev.next = noad
else
list = noad
end
if next.next then
next.next.prev = noad
end
prev.next = nil
next.next = nil
n.next = noad.next
cur = new
end
end
end
kernel_transform(cur.nucleus)
kernel_transform(cur.sub)
kernel_transform(cur.sup)
kernel_transform(cur.num)
kernel_transform(cur.denom)
kernel_transform(cur.accent)
kernel_transform(cur.bot_accent)
kernel_transform(cur.display)
kernel_transform(cur.text)
kernel_transform(cur.script)
kernel_transform(cur.scriptscript)
kernel_transform(cur.degree)
end
return list
end
luatexbase.add_to_callback('mlist_to_hlist', function(list, type, pen)
list = transform(list)
return node.mlist_to_hlist(list, type, pen)
end,
'fraction_slash')
\end{luacode*}
\begin{document}
$\displaystyle a/b/c/d/e \quad a/\text{abc} \quad a/c/b
\quad a/b/{u/{v/{w/{x/y}}}} \quad a//b$
\end{document}