使用fancyvrb
环境时Verbatim
,您可以吞噬每行的第一个n
字符,然后再将其打印出来。我希望能够做类似的事情,但不是通过逐字逐句的方式。
在以下 MWE 中,我想读取文件中的内容:
\textbf{This is the first line.}
%% \textbf{This is the second line.}
并让 LaTeX 处理它,就像它已经传递了一个文件一样:
\textbf{This is the first line.}
\textbf{This is the second line.}
这是我尝试过的一个例子,但它并没有像预期的那样工作:
\begin{filecontents*}{aetesting}
\textbf{This is the first line.}
%% \textbf{This is the second line.}
\end{filecontents*}
\documentclass{article}
\usepackage{catchfile}
\def\gobblefirst#1#2#3#4{}
\def\mysetup{\let\do\gobblefirst\dospecials}
\CatchFileDef{\aemyfile}{aetesting}\mysetup
\begin{document}
\aemyfile
\end{document}
更新
我几乎可以让它工作(没有catchfile
)
\begin{filecontents*}{aetesting}
The character of the First Caesar has perhaps never been worse
appreciated than by him who in one sense described it best; that is,
\textbf{This is the first line.}\par
%% \textbf{This is the second line.}
%% Great as Caesar was by the benefit of his original nature, there can be
no doubt that he, like others, owed something to circumstances; and
\end{filecontents*}
\documentclass{article}
\makeatletter
\newread\file
\newcommand\aeomit[2]{}
\newcommand\myaccumulatedfile{}
\newcommand*\aegobbleinput[1]{%
\IfFileExists{#1}{%
\openin\file #1
\begingroup
\endlinechar\newlinechar
\loop\unless\ifeof\file
\obeyspaces
\readline\file to\foo
\edef\myaccumulatedfile{\myaccumulatedfile\expandafter\@gobbletwo\foo\relax\relax}%%
\repeat
\closein\file
\expandafter\endgroup
\scantokens\expandafter{\myaccumulatedfile}
}{%
\errmessage{File `#1' doesn't exist!}%
}%
}
\makeatother
\begin{document}
Try:
\aegobbleinput{aetesting}
\end{document}
问题是前导空格被忽略了,而我不希望它们被忽略。此外,我之前的换行符\textbf{This is the first line.}
不再被正确视为段落分隔符。:(
进一步更新
当我想到我可以在 LaTeX3 中尝试这个时,我遇到了更多的麻烦。
\usepackage{xparse}
\ExplSyntaxOn
\ior_new:N \g_ae_fh_ior
\tl_new:N \l_ae_fh_line_tl
\cs_new:Npn \__ae_gobble:n #1
{
\file_if_exist:nTF { \__ae_open:n { #1 } }
{ \typeout{no file!} }
}
\cs_new:Npn \__ae_open:n #1
{
\ior_open:Nn \g_ae_fh_ior { #1 }
\ior_str_map_inline:Nn \g_ae_fh_ior { \tl_gput_right:Nn \l_ae_fh_line_tl {##1 \par}}
\ior_close:N \g_ae_fh_ior
}
\NewDocumentCommand{\aegobbleinput}{m}
{
\__ae_gobble:n {#1}
}
\ExplSyntaxOff
在这里我甚至没有尝试截断任何东西。但我无法让 LaTeX 读取文件。这段代码出现两个错误之一。当我尝试使用地图时inline
,我收到错误
! Illegal parameter number in definition of \l__file_internal_name_tl.
<to be read again>
1
l.6 \aegobbleinput{aetesting.tex}
?
如果我删除了这一行,尽管删除它不会导致任何内容被解析,但我还是收到了错误消息
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! LaTeX error: "kernel/space-in-file-name"
!
! Space in file name '\ior_open:Nn \g_ae_fh_ior {aetesting.tex}\ior_close:N
! \g_ae_fh_ior '.
!
! See the LaTeX3 documentation for further information.
!
! For immediate help type H <return>.
!...............................................
l.6 \aegobbleinput{aetesting.tex}
?
这对我来说完全没有意义,特别是因为我非常严格地遵循发布的示例这里。
答案1
这是一个幼稚的尝试,肯定不是万无一失的。忘了说它不使用该catchfile
包。文件不是逐字输入的,但每个非空行必须至少有四个初始字符,这些字符将被逐字处理并被忽略。
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{aetesting}
\textbf{This is the first line.}
%% \textbf{This is the second line.}
^_^_End of lines in the input file get converted into spaces,
except if followed by an empty line.
$~\\This follows an empty line in the input.
&&& This follows sucessive empty lines in the input.
\end{filecontents*}
\makeatletter
\long\def\@gobblethree#1#2#3{}
\long\def\aeafterfi #1#2\fi{\fi #1}
\begingroup
\catcode1=\active
\gdef^^A{\begingroup\let\do\@makeother\dospecials\aeaux }
\gdef\aeaux #1{\ifx #1^^A\aeafterfi{\endgroup\par^^A}%
\else \aeafterfi{ \expandafter\endgroup\@gobblethree}\fi}
\endgroup
\makeatother
\newcommand*\aeinput [1]{%
\begingroup
\endlinechar1
\catcode1=\active
\everyeof{\relax\relax\relax\relax}%
\InputIfFileExists
{#1}{}%
{File `#1' doesn't exist!}% (or using \errmessage)
\endgroup
}
% character with ascii code 1 made invalid
% apart from its use in \aeinput
\catcode1=15
\begin{document}
\aeinput{aetesting}
\aeinput{aetesting2} % attempt to input a non-existent file
\aeinput{aetesting} % inputting one more time
\end{document}
答案2
我不太确定你打算如何使用它,所以你可能需要告诉我要更改什么。我所做的就是按原样打印出文件的第一行。对于所有后续行,我吞噬了两个标记,然后输出它们。
这是一种不使用的方法catchfile
。
如果输入文件myfile.tex
是
\textbf{This is the first line.}
%% \textbf{This is the second line.}
123456789
然后这个代码
\documentclass{article}
\usepackage{readarray}
\makeatletter
%GOBBLE COMMANDS, UP TO 8 BYTES
\newcommand\gobblei{\@gobble}
\newcommand\gobbleii{\@gobbletwo}
\newcommand\gobbleiii{\expandafter\@gobble\@gobbletwo}
\newcommand\gobbleiv{\expandafter\@gobbletwo\@gobbletwo}
\newcommand\gobblev{\expandafter\gobbleiii\@gobbletwo}
\newcommand\gobblevi{\expandafter\gobbleiv\@gobbletwo}
\newcommand\gobblevii{\expandafter\gobblev\@gobbletwo}
\newcommand\gobbleviii{\expandafter\gobblevi\@gobbletwo}
\newcounter{index}
\newcounter{gobbleindex}
\catcode`\%=12
\catcode`\|=14
\newcommand\gobblechars[2]{|
\catcode`\%=12
\catcode`\|=14
\setcounter{gobbleindex}{#2}
\readdef{#1}{\tmp}|
\setcounter{index}{1}|
\showrecord{1}\\|
\whiledo{\value{index} < \nrows}{|
\stepcounter{index}|
\protected@edef\myrecord{\csname record\roman{index}\endcsname}|
\def\mygobble{\csname gobble\roman{gobbleindex}\endcsname}|
\expandafter\mygobble\myrecord|
\\}|
\catcode`\|=12
\catcode`\%=14
}
\catcode`\|=12
\catcode`\%=14
\makeatother
\parindent 0in
\begin{document}
\gobblei 123456789\\
\gobbleii 123456789\\
\gobbleiii 123456789\\
\gobbleiv 123456789\\
\gobblev 123456789\\
\gobblevi 123456789\\
\gobblevii 123456789\\
\gobbleviii 123456789
\gobblechars{myfile.tex}{2}
\end{document}
产生以下输出:
此时,吞噬范围限制为 8 个标记,但可以手动扩展(如果需要,不太确定如何自动扩展)。顺便说一句,我|
为处理外部文件制作了注释字符。显然,这是可以更改的。