编辑: inputencoding=latin1
最初写的选项应该inputencoding=utf8/latin1
如果listingsutf8
's 选项inputencoding=utf8/latin1
导致latin1.def
每次使用列表时读取文件,如以下 MWE 所指出的那样:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listingsutf8}
\usepackage{multido}
\usepackage{filecontents}
\begin{filecontents}{\jobname.code}
Foo
\end{filecontents}
% \lstset{inputencoding=utf8/latin1}
\begin{document}
\multido{}{1000}{%
\lstinputlisting{\jobname.code}
}
\end{document}
这可能会导致大量时间的浪费:time pdflatex test
此 MWE 的编译结果如下\lstset{inputencoding=utf8/latin1}
:
评论道:
pdflatex 测试 1,68s 用户 1,49s 系统 99% cpu 3,189 总计
不是评论道:
pdflatex 测试 2,66s 用户 2,26s 系统 99% cpu 4,956 总计
latin1.def
您能找到让文件只被读取一次的方法吗?
答案1
包listingsutf8
将列表文件从 UTF-8 重新编码为指定的 8 位编码,然后再将其传递给listings
。由于编码实际上发生了变化,包会从文件 ( )\inputencoding
中加载编码的活动字符的新定义。每次更改编码时都必须重复这些重新定义。.def
latin1.def
以下代码侵入宏\inputencoding
,捕获 的调用\input
并临时重新定义它。新定义通过包 将文件加载到宏中catchfile
。然后下一次,将使用此全局宏而不是加载文件。由于.def
的文件inputenc
不应包含类别代码更改等奇怪的东西,因此可以在此处使用一个简单的宏。否则,内容必须通过较慢的 传递\scantokens
。
例子:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listingsutf8}
\usepackage{multido}
\usepackage{filecontents}
\begin{filecontents}{\jobname.code}
Foo
\end{filecontents}
\lstset{inputencoding=utf8/latin1}
%%% Begin hack
\usepackage{catchfile}
\let\SavedInputEncoding\inputencoding
\renewcommand*{\inputencoding}{%
\let\TempSavedInput\input
\let\input\CachedInput
\SavedInputEncoding
}
\newcommand*{\CachedInput}[1]{%
\let\input\TempSavedInput
\ifcsname CachedInput@#1\endcsname
\else
\CatchFileDef\TempCachedInput{#1}{}%
\global\expandafter\let\csname CachedInput@#1\endcsname\TempCachedInput
\fi
\let\TempSavedEndinput\endinput
\let\endinput\relax
\csname CachedInput@#1\endcsname
\let\endinput\TempSavedEndinput
}
%%% End hack %%%
\begin{document}
\multido{}{1000}{%
\lstinputlisting{\jobname.code}
}
\end{document}
答案2
\inputencoding{XXX}
Listings(utf8) 使用包中的标准接口inputenc
来更改各种编码相关定义。\inputencoding
从 XXX.def 文件加载定义。虽然可以将定义存储在宏中而不是从中重新加载它们,但.def
我认为inputenc
默认情况下不应该这样做。文档经常切换输入编码的情况相当罕见。listings 包含非 ascii 字符的情况也相当罕见。
对于你的情况,你可以做这样的事情:
\newcommand\latinonedef[1]{%
% definitions from latin1.def
% with/without the \providecommands as needed
% carefully remove all spurious spaces!
}
\usepackage{etoolbox}
\makeatletter
\preto\lsthk@Init{\let\inputencoding\latinonedef}{}{}
\makeatother