扩张让我头疼。我需要一些帮助。问题如下:日志输出片段 AtEndAfterFileList。
这是我基于上下文的日志条目问题的扩展:
如何在调用宏时(以及在任何地方)将 <section counter value>:<section title>:<page>:<file>:<line> 写入日志?
目标
我希望以下特定于上下文的宏在附加到之前进行扩展\trackedmacrolist
,因为我不想\trackedmacrolist
直到最后才调用。
\thenumber:\thetitle:[\thepage]:\currfilepath:\the\inputlineno
代码
\listfiles
\documentclass{article}
\usepackage{atveryend}
\usepackage{currfile}% adds \currfilepath
% Define a couple commands to track
\DeclareRobustCommand{\myproduct}[1]{MacGyver.\textit{#1}}
% The following is normally put into separate file as to modularize the application of patches
% Define a context macro as described
\def\contextinfo{\thenumber:\thetitle:[\thepage]:\currfilepath:\the\inputlineno}
\def\trackedmacro{Tracked Macro List}% initialize macro
\AtEndAfterFileList{\typeout{\trackedmacro}}
\makeatletter
% Apply Patches
\usepackage{regexpatch}
\xapptocmd{\myproduct}{\typeout{MacMessage: \contextinfo}\g@addto@macro{\trackedmacro}{^^J==> #1 (\contextinfo)}}{}{}% <-- I'd rather show MacGyver.monkey shampoo, but unsure how best to implement
% Note: \typeout is always fully expanded due to \write %https://tex.stackexchange.com/a/60976/13552
\makeatother
%\usepackage{xparse}% Loaded by regexpatch
\let\oldsection\section
\makeatletter
\RenewDocumentCommand{\section}{s o m}{%
\begingroup
% Extract the counter representation
\stepcounter{section}%
\xdef\thenumber{\thesection}%
\addtocounter{section}{-1}%
\protected@xdef\thetitle{#3}%
\endgroup
% Regular section
\IfBooleanTF{#1}
{\oldsection*{#3}}
{\IfValueTF{#2}
{\oldsection[#2]{#3}}
{\oldsection{#3}}}
}
\makeatother
\begin{document}
\section{About \myproduct{elephant shampoo}}
\section{About \myproduct{monkey shampoo}}
\section{About \myproduct{giraffe shampoo}}
\section{About \myproduct{tiger shampoo}}
\end{document}
日志输出片段正在运行xelatex example.tex | grep MacMessage
看起来不错!
MacMessage: (1:About \myproduct {elephant shampoo}:[1]:example.tex:44)
MacMessage: (2:About \myproduct {monkey shampoo}:[1]:example.tex:45)
MacMessage: (3:About \myproduct {giraffe shampoo}:[1]:example.tex:46)
MacMessage: (4:About \myproduct {tiger shampoo}:[1]:example.tex:47)
日志输出片段AtEndAfterFileList
这里不太好
Tracked Macro List
==> elephant shampoo (4:About \myproduct {tiger shampoo}:[2]:example.tex:49)
==> monkey shampoo (4:About \myproduct {tiger shampoo}:[2]:example.tex:49)
==> giraffe shampoo (4:About \myproduct {tiger shampoo}:[2]:example.tex:49)
==> tiger shampoo (4:About \myproduct {tiger shampoo}:[2]:example.tex:49)
与上面的输出相比,您可以看到页码不再对应于代码中宏存在的位置,而是对应于宏首次展开的位置:在\AtEndAfterFileList
调用时的最末尾。
问题:
- 所有宏均显示第 4 节,这是挂接到where
\thenumber
时的 最新扩展。\end{document}
\AtEndAfterFileList
- 所有宏都扩展为,这是连接到时 的
\myproduct{tiger shampoo}
最新扩展。\thetitle
\end{document}
\AtEndAfterFileList
- 所有的宏都显示第 2 页,这是连接到where
\thepage
时 的最新扩展。\end{document}
\AtEndAfterFileList
- 所有宏都显示第 49 行,这是所挂钩的
\the\inputlineno
at\end{document}
where的最新扩展。\AtEndAfterFileList
请注意,如果我\input
在最后一次\myproduct
通话之前的某个时间点遇到了问题,我也会预料到会出现问题\currfilepath
。
有关的
答案1
我认为这个问题很难理解,除非人们理解它,否则它就太神秘了:)
我将尝试以建设性的方式回答这个问题。你的问题是
\g@addto@macro{\trackedmacro}{^^J==> #1 (\contextinfo)}
这不会扩展\contextinfo
,所以最后你会把\contextinfo .. \contextinfo .. \contextinfo .. \contextinfo
所有内容都放在里面\trackedmacro
,并且它们会同时扩展(因此会扩展为同一个内容)。所以这是你的特殊问题。你需要确保它在附加到 之前得到扩展\trackedmacro
。
你可以这样做首先,你需要完全扩展它,所以
\protected@edef\tmp{\contextinfo}
将节省已经扩大里面的内容\tmp
。现在你需要\tmp
在把它放进去之前展开一次,\tracketmacro
这样你就能得到整个值。这样就可以了
\expandafter\addtotrackedmacro\expandafter{\tmp}{#1}
具有适当的定义
\newcommand*\addtotrackedmacro[2]{\g@addto@macro{\trackedmacro}{^^J==> #2 (#1)}}
我并不是说这是你问题的最佳解决方案。但是从你得到的代码开始,你有一个简单而小的解决方案来解决这个问题。现在只需在你的代码中更改这一行
\xapptocmd{\myproduct}{\typeout{MacMessage: \contextinfo}\g@addto@macro{\trackedmacro}{^^J==> #1 (\contextinfo)}}{}{}
进入这个
\xapptocmd\myproduct{\typeout{MacMessage: \contextinfo}%
\protected@edef\tmp{\contextinfo}%
\expandafter\addtotrackedmacro\expandafter{\tmp}{#1}}{}{}
\newcommand*\addtotrackedmacro[2]{\g@addto@macro\trackedmacro{^^J==> #2 (#1)}}
就能解决这个问题。
解决该问题的另一种方法是使用\edef
而不是\def
代替\g@addto@macro
,这样您就可以更改
\g@addto@macro{\trackedmacro}{^^J==> #1 (\contextinfo)}
到
\protected@xdef\trackedmacro{\unexpanded\expandafter{\trackedmacro}^^J==> #1 (\contextinfo)}
\trackedmacro
这将获取(扩展一次)的当前值,然后添加您的代码。
答案2
试试这个,但我不知道这是否是正确的结果。
在我看来,\tracklistmacro
应该在then内递归定义\section
。
\listfiles
\documentclass{article}
\usepackage{atveryend}
\usepackage{currfile}% adds \currfilepath
% Define a couple commands to track
\DeclareRobustCommand{\myapp}[1]{\textit{#1}}
\DeclareRobustCommand{\myproduct}[1]{MacGyver.\textit{#1}}
\makeatletter
\newcommand{\@myapp}[1]{#1}
\newcommand{\@myproduct}[1]{MacGyver.#1}
\makeatother
% The following is normally put into separate file as to modularize the application of patches
% Define a context macro as described
\def\trackedmacrolist{Tracked Macro List}% initialize macro
\AtEndAfterFileList{\typeout{\trackedmacrolist}}
\makeatletter
% Apply Patches
\usepackage{regexpatch}
\def\foo@@{}
\xapptocmd{\myproduct}{\g@addto@macro{\trackedmacrolist}{^^J==> #1 (\contextinfo)}}{}{}% <-- I'd rather show MacGyver.monkey shampoo, but unsure how best to implement
% Note: \typeout is always fully expanded due to \write %http://tex.stackexchange.com/a/60976/13552
\makeatother
%\usepackage{xparse}% Loaded by regexpatch
\let\oldsection\section
\makeatletter
\RenewDocumentCommand{\section}{s o m}{%
\begingroup
% Extract the counter representation
\stepcounter{section}%
\xdef\thenumber{\thesection}%
\addtocounter{section}{-1}%
% Temporarily change \myapp and \myproduct to be expandable and ordinary
\let\myapp\@myapp
\let\myproduct\@myproduct
% Extract the title with possible \myapp and \myproduct (now ordinary/expandable)
% Extract the title with possible \myapp and \myproduct (now ordinary/expandable)
\protected@xdef\thetitle{#3}%
\endgroup
% Regular section
%
\xdef\contextinfo{\thenumber:\thetitle:[\the\c@page]:\currfilepath:\the\inputlineno}%
\IfBooleanTF{#1}
{\oldsection*{#3}}
{\IfValueTF{#2}
{\oldsection[#2]{#3}}
{\oldsection{#3}}}
\xdef\trackedmacrolist{\trackedmacrolist}%
}
\makeatother
\begin{document}
\section{About \myproduct{elephant shampoo}}
\meaning\trackedmacrolist
\clearpage
\section{About \myproduct{monkey shampoo}}
\clearpage
\section{About \myproduct{giraffe shampoo}}
\clearpage
\section{About \myproduct{tiger shampoo}}
\end{document}
跟踪的宏列表 ==> 大象洗发水 (1:关于 MacGyver。大象洗发水:[1]:macmadness.tex:56) ==> 猴子洗发水 (2:关于 MacGyver。猴子洗发水:[2]:macmadness.tex:59) ==> 长颈鹿洗发水 (3:关于 MacGyver。长颈鹿洗发水:[3]:macmadness.tex:62) ==> 老虎洗发水 (4:关于 MacGyver。老虎洗发水:[4]:macmadness.tex:65) )