我编写了一个宏,将外部文件的内容写入日志输出。不幸的是,我总是读出\par
LaTeX 在读取文件时添加的尾随。我该如何测试并删除它?我对“TeX 方式”很感兴趣,但当然欢迎所有答案。
示例宏处理以下条件:
- 文件为空
- 文件有内容
它不涵盖以下情况:
- 文件不存在
在我的示例中,我在编译时执行以下操作:
- 写入一个名为
functions-\jobname.txt
(收集\myfunction
正文中提到的每一个内容)的文件 - 稍后阅读文件
functions-\jobname.txt
- 用来
typeout
把此文件的内容放在日志输出的末尾(用于协作内容相关的调试)
读取日志宏
我用\typeout
它来写入日志和终端。我可能需要向我的\readtolog
宏添加一些逻辑来测试尾随\par
,所以我从下面的工作示例中提取了它。
\newread\customfile
\def\readtolog#1{%
\openin\customfile=#1\relax
\loop\unless\ifeof\file
\read\customfile to\fileline
\ifx\fileline\eolmarker
\else
\typeout{\fileline}
\fi
\repeat
\closein\customfile
}
示例代码
\listfiles% used to illustrate atveryend which does not have much to do with the question
\documentclass{article}
\usepackage{fontspec}% compiled with xelatex
\usepackage{regexpatch}% use for \xapptocmd
\usepackage{etoolbox}% use for \tracingpatches
\usepackage{atveryend}% Add support for \AtEndAfterFileList
\newenvironment{logmessage}[1]{%
\typeout{^^J**************************************************^^J%
#1%
^^J************************************************** }}
{\typeout{**************************************************}}
\def\myfunction#1{#1}% Macro appended to by \xapptocmd
\newread\customfile
\def\readtolog#1{% LOGIC NEEDED TO REMOVE TRAILING \par
\openin\customfile=#1\relax
\loop\unless\ifeof\customfile
\read\customfile to\fileline
\ifx\fileline\eolmarker
\else
\typeout{\fileline}
\fi
\repeat
\closein\customfile
}
\def\checkfunctions{% Debug mode (enable writes and reads)
\tracingpatches
\newwrite\myfunctionsfile
\AtBeginDocument{\immediate\openout\myfunctionsfile=functions-\jobname.txt}
\AtEndDocument{\immediate\closeout\myfunctionsfile}
\AtEndAfterFileList{\begin{logmessage}{Functions}\readtolog{functions-\jobname.txt}\end{logmessage}}
\xapptocmd{\myfunction}{\immediate\write\myfunctionsfile{\unexpanded{##1}}}{}{}
}
\checkfunctions
\begin{document}
\myfunction{A function worth noting}
\end{document}
日志输出片段
怎么回事\par
?这有关系吗?如何修剪从外部文件读取的每一行的行尾字符?
**************************************************
Functions
**************************************************
A function worth noting
\par
**************************************************
)
答案1
我不确定我理解了这个问题,但是
\def\readtolog#1{% LOGIC NEEDED TO REMOVE TRAILING \par
\openin\customfile=#1\relax
{\endlinechar-1
\loop\unless\ifeof\customfile
\read\customfile to\fileline
\typeout{\fileline}
\repeat}%
\closein\customfile
}
将抑制线两端变成\par
如果要在末尾添加一个空行,只需保存每一行,然后输出以前的行,然后只需在末尾查看所拥有的内容,这将是一个空宏,除非读取的文件的最后一行没有行尾。
\def\readtolog#1{% LOGIC NEEDED TO REMOVE TRAILING \par
\openin\customfile=#1\relax
{\endlinechar-1
\def\temp{}%
\loop\unless\ifeof\customfile
\temp
\read\customfile to\fileline
\def\temp{\typeout{\fileline}}%
\repeat
\ifx\fileline\@empty\else\temp\fi% just in case there was not an eol on the last line
}%
\closein\customfile
}
答案2
一个简单的解决方案是使用catchfile
:
\listfiles
\documentclass{article}
\usepackage{regexpatch}% use for \xapptocmd
\usepackage{atveryend}% Add support for \AtEndAfterFileList
\usepackage{catchfile}
\newenvironment{logmessage}[1]{%
\typeout{^^J**************************************************^^J%
#1%
^^J************************************************** }}
{\typeout{**************************************************}}
\def\myfunction#1{#1}% Macro appended to by \xapptocmd
\long\def\readtolog#1{%
\IfFileExists{#1}{%
\CatchFileDef\tologfile{#1}{\endlinechar=`\^^J}%
\typeout{\unexpanded\expandafter{\tologfile}}%
}{\typeout{No file #1}}%
}
\newwrite\myfunctionsfile
\def\checkfunctions{% Debug mode (enable writes and reads)
\AtBeginDocument{\immediate\openout\myfunctionsfile=functions-\jobname.txt}%
\AtEndDocument{\immediate\closeout\myfunctionsfile}%
\AtEndAfterFileList{%
\begin{logmessage}{Functions}
\readtolog{functions-\jobname.txt}
\end{logmessage}%
}%
\xapptocmd{\myfunction}
{\immediate\write\myfunctionsfile{\unexpanded{##1} -- line \the\inputlineno}}
{}{}%
}
\checkfunctions
\begin{document}
\myfunction{A function worth noting}
\myfunction{A function worth noting again}
\end{document}
这会在结束的星号前产生一个空白行,但我认为这不是一个真正的问题。
*File List*
article.cls 2014/09/29 v1.4h Standard LaTeX document class
size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option)
regexpatch.sty 2015/05/20 v0.2a Extending etoolbox patching commands
expl3.sty 2016/03/28 v6468 L3 programming layer (loader)
expl3-code.tex 2016/03/28 v6468 L3 programming layer
l3pdfmode.def 2016/03/26 v6465 L3 Experimental driver: PDF mode
xparse.sty 2016/03/28 v6468 L3 Experimental document command parser
l3regex.sty 2016/03/26 v6466 L3 Experimental regular expressions
l3tl-build.sty 2016/03/26 v6466 L3 Experimental token list construction
l3tl-analysis.sty 2016/03/24 v6443 L3 Experimental token lists analysis
l3flag.sty 2016/03/26 v6466 L3 Experimental flags
l3str-convert.sty 2016/03/24 v6443 L3 Experimental string encoding conversio
ns
atveryend.sty 2011/06/30 v1.8 Hooks at the very end of document (HO)
catchfile.sty 2011/03/01 v1.6 Catch the contents of a file (HO)
infwarerr.sty 2010/04/08 v1.3 Providing info/warning/error messages (HO)
ltxcmds.sty 2011/11/09 v1.22 LaTeX kernel commands for general use (HO)
etexcmds.sty 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO)
ifluatex.sty 2010/03/01 v1.3 Provides the ifluatex switch (HO)
***********
**************************************************
Functions
**************************************************
(./functions-readtolog.txt)
A function worth noting -- line 38
A function worth noting again -- line 39
**************************************************
使用 可以获得一个非常简单的例程,用于逐行读取文件,而不会出现最后的空行问题expl3
。只需\readtolog
按以下方式重新定义宏:
\ExplSyntaxOn
\ior_new:N \g_macmadness_logfile_stream
\cs_new_protected:Npn \readtolog #1
{
\file_if_exist:nTF { #1 }
{
\macmadness_logfile_typeout:n { #1 }
}
{
\typeout{No~file~#1}
}
}
\cs_new_protected:Nn \macmadness_logfile_typeout:n
{
\ior_open:Nn \g_macmadness_logfile_stream { #1 }
\ior_map_inline:Nn \g_macmadness_logfile_stream
{
\typeout{ \exp_not:n { ##1 } }
}
}
\ExplSyntaxOff
完整示例:
\listfiles
\documentclass{article}
\usepackage{regexpatch}% use for \xapptocmd; already loads expl3
\usepackage{atveryend}% Add support for \AtEndAfterFileList
\ExplSyntaxOn
\ior_new:N \g_macmadness_logfile_stream
\cs_new_protected:Npn \readtolog #1
{
\file_if_exist:nTF { #1 }
{
\macmadness_logfile_typeout:n { #1 }
}
{
\typeout{No~file~#1}
}
}
\cs_new_protected:Nn \macmadness_logfile_typeout:n
{
\ior_open:Nn \g_macmadness_logfile_stream { #1 }
\ior_map_inline:Nn \g_macmadness_logfile_stream
{
\typeout{ \exp_not:n { ##1 } }
}
}
\ExplSyntaxOff
\newenvironment{logmessage}[1]{%
\typeout{^^J**************************************************^^J%
#1%
^^J************************************************** }}
{\typeout{**************************************************}}
\def\myfunction#1{#1}% Macro appended to by \xapptocmd
\newwrite\myfunctionsfile
\def\checkfunctions{% Debug mode (enable writes and reads)
\AtBeginDocument{\immediate\openout\myfunctionsfile=functions-\jobname.txt}%
\AtEndDocument{\immediate\closeout\myfunctionsfile}%
\AtEndAfterFileList{%
\begin{logmessage}{Functions}
\readtolog{functions-\jobname.txt}
\end{logmessage}%
}%
\xapptocmd{\myfunction}
{\immediate\write\myfunctionsfile{\unexpanded{##1} -- line \the\inputlineno}}
{}{}%
}
\checkfunctions
\begin{document}
\myfunction{A function worth noting}
\myfunction{A function worth noting again}
\end{document}
输出:
*File List*
article.cls 2014/09/29 v1.4h Standard LaTeX document class
size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option)
regexpatch.sty 2015/05/20 v0.2a Extending etoolbox patching commands
expl3.sty 2016/03/28 v6468 L3 programming layer (loader)
expl3-code.tex 2016/03/28 v6468 L3 programming layer
l3pdfmode.def 2016/03/26 v6465 L3 Experimental driver: PDF mode
xparse.sty 2016/03/28 v6468 L3 Experimental document command parser
l3regex.sty 2016/03/26 v6466 L3 Experimental regular expressions
l3tl-build.sty 2016/03/26 v6466 L3 Experimental token list construction
l3tl-analysis.sty 2016/03/24 v6443 L3 Experimental token lists analysis
l3flag.sty 2016/03/26 v6466 L3 Experimental flags
l3str-convert.sty 2016/03/24 v6443 L3 Experimental string encoding conversio
ns
atveryend.sty 2011/06/30 v1.8 Hooks at the very end of document (HO)
***********
**************************************************
Functions
**************************************************
A function worth noting -- line 52
A function worth noting again -- line 53
**************************************************