如果 .dtx 文件是 \DocInput,则 \inputencoding{latin1} 不能用于该文件的用户文档中

如果 .dtx 文件是 \DocInput,则 \inputencoding{latin1} 不能用于该文件的用户文档中

第三次编辑:(正如 Ulrike 指出的那样,我的问题实际上并不涉及listingsutf8而只涉及inputenc,因此我通过赋予问题另一个标题和另一个 MWE 来反映这一点。)

以下 MWE 指出,在一个.dtx文件中,同时:

  • ltxdoc文件\DocInput.dtx文件本身,
  • 用户文档(即注释部分)选择latin1使用 进行编码\inputencoding{latin1}

一个奇怪的错误:

***************************
* Character table correct *
***************************
(/usr/local/texlive/2014/texmf-dist/tex/latex/base/latin1.def

! Package doc Error: Character table corrupted.

See the doc package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.53 %%   Right brace   \}     Tilde         \~}

?

在编译期间被抛出pdfLaTeX

% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage[utf8]{inputenc}
\begin{document}
\DocInput{\jobname.dtx}
\inputencoding{latin1}
Foo bar.
\end{document}
%</driver>
% \fi
%
% \inputencoding{latin1}
%
% \Finale
\endinput

我不知道发生了什么事。

请注意,在以下情况下不会发生这种奇怪的错误:

  1. 要么\DocInput{\jobname.dtx}被移除,

  2. 或者将\inputencoding{latin1}声明直接插入ltxdoc文档主体中而不是用户文档中。

原始编辑:以下 MWE 指出,在一个.dtx文件中,同时:

  • 文件ltxdoc
    • 加载listingsutf8包,
    • \DocInput.dtx文件本身,
  • 用户文档包含一个lstlisting环境:
    • 使用listingsutf8inputencoding=utf8/latin1选项,
    • 包含utf8编码字符,

一个奇怪的错误:

***************************
* Character table correct *
***************************
(/usr/local/texlive/2014/texmf-dist/tex/latex/base/latin1.def

! Package doc Error: Character table corrupted.

See the doc package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.53 %%   Right brace   \}     Tilde         \~}

?

在编译期间被抛出pdfLaTeX

% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listingsutf8}
\begin{document}
\DocInput{\jobname.dtx}
\begin{lstlisting}
ü
\end{lstlisting}
\end{document}
%</driver>
% \fi
%
% \begin{lstlisting}[inputencoding=utf8/latin1]
% ü
% \end{lstlisting}
%
% \Finale
\endinput

我不知道发生了什么事。

请注意,在以下情况下不会发生这种奇怪的错误:

    1. 要么\DocInput{\jobname.dtx}被移除,
    2. 或者环境inputencoding=utf8/latin1选项lstlisting被删除(在这种情况下,Package inputenc Error: Unicode char会发生正常情况),
  1. lstlistingwith选项inputencoding=utf8/latin1中含有utf8编码字符的字符直接插入到ltxdoc文档主体中,

  2. \usepackage[T1]{fontenc}\usepackage[utf8]{inputenc}被删除,listingsutf8由 替换listings,并使用和XeLaTeX或编译。LuaLaTeX

第二次编辑:同样的问题也出现在更符合规范的使用方式中listingsutf8

% mylistings.txt file
\begin{lstlisting}
ü
\end{lstlisting}

和:

% .dtx file
% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listingsutf8}
\begin{document}
\DocInput{\jobname.dtx}
\lstinputlisting[inputencoding=utf8/latin1]{mylisting.txt}
\end{document}
%</driver>
% \fi
%
% \lstinputlisting[inputencoding=utf8/latin1]{mylisting.txt}
%
% \Finale
\endinput

答案1

错误的字符表来自错误的设置\endlinechar,请参阅 Ulrike 的评论。在 中设置\endlinechar是为了防止在水平模式下使用时行尾出现额外的空格和空行出现标记。因此,这个 的设置是必要的,而不是错误。-1\inputencoding\par\inputencoding\endlinechar

因此,问题反而是,为什么首先检查注释中的字符表。latin1.def不是 的参数\DocInput。原因是百分号的类别代码发生了变化,它是活动的,而不是注释字符。因此,\inputencoding通过确保百分号字符的类别代码,可以使其更加健壮。

应用修复的最小示例:

% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage[utf8]{inputenc}

\usepackage{etoolbox}
\makeatother
\pretocmd\inputencoding{%
  \xdef\saved@percent@catcode{\the\catcode`\%}%
  \catcode`\%14\relax
}{}{%
  \errmessage{Cannot patch \string\inputencoding}%
}
\apptocmd\inputencoding{%
  \catcode`\%\saved@percent@catcode\relax
}{}{%
  \errmessage{Cannot patch \string\inputencoding}%
}
\makeatother

\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% Hello\inputencoding{latin1} World
%
% \Finale
\endinput

如果 LaTeX3 类别代码有效(\ExplSyntaxOn或隐含地\ProvidesExplPackage,请参阅评论),它们必须被禁用,因为\inputencoding它们没有被expl3宏编码:

\RequirePackage{expl3}
\RequireExplPackage{...}
...
\ExplSyntaxOff
\pretocmd ...
\apptocmd ...
\ExplSyntaxOn    

其他修补方法:

\newcommand{\org@inputencoding}{} 
\let\org@inputencoding\inputencoding
\def\inputencoding#1{%
  \xdef\saved@percent@catcode{\the\catcode`\%}%
  \catcode`\%14\relax
  \org@inputencoding{#1}%
  \catcode`\%\saved@percent@catcode\relax
}

或者更优雅的是,包inputenc提供了两个钩子,分别在开始和结束时调用\inputencoding

\inpenc@prehook=\expandafter{\the\inpenc@prehook
  \xdef\saved@percent@catcode{\the\catcode`\%}%
  \catcode`\%14\relax
}
\inpenc@posthook=\expandafter{\the\inpenc@posthook
  \catcode`\%\saved@percent@catcode\relax
}

相关内容