在尝试实现自己的工作替代方案时shdoc
(其中一个问题参见这里) 我遇到了 LuaLaTeX 的一个有趣的行为,我无法解释。
考虑以下代码:
\documentclass{scrreprt}
\usepackage{xparse}
\usepackage{luacode}
\DeclareDocumentCommand{\terminaloutput}{+v}{
\directlua{tex.print("\luatexluaescapestring{#1}")}
}
\begin{document}
\terminaloutput{
total 10244
drwxr-xr-x 47 User Users 16384 Mar 31 18:26 .
dr-xr-xr-x 8 User Users 4096 Jun 27 2015 ..
drwxr-xr-x 9 User Users 4096 Dec 23 12:49 .editor
-rw-r--r-- 1 User Users 2950 Mar 31 09:01 .bash_history
}
\end{document}
我刚刚使用逐字参数 () 定义了一个函数,由于中\terminaloutput
有 ,因此该参数必须是逐字的。我的问题是为什么 LaTeX 能够打印 的全部内容(如预期的那样以连续的方式)而 Lua 却不打印任何内容。_
.bash_history
#1
答案1
我更愿意参考 Paul Isambert 的精彩文章,并在此基础上进行改进。LuaTEX:如何写一个段落,于2011年在TUGBoat第32卷出版。
在本文中,作者讨论除其他外如何利用 LuaTeX 的process_input_buffer
回调以非常强大和灵活的方式处理逐字材料。引用文章中的一段话:
TeX 最神秘的领域之一是 catcode 管理。当想要打印逐字文本时,这一点变得非常重要,即 TeX 应该将代码读取为仅需排版的字符,而没有特殊字符,而当想要排版一段代码并执行它时,事情就会变得非常混乱(通常必须使用外部文件)。使用回调
process_input_buffer
,这些限制就消失了:我们通常传递给 TeX 的行可以存储起来,之后以各种方式使用。
下面显示的 MWE 将 Paul 的 TUGBoat 文章代码改编为 LaTeX 编码实践。(Paul 的代码明显是 PlainTEX 风格。)如果您对这个问题感兴趣,您绝对应该阅读 Paul 的原始文章;关于处理逐字材料的段落位于文章的 pdf 文件版本的第 2 页和第 3 页(原始出版期刊卷的第 69 页和第 70 页)。Paul 对这些问题的解释比我好得多。
Lua 端代码包括定义一个 Lua 表(用于保存逐字材料)和 3 个完成大部分工作的 Lua 函数。
TeX 端代码设置了几个 TeX 宏,用于激活、调用和暂停 Lua 函数的操作。主要的 LaTeX 宏是
\printverbatim
(您应该能够猜出它的作用……)和\useverbatim
;后者执行最近读取的逐字块中的任何内容。逐字块是夹在分别写着
\Verbatim
和的行之间的任何\EndVerbatim
内容。如果行中有任何内容分别包含字符串\Verbatim
和\EndVerbatim
,它将被忽略。
请注意,我有不是定义一个名为的 LaTeX 环境Verbatim
,尽管这样做并不太难。
% !TEX TS-program = lualatex
\documentclass{scrreprt}
%% Set up a Lua table and 3 Lua functions
\directlua{%
verb_table = {}
function store_lines (str)
if string.find (str , "\noexpand\\EndVerbatim" ) then
luatexbase.remove_from_callback (
"process_input_buffer" , "store_lines")
else
table.insert(verb_table, str)
end
return ""
end
function register_verbatim ()
verb_table = {}
luatexbase.add_to_callback(
"process_input_buffer" , store_lines , "store_lines")
end
function print_lines ( catcode )
if catcode then
tex.print ( catcode , verb_table)
else
tex.print ( verb_table )
end
end
}
%% TeX-side code: define several macros
\def\Verbatim{\directlua{register_verbatim()}}
\def\useverbatim{\directlua{print_lines()}}
\def\printverbatim{%
\par
\bgroup
\setlength{\parindent}{0pt}
\ttfamily
\directlua{print_lines(1)}
\egroup
}
\def\createcatcodes{%
\bgroup
\catcode`\\=12 \catcode`\{=12 \catcode`\}=12
\catcode`\$=12 \catcode`\&=12 \catcode`\^^M=13
\catcode`\#=12 \catcode`\^=12 \catcode`\_=12
\catcode`\ =13 \catcode`\~=12 \catcode`\%=12
\savecatcodetable 1 % '\savecatcodetable' is a LuaTeX primitive
\egroup}
\createcatcodes
\def\Space{ }
\bgroup
\catcode`\^^M=13\gdef^^M{\quitvmode\par}%
\catcode`\ = 13\gdef {\quitvmode\Space}%
\egroup
\begin{document}
\Verbatim
total 10244
drwxr-xr-x 47 User Users 16384 Mar 31 18:26 .
dr-xr-xr-x 8 User Users 4096 Jun 27 2015 ..
drwxr-xr-x 9 User Users 4096 Dec 23 12:49 .editor
-rw-r--r-- 1 User Users 2950 Mar 31 09:01 .bash_history
\EndVerbatim
\printverbatim
\bigskip
\Verbatim
\def\lululu{%
Lua\kern-.01em
\TeX
}%
\EndVerbatim
\printverbatim
\bigskip
\useverbatim % this "registers" the macro "\lululu"
\noindent\lululu
\end{document}
答案2
Mico 的回答非常好,并展示了 LuaTeX 中逐字缓冲区的低级实现是什么样子。
ConTeXt 附带此功能,并且使用起来非常简单。
\starttext
\startbuffer[terminal]
total 10244
drwxr-xr-x 47 User Users 16384 Mar 31 18:26 .
dr-xr-xr-x 8 User Users 4096 Jun 27 2015 ..
drwxr-xr-x 9 User Users 4096 Dec 23 12:49 .editor
-rw-r--r-- 1 User Users 2950 Mar 31 09:01 .bash_history
\stopbuffer
\typebuffer[terminal]
\startbuffer[logo]
\def\lululu{%
Lua\kern-.01em
\TeX
}%
\stopbuffer
\typebuffer[logo]
\getbuffer[logo]
\lululu
\stoptext
输出与 Mico 的答案类似。
答案3
另一种方法是模仿 ConTeXt緩衝器是scontents
包。获得的输出与Mico的响应相同,当然不是“防弹”,但是,请允许我verbatim
使用和自定义输出fancyvrb
,tcolorbox
正如我在您的评论中读到的那样。
包的主要功能是存储内容,但尝试\typebuffer
使用来模仿verbatim
,无论如何,这是我的答案:
\documentclass{article}
\usepackage{scontents}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\begin{document}
\section{default}
% stored in terminal
\begin{scontents}[store-env=terminal]
total 10244
drwxr-xr-x 47 User Users 16384 Mar 31 18:26 .
dr-xr-xr-x 8 User Users 4096 Jun 27 2015 ..
drwxr-xr-x 9 User Users 4096 Dec 23 12:49 .editor
-rw-r--r-- 1 User Users 2950 Mar 31 09:01 .bash_history
\end{scontents}
\typestored[1]{terminal}
% stored in logo
\begin{scontents}[store-env=logo]
\def\lululu{
Lua\kern-.01em
\TeX
}
\end{scontents}
\typestored[1]{logo}
\getstored[1]{logo}
\lululu
\end{document}
\typestored
使用fancyvrb
和自定义输出tcolorbox
:
\documentclass{article}
\usepackage{scontents}
\makeatletter
\let\verbatimsc\@undefined
\let\endverbatimsc\@undefined
\makeatother
\usepackage{fancyvrb,tcolorbox}
\newenvironment{verbatimsc} %
{\VerbatimEnvironment
\begin{tcolorbox}[colback=gray!25, boxsep=0pt, arc=0pt, boxrule=0pt]
\begin{Verbatim}[fontsize=\small]} %
{\end{Verbatim} %
\end{tcolorbox}}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\begin{document}
\section{Using tcolorbox and fancyvrb}
% stored in terminal
\begin{scontents}[store-env=terminal]
total 10244
drwxr-xr-x 47 User Users 16384 Mar 31 18:26 .
dr-xr-xr-x 8 User Users 4096 Jun 27 2015 ..
drwxr-xr-x 9 User Users 4096 Dec 23 12:49 .editor
-rw-r--r-- 1 User Users 2950 Mar 31 09:01 .bash_history
\end{scontents}
\typestored[1]{terminal}
% stored in logo
\begin{scontents}[store-env=logo]
\def\lululu{
Lua\kern-.01em
\TeX
}
\end{scontents}
\typestored[1]{logo}
\getstored[1]{logo}
\lululu
\end{document}