
答案1
這是一個基於 LuaLaTeX 的解決方案。如果您被迫使用 pdfLaTeX,您可能會不走運。不過,希望答案對其他讀者仍然有用。
中綴分數表示法(例如a/b
和1/2
)的一個主要問題是,當 TeX 有機會注意到輸入流中存在符號時/
,應該形成分子的材料已經消失了;退格來恢復分子將是非常乏味的(甚至可能是不可能的)。基於預處理器的方法似乎更有前途。幸運的是,LuaTeX提供了process_input_buffer
回調,非常適合預處理。
以下範例程式碼提供了一個執行 infix 到 dfrac 轉換的 Lua 函數。唯一的語法要求是分子和分母中的字元僅由字母字元和阿拉伯數字組成。 (不允許括號)(斜線)符號左側或右側/
允許有空格。
/
考慮到with的替換\dfrac
,這個 Lua 函數應該絕不在內聯數學模式材料上運行,更不用說文字模式材料了,以免它對任何/
字元造成嚴重破壞。因此,程式碼還提供了兩個 LaTeX 巨集 -\ReplaceOn
和\ReplaceOff
- 來啟動和停用 Lua 功能。我建議您\ReplaceOn
在包含中綴分數的每組方程式的開頭插入一個指令,並\ReplaceOff
在每個此類組的末尾插入一個指令。
% !TEX TS-program = lualatex
\documentclass{article}
%% Lua-side code
\usepackage{luacode}
\begin{luacode*}
function sltodf ( s ) -- "slash to dfrac"
return ( string.gsub ( s , "(%w+)%s-/%s-(%w+)" , "\\dfrac{%1}{%2}" ) )
end
\end{luacode*}
%% TeX-side code
\newcommand\ReplaceOn{\directlua{luatexbase.add_to_callback (
"process_input_buffer", sltodf, "sltodf" )}}
\newcommand\ReplaceOff{\directlua{luatexbase.remove_from_callback (
"process_input_buffer", "sltodf" )}}
\usepackage{amsmath} % for '\dfrac' macro
\begin{document}
\ReplaceOn
\[ m /n + pq / rs = 1 / 2 - 21/ 32 . \] % lots of whitespace
\[m/n+pq/rs=1/2-21/32.\] % no whitespace at all
\[ 2a /3b + pq/rs = a / 5 - 61c/41d . \] % mixtures of letters and numerals
\ReplaceOff % no more infix to frac processing
\[ m /n + pq/rs = 1 / 2 - 21/32 . \]
\end{document}
附錄:為了自動將Lua函數的範圍擴展到整個文檔,有必要執行一些測試來檢查我們是否處於顯示數學環境中,並且只有在這種情況下才執行infix-to-frac轉換。以下範例顯示如何執行此操作。自動辨識六個顯示數學環境(除了「基本 LaTeX」\[
和\]
指令之外):equation
、align
、alignat
、flalign
、gather
和multline
。這些環境的“加星標”和“常規”變體均得到處理。
對輸入語法的要求相當溫和。表達式\[ ... \]
是允許的,就像所有顯示數學環境一樣,其中開始和結束語句(例如\begin{equation}
或\end{align}
)本身位於行上。
下面的程式碼還提供了巨集\ReplaceOff
和\ReplaceOn
,因為可能需要「手動」暫停 Lua 函數的操作,例如,在verbatim
包含 displaymath 程式碼的類似材料的情況下。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{amsmath} % for various displayed-equation environments
%% Lua-side code
\usepackage{luacode}
\begin{luacode*}
in_dispmath = false -- set up a Boolean variable
function sltofr ( s ) -- "slash to frac"
-- if we find a '\[ ... \]' line, perform infix fraction replacements
if string.find ( s , "\\%[.*\\%]" ) then
return ( string.gsub ( s , "(%w+)%s-/%s-(%w+)" , "\\frac{%1}{%2}" ) )
-- switch 'in_dispmath' to 'true' if at start of a displaymath env.
elseif string.find ( s , "\\begin{equation%*?}" ) or
string.find ( s , "\\begin{align%*?}" ) or
string.find ( s , "\\begin{alignat%*?}" ) or
string.find ( s , "\\begin{flalign%*?}" ) or
string.find ( s , "\\begin{gather%*?}" ) or
string.find ( s , "\\begin{multline%*?}" ) or
string.find ( s , "\\%[" ) then
in_dispmath = true
-- switch 'in_dispmath' back to 'false' if at end of a displaymath env.
elseif string.find ( s , "\\end{equation%*?}" ) or
string.find ( s , "\\end{align%*?}" ) or
string.find ( s , "\\end{alignat%*?}" ) or
string.find ( s , "\\end{flalign%*?}" ) or
string.find ( s , "\\end{gather%*?}" ) or
string.find ( s , "\\end{multline%*?}" ) or
string.find ( s , "\\%]" ) then
in_dispmath = false
-- if in displaymath mode, replace infix fractions with \frac expressions
elseif in_dispmath == true then
return ( string.gsub ( s , "(%w+)%s-/%s-(%w+)" , "\\frac{%1}{%2}" ) )
end
end
\end{luacode*}
%% TeX-side code
% Assign the Lua function to the 'process_input_buffer' callback
\AtBeginDocument{\directlua{luatexbase.add_to_callback (
"process_input_buffer", sltofr, "sltofr" )}}
% Macros to enable and disable the Lua function "by hand";
% this may be needed if the document contains verbatim sections
% that feature displaymath-mode code
\newcommand\ReplaceOn{\directlua{luatexbase.add_to_callback (
"process_input_buffer", sltofr, "sltofr" )}}
\newcommand\ReplaceOff{\directlua{luatexbase.remove_from_callback (
"process_input_buffer", "sltofr" )}}
\begin{document}
\[ 2m /3n + pq / rs = 1 / 2 - 33/ 55 . \]
\[
2m/3n+pq/rs=1/2-33/55.
\]
\[1/2+1/2=1\]\[1/3+1/3+1/3=1\]
\begin{align*}
1/2+1/2 &=1\\
1/3+1/3 + 1 / 3 &= 1
\end{align*}
When not in display math mode, no processing: ``and/or'', $a/b$, $1/2$
\ReplaceOff % get ready for some verbatim material
\begin{verbatim}
\begin{align*}
1/2+1/2 &=1\\
1/3+1/3 + 1 / 3 &= 1
\end{align*}
\end{verbatim}
\ReplaceOn % back to 'normal' (replacement) mode
\begin{align*}
1/2+1/2 &=1\\
1/3+1/3 + 1 / 3 &= 1
\end{align*}
\end{document}
答案2
如果提供的文件另存為f.tex
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\begin{document}
\[ m/n + p/q = 2/3 . \]
I want
\[\dfrac{m}{n} + \dfrac{p}{q} = \dfrac{2}{3}.\]
\end{document}
然後
sed -e "s@ \([a-zA-Z0-9]\+\)/\([a-zA-Z0-9]\+\) @ \\\\dfrac{\\1}{\\2} @g" f1.tex > f2.tex
將產生
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\begin{document}
\[ \dfrac{m}{n} + \dfrac{p}{q} = \dfrac{2}{3} . \]
I want
\[\dfrac{m}{n} + \dfrac{p}{q} = \dfrac{2}{3}.\]
\end{document}
sed
預設情況下,在類 UNIX 系統(linux、macos、cygwin...)中可用,並且在 Windows 上的許多地方都可以使用。
如果不需要命令列 sed,也可以在任何文字編輯器中完成相同的正規表示式替換。