将行内方程式转换为 TeX 代码(有任何包吗?)

将行内方程式转换为 TeX 代码(有任何包吗?)

我有一个可以实现方程式的软件,并且可以在线写入它们,例如:

==================

x = a_avg + ((x-1)/b_trans)^(-y^(-x))

y = ....

z = .... (something that have a similar form)

... etc, etc

=================

所以基本上,我有*.doc这些方程式,我想把它们转换成 Latex,这样它们看起来就像这样:

$x = a_{avg} + \frac{x-1}{b_{trans}}^{-y^{-x}}$ 

挑战在于将索引(例如 )转换avgtrans{}标或上标。也可以转换()/()\frac{}{}。有人知道有这样一个包可以将整个文档转换为方程列表吗?或者有人知道如何做到这一点吗?

我将非常感激您的建议!

保罗

答案1

如果 eq.txt 包含类似以下行

x = a_avg + ((x-1)/b_trans)^(-y^(-x))

然后是一个简单的编辑行,例如

 sed -e 's/(/{(/g' -e 's/)/)}/g'  -e 's/\//\\over /g' -e 's/_\([a-z]*\)/_{\\mathrm{\1}}/g' -e 's/.*/$\0$/' eq.txt 

将输出

$x = a_{\mathrm{avg}} + {({(x-1)}\over b_{\mathrm{trans}})}^{(-y^{(-x)})}$

每行

当排版为

\documentclass{article}

\begin{document}

$x = a_{\mathrm{avg}} + {({(x-1)}\over b_{\mathrm{trans}})}^{(-y^{(-x)})}$

\end{document}

生产

在此处输入图片描述

我在这里使用了 sed,但您可以使用 perl 或 lua 或您的编辑器搜索/替换。


实际上,您需要在括号中使用正则表达式多下点功夫(注意有一个)滑落了……),但我希望这足以展示基本思想。

答案2

这是一个不寻常的答案,因为虽然它确实将 OP 的代码转换为 LaTeX 代码,但该代码的存储方式是计算机可以读取的,而不是人眼可以读取的。因此,描述这个答案更合适的方法是它提供了一个用 LaTeX 编写的解释器,用于转换和呈现以非 LaTeX 格式提供的方程式。然而,最新的更新现在可以将内部代码转换为去标记化的翻译相关的 LaTeX 代码。

这个答案已经更新了很多:

已编辑,以便可以解析选定的数学运算符和希腊字母而无需转义(例如,cos x = beta正确解析)。可以添加更多内容。

已编辑,因此方括号[...]可以用作不可见的分组字符。

重新编辑以自动转换/\frac样式(感谢 David 的\over描述使用 \over 与 \frac 的实际后果如何?)。

已编辑以提供自动化。

经过编辑,提供翻译以及解释性呈现。

解释方程式

此答案自动执行使用 LaTeX 宏解释以非 LaTeX 用户语法表达的方程式的过程。我提供了 LaTeX 宏,\interpreteq{}其中传递了非乳胶方程式,在 7 个阶段进行解析,重构并呈现为 LaTeX 方程式。

这种方法的真正巧妙之处在于,用户输入的非 LaTeX 格式的方程式会被解析为数学“基因”,这些基因会按照运算顺序组成方程式。然后,每个基因会被转换成 LaTeX 格式,生成的基因会自动重组为可执行 LaTeX 代码的 DNA 链。

但是,可执行代码的 DNA 链间接地表达在listofitems包的内部表示中,该包用于以数学方式分割原始的非 LaTeX 方程。方程的这个内部表示(看起来很奇怪)可以在\detokenize\expandafter{\Z}的结尾处显示,作为该方法的证明\interpreteq。这将提供实际执行的标记,以呈现方程的 LaTeX 形式。

举例来说,采用用户格式化(非 LaTeX)的方程式:

x = a_avg + ([x-1] /b_trans)^(-y^[-x])

该包使用以下解析层次结构将此标记字符串解析到列表listofitems中:\Q

\setsepchar[@]{=@(||)||[||]@^@/||*@+||-@_@alpha||beta||pi||cos||sin||tan}

解析的第一层是查找 的实例=。 左侧的所有代码=都存储在 中\Q[1],而 [第一个] 右侧=(以及第二个 左侧=)的所有代码都存储在 中\Q[2]。 此级别的分隔符(即=)存储在 中\Qsep[1]

对于每个部分\Q[1]\Q[2],都会发生第二级解析,即查找()[和的所有实例]。因此,例如\Q[2,3]表示 [非 LaTeX] DNA 链位于 右侧=且位于括号或方括号分隔符的第 3 个实例之前。

根据 PEMDAS 操作顺序,此过程继续进行 7 级以上的解析:

  1. =
  2. ()[, 和]
  3. ^
  4. /*
  5. +-
  6. _
  7. alpha、、、、、以及其他所需功能betapicossintan

任何不是可解析分隔符的内容最终都会出现在某个低级\Q[.,.,...]基因条目中。但是,所有可解析分隔符最终都会出现在\Qsep[.,.,...]分隔符基因条目中。这些\Qsep条目需要转换转换为 LaTeX 格式,这个过程由宏执行\QS

\def\QS[#1]{%
  \if+\Qsep[#1]+\else%
  \if-\Qsep[#1]-\else%
  \if/\Qsep[#1]\over\else%
  \if=\Qsep[#1]=\else%
  \if^\Qsep[#1]^\else%
  \if(\Qsep[#1]\bgroup\left(\else%
  \if)\Qsep[#1]\right)\egroup\else%
  \if[\Qsep[#1]\bgroup\else%
  \if]\Qsep[#1]\egroup\else%
  \if*\Qsep[#1]\cdot\else%
  \if_\Qsep[#1]\expandafter\theund\else%
  \csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}

\Q[]然后,DNA 被重构为对索引序列和\QS[](转换的)基因的调用字符串\Qsep[]。它们都以原始顺序出现在切片中。因此,例如,用户格式方程(x = a_avg + ([x-1] /b_trans)^(-y^[-x]))一旦被切片并被转换\interpreteq,就会通过以下表达式重构为 DNA 链:

\Q [1,1,1,1,1,1,1]\QS [1]\Q [2,1,1,1,1,1,1]\QS [2,1,1,1,1,1]\Q [2,1,1,1,1,2,1]\QS
[2,1,1,1,1]\Q [2,1,1,1,2,1,1]\QS [2,1]\Q [2,2,1,1,1,1,1]\QS [2,2]\Q [2,3,1,1,1,1,1]\QS
[2,3,1,1,1]\Q [2,3,1,1,2,1,1]\QS [2,3]\Q [2,4,1,1,1,1,1]\QS [2,4,1,1]\Q [2,4,1,2,1,1,1]\QS
[2,4,1,2,1,1]\Q [2,4,1,2,1,2,1]\QS [2,4]\Q [2,5,1,1,1,1,1]\QS [2,5,1]\Q [2,5,2,1,1,1,1]\QS
[2,5]\Q [2,6,1,1,1,1,1]\QS [2,6,1,1,1]\Q [2,6,1,1,2,1,1]\QS [2,6,1]\Q [2,6,2,1,1,1,1]\QS
[2,6]\Q [2,7,1,1,1,1,1]\QS [2,7,1,1,1]\Q [2,7,1,1,2,1,1]\QS [2,7]\Q [2,8,1,1,1,1,1]\QS
[2,8]\Q [2,9,1,1,1,1,1]

并且,基于\Q和中的基因\QS,结果看起来像是期望的,即

在此处输入图片描述

翻译方程式

翻译可以通过宏形式实现,\translateeq{}也可以通过空间分离方程的翻译环境实现

\begin{translateeqs}% NO BLANK LINE IS PERMITTED HERE
EQ1

EQ2

...

EQn
\end{translateeqs}% NO BLANK LINE IS PERMITTED BEFORE HERE

这仅通过临时重新定义过程中的几个关键宏并使用将和基因\protected@edef扩展为它们相关的 LaTeX 代码来实现。然后,生成的方程式不会像以前一样呈现,而是以去标记化的 LaTeX 代码呈现。 \Q\QS

实际上,翻译可以在单独的文档中完成,并将结果从生成的 PDF 复制并粘贴到目标源文档中。

数学家

您将在以下 MWE 中看到的 5 个方程式(解释和翻译)均以非 LaTeX 形式输入。转换过程的显著亮点包括处理多字符下标而不进行分组、识别大量文本(非宏)数学函数和希腊字母名称(可以添加更多)、自动转换/为分数、自动调整括号大小、转换*\cdot等。以下是 5 个方程式:

cos(1/s) = f*g

f(x) = y^(2*x) =beta

f(x) = pi * y^[((2/x)^3 + [B/x_i])^n] =(z/B)^(2/x_i)

f(x) = pi * y^[((2/x)^3 +  B/x_i )^n] =(z/B)^(2/x_i)

x = a_avg + ([x-1] /b_trans)^(-y^[-x])

以下是 MWE:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{listofitems,ifthen}

\def\QS[#1]{%
  \if+\Qsep[#1]+\else%
  \if-\Qsep[#1]-\else%
  \if/\Qsep[#1]\over\else%
  \if=\Qsep[#1]=\else%
  \if^\Qsep[#1]^\else%
  \if(\Qsep[#1]\bgroup\left(\else%
  \if)\Qsep[#1]\right)\egroup\else%
  \if[\Qsep[#1]\bgroup\else%
  \if]\Qsep[#1]\egroup\else%
  \if*\Qsep[#1]\cdot\else%
  \if_\Qsep[#1]\expandafter\theund\else%
  \csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}%

\def\theund#1[#2]{_{\mathrm{#1[#2]}}}%

\setsepchar[@]{=@(||)||[||]@^@/||*@+||-@_@alpha||beta||pi||cos||sin||tan}

\makeatletter

\def\gQ[#1]{\edef\tmp{#1}\expandafter\g@addto@macro\expandafter\Z%
  \expandafter{\expandafter\Q\expandafter[\tmp]}}
\def\gQS[#1]{\edef\tmp{#1}\expandafter\g@addto@macro\expandafter\Z%
  \expandafter{\expandafter\QS\expandafter[\tmp]}}

\makeatother

\newcommand\interpreteq[1]{%
  \def\Z{}%
  \greadlist*\Q{#1}%
  \presentQ%
  \Z%
}

\newcounter{lindex}
\def\presentQ{% =
  \setcounter{lindex}{0}%
  \whiledo{\value{lindex}<\listlen\Q[]}{%
    \stepcounter{lindex}%
    \presentQA[\thelindex]%
    \ifnum\value{lindex}<\listlen\Q[]\relax%
      \gQS[\thelindex]%
    \fi%
  }%
}
\newcounter{lindexA}
\def\presentQA[#1]{% ()
  \setcounter{lindexA}{0}%
  \whiledo{\value{lindexA}<\listlen\Q[#1]}{%
    \stepcounter{lindexA}%
    \presentQB[#1,\thelindexA]%
    \ifnum\value{lindexA}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexA]%
    \fi%
  }
}
\newcounter{lindexB}
\def\presentQB[#1]{% ^
  \setcounter{lindexB}{0}%
  \whiledo{\value{lindexB}<\listlen\Q[#1]}{%
    \stepcounter{lindexB}%
    \presentQC[#1,\thelindexB]%
    \ifnum\value{lindexB}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexB]%
    \fi%
  }
}
\newcounter{lindexC}
\def\presentQC[#1]{% /*
  \setcounter{lindexC}{0}%
  \whiledo{\value{lindexC}<\listlen\Q[#1]}{%
    \stepcounter{lindexC}%
    \presentQD[#1,\thelindexC]%
    \ifnum\value{lindexC}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexC]%
    \fi%
  }
}
\newcounter{lindexD}
\def\presentQD[#1]{% +-
  \setcounter{lindexD}{0}%
  \whiledo{\value{lindexD}<\listlen\Q[#1]}{%
    \stepcounter{lindexD}%
    \presentQE[#1,\thelindexD]%
    \ifnum\value{lindexD}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexD]%
    \fi%
  }
}
\newcounter{lindexE}
\def\presentQE[#1]{% _
  \setcounter{lindexE}{0}%
  \whiledo{\value{lindexE}<\listlen\Q[#1]}{%
    \stepcounter{lindexE}%
    \presentQF[#1,\thelindexE]%
    \ifnum\value{lindexE}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexE]%
    \fi%
  }
}
\newcounter{lindexF}
\def\presentQF[#1]{% alpha beta pi cos sin tan
  \setcounter{lindexF}{0}%
  \whiledo{\value{lindexF}<\listlen\Q[#1]}{%
    \stepcounter{lindexF}%
    \gQ[#1,\thelindexF]%
    \ifnum\value{lindexF}<\listlen\Q[#1]\relax%
      \gQS[#1,\thelindexF]%
    \fi%
  }
}

% THESE ARE THE REDEFITIIONS FOR TRANSLATION
\usepackage{environ}

\def\QSALT[#1]{%
  \if+\Qsep[#1]+\else%
  \if-\Qsep[#1]-\else%
  \if/\Qsep[#1]\over\else%
  \if=\Qsep[#1]=\else%
  \if^\Qsep[#1]^\else%
  \if(\Qsep[#1]{\left(\else%
  \if)\Qsep[#1]\right)}\else%
  \if[\Qsep[#1]{\else%
  \if]\Qsep[#1]}\else%
  \if*\Qsep[#1]\cdot\else%
  \if_\Qsep[#1]\expandafter\theundALT\else%
  \expandafter\noexpand\csname \Qsep[#1]\endcsname\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}%

\def\theundALT#1[#2]{_{\noexpand\mathrm{#1[#2]}}}%

\makeatletter
\newcommand\translateeq[1]{%
  \bgroup%
  \let\QS\QSALT%
  \def\Z{}%
  \greadlist*\Q{#1}%
  \presentQ%
  \protected@edef\ZZ{\Z}
  \par\medskip\noindent%
  \parbox{\linewidth}{\detokenize\expandafter{\ZZ}}%
  \par\medskip%
  \egroup%
}
\makeatother

\NewEnviron{translateeqs}{\expandafter\nexteqn\BODY\par\relax}

\long\def\nexteqn#1\par#2\relax{%
  \translateeq{#1}\ifx\relax#2\else\nexteqn#2\relax\fi%
}
\begin{document}
\textbf{INTERPRETATING EQUATIONS}
\[
\interpreteq{cos(1/s) = f*g}
\]
\[
\interpreteq{f(x) = y^(2*x) =beta}
\]
\[
\interpreteq{f(x) = pi * y^[((2/x)^3 + [B/x_i])^n] =(z/B)^(2/x_i)}
\]
\[
\interpreteq{f(x) = pi * y^[((2/x)^3 +  B/x_i )^n] =(z/B)^(2/x_i)}
\]
\[
\interpreteq{x = a_avg + ([x-1] /b_trans)^(-y^[-x])}
\]

This is the code ``DNA'' that expresses the above equation:

\detokenize\expandafter{\Z}% COPY/PASTE RESULT OF THIS FROM PDF TO BELOW

See?  I copied/pasted it into equation mode and get the same result.
\[
\Q [1,1,1,1,1,1,1]\QS [1]\Q [2,1,1,1,1,1,1]\QS [2,1,1,1,1,1]\Q [2,1,1,1,1,2,1]\QS
[2,1,1,1,1]\Q [2,1,1,1,2,1,1]\QS [2,1]\Q [2,2,1,1,1,1,1]\QS [2,2]\Q [2,3,1,1,1,1,1]\QS
[2,3,1,1,1]\Q [2,3,1,1,2,1,1]\QS [2,3]\Q [2,4,1,1,1,1,1]\QS [2,4,1,1]\Q [2,4,1,2,1,1,1]\QS
[2,4,1,2,1,1]\Q [2,4,1,2,1,2,1]\QS [2,4]\Q [2,5,1,1,1,1,1]\QS [2,5,1]\Q [2,5,2,1,1,1,1]\QS
[2,5]\Q [2,6,1,1,1,1,1]\QS [2,6,1,1,1]\Q [2,6,1,1,2,1,1]\QS [2,6,1]\Q [2,6,2,1,1,1,1]\QS
[2,6]\Q [2,7,1,1,1,1,1]\QS [2,7,1,1,1]\Q [2,7,1,1,2,1,1]\QS [2,7]\Q [2,8,1,1,1,1,1]\QS
[2,8]\Q [2,9,1,1,1,1,1]
\]

\textbf{TRANSLATING EQUATIONS}
\begin{translateeqs}% NO BLANK LINE IS PERMITTED HERE
cos(1/s) = f*g

f(x) = y^(2*x) =beta

f(x) = pi * y^[((2/x)^3 + [B/x_i])^n] =(z/B)^(2/x_i)

f(x) = pi * y^[((2/x)^3 +  B/x_i )^n] =(z/B)^(2/x_i)

x = a_avg + ([x-1] /b_trans)^(-y^[-x])
\end{translateeqs}% NO BLANK LINE IS PERMITTED BEFORE HERE

\translateeq{x = a_avg + ([x-1] /b_trans)^(-y^[-x])}

\end{document}

在此处输入图片描述

相关内容