METAPOST: Диаграмма Фейнмана, обрезанная с помощью XeLaTeX

METAPOST: Диаграмма Фейнмана, обрезанная с помощью XeLaTeX

Следующий код дает правильные результаты с 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.mpnow выглядит так:

...
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. Вы также можете рассмотреть возможность сообщения об ошибке автору пакета.

Связанный контент