将 PDF 中的数学符号转换为 LaTeX

将 PDF 中的数学符号转换为 LaTeX

我正在尝试从 LaTeX 生成的 PDF 文件中提取数学内容。大多数提取的符号都能顺利提取。但是有些符号(例如\epsilon\Updownarrow\simeq使用非 Unicode 代码,而其他符号(例如)\neq使用非 Unicode 代码的组合。

  • \epsilonSCCPFS+CMMI10使用嵌入字体和代码 017编写
  • \Updownarrow使用嵌入的字体KAXSYH+CMSY10和代码0x6d (m)
  • \simeq使用嵌入的字体KAXSYH+CMSY10和代码0x27 (')
  • \neq使用嵌入的字体KAXSYH+CMSY10和代码0x36 (/)以及0x3d (=)

在我开始编写一个表格来将字形代码映射到等效的 LaTeX 之前,我想知道是否已经存在这样的反向映射表供 LaTeX 使用。毕竟,原始的 等将在某个地方\epsilon映射\neq到一个或多个字形代码。组合情况也需要位置信息,但反向也应该有位置信息。

编辑:我尝试在字体表中查找此信息,但 GSUB 和 GPOS 中没有条目。我应该在那里查找吗?这些信息真的在字体中吗?

在此处输入图片描述

编辑:我尝试在文本编辑器中查找 mmap 文件,但它主要是十六进制。有没有可以打开它的工具?

%!PS-Adobe-3.0 Resource-CMap
%%DocumentNeededResources: ProcSet (CIDInit)
%%IncludeResource: ProcSet (CIDInit)
%%BeginResource: CMap (TeXmath-LMR-0)
%%Title: (TeXmath-LMR-0 TeXmath LMR 0)
%%Version: 1.000
%%EndComments
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo
<< /Registry (TeXmath)
/Ordering (LMR)
/Supplement 0
>> def
/CMapName /TeXmath-LMR-0 def
/CMapVersion 1.000 def
/CMapType 2 def
1 begincodespacerange
<00> <FF>
endcodespacerange
96 beginbfchar
<00> <005C00620069006700630069007200630020>
<01> <005C006D0064006C00670062006C006B0063006900720063006C00650020>
<02> <005C0073007100750061007200650020>
<03> <005C0062006C00610063006B0073007100750061007200650020>
<04> <005C0076006100720074007200690061006E0067006C00650020>
<05> <005C0062006C00610063006B0074007200690061006E0067006C00650020>
<06> <005C0074007200690061006E0067006C00650064006F0077006E0020>
<07> <005C0062006C00610063006B0074007200690061006E0067006C00650064006F0077006E0020>
<08> <005C006C006F007A0065006E006700650020>
<09> <005C0062006C00610063006B006C006F007A0065006E006700650020>
<0A> <005C006D0064006C00670062006C006B006400690061006D006F006E00640020>

编辑:我查找了 \neq 的字符,发现它由两种不同的字体组成,因此这些信息不太可能存在于一种字体中。在 texlive 目录中执行 grep 会给出一些提示:-

% grep -rw neq * | grep -w not
texmf-dist/tex/plain/base/plain.tex:\def\neq{\not=} \let\ne=\neq
texmf-dist/tex/generic/enctex/utf8raw.tex:\mubyte \neq ^^e2^^89^^a0\endmubyte % U+2260 not equal to
texmf-dist/tex/generic/ofs/ofs-cm.tex:  \def\neq{\not=} 
texmf-dist/tex/latex/listings/lstlang3.sty:      myfont,n,nat2string,neq,ngon,norm2,normalmap,not,nu_grid,nubspline,%
texmf-dist/tex/latex/sansmath/sansmath.sty:% two lines, but it did not work well (unbold +, bold greek, bad \neq)
texmf-dist/tex/latex/base/fontmath.ltx:\def\neq{\not=} \let\ne=\neq
texmf-dist/tex/latex/unicode-math/unicode-math-xetex.sty:  \cs_gset:cpn { not= }    { \neq }
texmf-dist/tex/latex/unicode-math/unicode-math-table.tex:\UnicodeMathSymbol{"02260}{\ne                       }{\mathrel}{/ne /neq r: not equal}%
texmf-dist/tex/latex/unicode-math/unicode-math-luatex.sty:  \cs_gset:cpn { not= }    { \neq }
texmf-dist/tex/latex/breqn/cmbase.sym:\DeclareFlexCompoundSymbol{\neq}{Rel}{\not{=}}
texmf-dist/tex/latex/breqn/mathpazo.sym:\DeclareFlexCompoundSymbol{\neq}{Rel}{\not{=}}
texmf-dist/tex/latex/breqn/mathptmx.sym:\DeclareFlexCompoundSymbol{\neq}{Rel}{\not{=}}

答案1

让我们从以下示例开始:

\documentclass{article}
\newcommand*\testsqrtsign[1]{\sqrtsign{\vphantom{#1}}}
\pagestyle{empty}
\begin{document}
\[
\testsqrtsign{|}\testsqrtsign{\big|}\testsqrtsign{\Big|}\testsqrtsign{\bigg|}\testsqrtsign{\Bigg|}
\]
\end{document}

通过 pdfLaTeX 编译上述代码,然后通过 Adob​​e Acrobat Reader DC 打开 PDF 文件。在打开的 PDF 文件中,按下Ctrl + F并在查找栏中输入“pqrsvuut”。按下Enter键或Next按钮,我们会发现

平方符号
这很奇怪不是吗?

进一步检查 PDF 文件,我们发现嵌入了一个名为“cmex10”的字体。这个简单的实验可以让您了解数学符号在默认 LaTeX(以及某种程度上 - 原始 TeX)中的编码方式。


回答你的问题

我想知道是否已经存在这样的反向映射表以供在 LaTeX 中使用。

简短的回答是:是的。

第一部分:默认数学编码

根据LaTeX 字体编码指南,默认情况下有 3 种数学字体编码(第 10 页第 2.6 节),即OMLOMS。 OMX具体来说,附录 A.4(第 33-34 页)列出了 3 个表格,显示了每个数学字母/符号的具体编码位置。

例如,

  • “希腊数学斜体小写 epsilon” 在OML位置'017(八进制) 或"0F(十六进制) 处编码,对应字体“cmmi10”(Computer Modern Math Italic 10);
  • “上下双箭头”在OMS位置'155(八进制)或"6D(十六进制)处编码,对应字体“cmsy10”(计算机现代数学符号10);
  • “中的积分符号”在位置(八进制)或(十六进制)\textstyle处编码,对应字体“cmex10”(计算机现代数学扩展 10);OMX'122"52

第 2 部分:从命令到插槽的映射

\epsilon包含命令及其对应插槽的映射的代码可以在以下位置\Updownarrow找到\intfontdef.dtx。例如,我们发现这些声明:

...
\DeclareSymbolFont{letters}     {OML}{cmm} {m}{it}
\DeclareSymbolFont{symbols}     {OMS}{cmsy}{m}{n}
\DeclareSymbolFont{largesymbols}{OMX}{cmex}{m}{n}
...
\DeclareMathSymbol{\epsilon}{\mathord}{letters}{"0F}
...
\DeclareMathDelimiter{\Updownarrow}
   {\mathrel}{symbols}{"6D}{largesymbols}{"77}
...
\DeclareMathSymbol{\intop}{\mathop}{largesymbols}{"52}
    \def\int{\intop\nolimits}
...

这是您要求的“反向”表:

  • \epsilon来自letters,其OML编码为 ,位于 "0F
  • \Updownarrowwhen 不作为分隔符,来自symbols,其OMS编码为 ,位于 "6D
  • \intop来自largesymbols,它被OMX编码并且当用于\textstyle位于 "52

第 3 部分:指示 LaTeX 加载实际的字体文件

这部分代码也可以在fontdef.dtx

...
\input  {omlcmm.fd}
\input  {omscmsy.fd}
\input  {omxcmex.fd}
...

但似乎与你当前的问题无关。请随意看看(La)TeX 在选择字体时如何使用字体相关文件 [...]?和相关文章以了解更多信息。之所以包含此部分,是因为……

第 4 部分:其他数学字体和非标准编码

newtxmath软件包提供了完整的直立希腊字母(\Gammaup\alphaup等)。它们来自,在aslettersA中声明为newtxmath.sty

...
\DeclareSymbolFont{lettersA}{U}{ntxmia}{m}{it}
...

其中U代表“未知”。相应的untxmia.fd文件包含各种字体:“nxlmia”、“zmnmia”、“zcochmia”、“zchmia”、“ntxstx2mia”和“ntxmia”,以及它们的粗体版本。理论上,作者可以对这些字体使用他/她喜欢的任何编码。对于newtxmath,我们看到

...
\re@DeclareMathSymbol{\Gammaup}{\mathalpha}{lettersA}{0}
...

因此,如果你写下,比如$\bm{\Gammaup}$,其中\bmbm包,则可以得到一个粗体直立希腊大写字母 Gamma。在 Unicode 中,“Mathematical Bold Capital Gamma” 的编码为U+1D6AA,而在 的“lettersA”中newtxmath,它的编码为 0(十进制,字体中的第一个位置)常规字体和粗体字体

现在您看到了问题:不能存在将提取的符号转换为其对应的 Unicode 字符的单一映射。

由于数学字体编码缺乏开发(请参阅 LaTeX 字体编码指南,第 1.2 节末尾的最后 3 段),数学字体可以有各种不同的“内部”编码。除了 的newtxmath“lettersA”(U-编码)外,还有amsfonts的“AMSa”和“AMSb”,均为U-编码;还有mtpro2的(商业字体)LMP1和编码;等等LMP2LMP3

结束语

市场上除了标准 3 之外还有许多数学字体编码,它们与特定字体绑定。有关输入字符与其对应字体槽之间的映射信息可在支持 LaTeX 包中找到。

由于没有“普遍认可的”数学字体编码,因此不能指望单身的将(如果存在)字形映射回命令/Unicode 字符。

如果你只是想在 PDF 文件中复制粘贴数学公式,那么也许可以unicode-math尝试一下:

% !TeX program = XeLaTeX or LuaLaTeX
\documentclass{article}
\usepackage{unicode-math}
\begin{document}
\[\int_0^{\pi\pm\epsilon} \sin x \, \symup{d} x = 2 \mp \delta\]
\end{document}

unicode 数学
跪拜在力量面前吧unicode-math,凡人!


好的——回到默认编码——为什么我们可以在“pqrsvuut”中搜索平方根符号?好吧,前 4 个扩展根符号分别在 、 和 位置编码;而OMX最后一个“垂直”根符号使用一个、两个和一个拼凑在一起。猜猜在到 位置通常是什么;-)"70"71"72"73"76"75"74"70"76

有关 LaTeX 如何处理字体的更多信息,请参阅两个主要参考资料(可在https://ctan.org/pkg/latex-base) 是

  • 字体编码指南
  • 字体选择指南

相关内容