以下代码使用 PDFLaTex 给出了正确的结果,但如果我运行 XeLaTeX(我需要对整个文档执行此操作),部分胶子线会被切断。
\documentclass{article}
\usepackage{feynmp-auto}
\begin{document}
\begin{fmffile}{fgraph_qxq_z_gz_s}
\setlength{\unitlength}{0.5cm}
\begin{fmfgraph*}(8,5)
\fmfleft{i0,i1}
\fmfright{o0,o1}
\fmf{fermion , label=$\overline{q}$}{w0,i0}
\fmf{fermion , label=$q $}{i1,w0}
\fmf{boson , label=$Z^0 $}{w0,w1}
\fmf{gluon , label=$g $}{w1,o0}
\fmf{boson , label=$Z^0 $}{w1,o1}
\end{fmfgraph*}
\end{fmffile}
\end{document}
我该如何避免这种情况?
编辑:更改\documentclass{minimal}
并\documentclass{article}
添加了下面的输出差异图像(来自用户 Dr. Manuel Kuehner):
pdflatex
赛莱特
答案1
这可能只是答案的开始,因为我不太确定解决这个问题的最佳方法是什么。
问题是胶子的底部超出了 Metapost 生成的图形的边界框,并且xetex
对此非常热衷,并将图形裁剪到边界框中;pdftex
更宽松,包括所有内容,甚至包括应该裁剪的胶子部分。所以很难说 xetex 有错——如果有什么问题的话,我会说 pdftex 应该被“纠正”。
但是胶子是如何被画到边界框外面的呢?
通常情况下,Metapost 会自动计算并设置边界框,以包含绘图的所有元素。但该语言还提供了一个setbounds
命令,可让您在绘图过程中的任何时候任意设置边界框。例如,它的一个用途是在绘图周围创建空白边缘。
源代码中的这一\end{fmfgraph*}
行将完成绘图并将所有相关命令写入 Metapost 文件,最后是 Metapost 宏endchar;
。事实上,完成的 MP 文件如下所示:
% fgraph_qxq_z_gz_s.mp -- do not edit, generated automatically by glue.tex
input feynmp
require_RCS_revision "1.30";
beginchar(1, 8*14.22636pt#, 5*14.22636pt#, 0);
"feynmf: 1";
LaTeX_unitlength:=14.22636pt;
subgraph (0, 0, w, h);
vinit;
pickup pencircle scaled thin;
vleft (__i0, __i1);
vright (__o0, __o1);
vconnect ("fermion , label=$\overline {q}$", __w0, __i0);
vconnect ("fermion , label=$q $", __i1, __w0);
vconnect ("boson , label=$Z^0 $", __w0, __w1);
vconnect ("gluon , label=$g $", __w1, __o0);
vconnect ("boson , label=$Z^0 $", __w1, __o1);
vfreeze;
vdraw;
endsubgraph;
endchar;
% the end.
end.
endinput;
请注意,在顶部,您包括了feynmp.mp
并且在原始命令之前调用的最后一个宏end
是endchar;
。如果您查看feynmp.mp
系统,您将看到endchar
定义如下:
vardef endchar =
setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
if LaTeX_file <> "":
write EOF to LaTeX_file;
LaTeX_file := "";
fi
endfig
enddef;
为了整洁起见,软件包的作者决定裁剪图片,以便它适合由w
和h
参数定义的框(当然,这些参数设置为您用定义的宽度和高度\begin{fmfgraph*}(8,5)
)。此setbounds
命令实际上不会更改任何绘图命令,它只会使 MP 将指定的边界框写入它生成的 PostScript。因此,当 xetex“正确”遵循边界框尺寸时,胶子会被切断,但当 pdftex“有用地”忽略边界框时,胶子的脚仍然会被绘制。
显而易见的解决方案(以我的拙见)是删除整行:
setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
如果您编辑本地副本,那么您会发现它xetex
可以正确处理您的文件,如下所示:
但正如您立即看到的,由于某种原因,标签现在全部向右偏移了!
仔细观察一下发生的情况,似乎标签绘图宏对图形的大小做出了假设,这就是setbounds
需要该命令的原因。
我的 hack 解决方案也是修复beginchar
,这样它就会在我们开始之前绘制一个不可见的框。我feynmp.mp
现在的副本如下所示:
...
vardef beginchar (expr c, wd, ht, dp) =
LaTeX_file := "";
beginfig(c);
w:=wd;
h:=ht;
% new line added here to draw an "invisible" box
undraw (0,0)--(w,0)--(w,h)--(0,h)--cycle;
enddef;
string LaTeX_file;
vardef endchar =
% next line removed
% setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
if LaTeX_file <> "":
write EOF to LaTeX_file;
LaTeX_file := "";
fi
endfig
enddef;
...
你的图片就是xetex
这样的:
(此图片底部可见的灰线显示了“不可见”框的底部位置。这是我将 pdf 转换为 png 时 ImageMagick 生成的伪影。我在 PDF 版本中看不到该伪影)。
我之所以对这个解决方案犹豫不决,是因为我觉得告诉你修补你的 副本是完全错误的feynmp.mp
,因为升级时你必须重新做任何更改。但这可能是短期内解决问题的最简单方法。
在我的 MacOS 系统上,MacTeX 2016 的文件位于
/usr/local/texlive/2016/texmf-dist/metapost/feynmf/feynmp.mp
但它可能位于您系统的其他地方。有多种机制可以修补 LaTeX 包,但我不知道如何将它们应用于 Metapost 源文件。您还可以考虑使用 的“固定”副本制作本地 texmf 树feynmp.mp
。您还可以考虑向包作者提出错误。