带有 eplain 的 LaTeX graphic[sx] 包因驱动程序 dvipdfmx 而失败

带有 eplain 的 LaTeX graphic[sx] 包因驱动程序 dvipdfmx 而失败

根据TeX 常见问题解答为了获得dvipdfm[x] 和非 eps 图形文件的边界框支持(带有.xbb和文件),必须指定驱动程序,如下所示:.bb

\usepackage[dvipdfmx]{graphicx}

不幸的是,这失败了

Forbidden control sequence found while scanning...\newif...

我认为这是由于 plainTeX 将 \newif 定义为“外部”造成的。

有几个问题:

  1. 这可以被认为是miniltx/eplain中的一个错误吗?
  2. 类似这样的包以“内部”方式graphic[sx]使用有什么好处\newif?换句话说,是否值得破坏 plainTeX 以使其可以以“内部”方式使用?
  3. 最不具侵入性/最简单的解决方法是什么?

对于问题 3 的答案,我只能想到以下做法:

% Save the plain format's \newif
\let\plainnewif = \newif

% Re-def \newif without \outer
\catcode`@ = 11
\def\newif#1{\count@\escapechar \escapechar\m@ne
  \expandafter\expandafter\expandafter
   \def\@if#1{true}{\let#1=\iftrue}%
  \expandafter\expandafter\expandafter
   \def\@if#1{false}{\let#1=\iffalse}%
  \@if#1{false}\escapechar\count@}
\catcode`@ = 12

% latex packages (assumes the use of eplain)
\beginpackages
    \usepackage[dvipdfmx]{graphicx}
\endpackages

% Restore plain format's \newif
\let\newif = \plainnewif

答案1

我无法重建错误。但对于外部宏的去外部化,您可以编写更简单的代码:

\let\plainnewif=\newif
\def\newif{\csname plainnewif\endcsname}

答案2

具体解决'问题出在哪里'部分,我可以\newif在中找到一个用法dvipdfmx.def

\def\Ginclude@eps#1{%
 \message{<#1>}%
  \bgroup
  \newif\if@trim@vport
  \ifx\Undefined\Gin@vllx\else\@trim@vporttrue\fi
  \def\@tempa{!}%
  \dimen@\Gin@urx\p@
  \advance\dimen@ -\Gin@llx\p@
  \if@trim@vport
  \advance\dimen@ \Gin@vllx\p@
  \fi
  \edef\Gin@urx{\strip@pt\dimen@}%
  \dimen@\Gin@ury\p@
  \advance\dimen@ -\Gin@lly\p@
  \if@trim@vport
  \advance\dimen@ \Gin@vlly\p@
  \fi
  \edef\Gin@ury{\strip@pt\dimen@}%
  \dimen@\Gin@req@width
  \[email protected]%
  \divide\dimen@\dimen@ii
  \@tempdima\Gin@req@height
  \divide\@tempdima\dimen@ii
    \special{PSfile="#1"\space
      \if@trim@vport
      llx=\Gin@vllx\space
      lly=\Gin@vlly\space
      \fi
      urx=\Gin@urx\space
      ury=\Gin@ury\space
      \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi
      \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi
      \ifGin@clip clip\fi}%
  \egroup}

看看那段代码,我认为将条件移到宏外面的替代方法也应该可行

\newif\if@trim@vport
\def\Ginclude@eps#1{%
 \message{<#1>}%
  \bgroup
  \@trim@vportfalse
  \ifx\Undefined\Gin@vllx\else\@trim@vporttrue\fi
  \def\@tempa{!}%
  \dimen@\Gin@urx\p@
  \advance\dimen@ -\Gin@llx\p@
  \if@trim@vport
  \advance\dimen@ \Gin@vllx\p@
  \fi
  \edef\Gin@urx{\strip@pt\dimen@}%
  \dimen@\Gin@ury\p@
  \advance\dimen@ -\Gin@lly\p@
  \if@trim@vport
  \advance\dimen@ \Gin@vlly\p@
  \fi
  \edef\Gin@ury{\strip@pt\dimen@}%
  \dimen@\Gin@req@width
  \[email protected]%
  \divide\dimen@\dimen@ii
  \@tempdima\Gin@req@height
  \divide\@tempdima\dimen@ii
    \special{PSfile="#1"\space
      \if@trim@vport
      llx=\Gin@vllx\space
      lly=\Gin@vlly\space
      \fi
      urx=\Gin@urx\space
      ury=\Gin@ury\space
      \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi
      \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi
      \ifGin@clip clip\fi}%
  \egroup}

\outer事实上,我怀疑这是一个 plain 的定义指出了奇怪之处的地方\newif:没有明显的原因可以解释为什么当前代码在那里有这样的定义。

请注意,这并不是真正的错误miniltx:通常的理解是,使用纯文本(即使是 LaTeX 派生的)的代码必须允许某个\outer 版本\newif(要么不在宏中使用它,要么通过 csname 访问)。

相关内容