Следующий код дает правильные результаты с 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
нужна эта команда.
Мое решение для взлома — исправить beginchar
это так, чтобы оно рисовало невидимый ящик, прежде чем мы начнем. Моя копия feynmp.mp
now выглядит так:
...
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
такой:
(Серая линия, видимая внизу этой картинки, показывает, где находится дно «невидимого» поля. Это артефакт, созданный ImageMagick, когда я конвертирую PDF в PNG. Я не вижу этого артефакта в версии PDF).
Причина, по которой я сомневаюсь в этом решении, заключается в том, что кажется неправильным сказать вам пропатчить вашу копию feynmp.mp
, поскольку вам придется заново вносить любые изменения при обновлении. Но это может быть самым простым способом исправить ситуацию в краткосрочной перспективе.
На моей системе MacOS с MacTeX 2016 файл находится по адресу
/usr/local/texlive/2016/texmf-dist/metapost/feynmf/feynmp.mp
но он может быть где-то еще в вашей системе. Существуют различные механизмы исправления пакетов LaTeX, но я не знаю, как применить их к исходным файлам Metapost. Вы также можете рассмотреть возможность создания локального дерева texmf с "исправленной" копией feynmp.mp
. Вы также можете рассмотреть возможность сообщения об ошибке автору пакета.