通过 l3msg 包,您可以创建有趣的消息。
从一个消息类别重定向到另一个消息类别(例如,将错误消息转换为警告消息)也是可能的。
我如何重定向要显示消息的模块?
例如,当使用 l3keys/ \keyval_parse:nnn
/\keys_set:nn
并提供空白键名时,您会收到以下消息\LaTeX3 error: Blank key name in key-value input on line ...
利用我的一些宏,在这种情况下,我想显示另一条消息文本。
在我的模块中定义的消息文本,它命名了我的模块和我的宏,因为这样可以更容易地识别用户级别的宏调用,从而触发处理链,最终导致错误消息。
起初我以为我可以做这样的事情:
\group_begin:
\msg_set:nnn { LaTeX } { kernel/blank-key-name } { My additional remarks. Blank~key~name~in~key-value~input~\msg_line_context: }
\prop_put:Nnn \g_msg_module_name_prop { LaTeX } { MYMODULE }
\keyval_parse:nnn{\MYMODULE_PrintKey:n}{\MYMODULE_PrintKeyAndValue:nn}{a=b, a=, =b}
\group_end:
但它不起作用:使用, =b
我仍然得到的
\LaTeX3 error: Blank key name in key-value input on line...
而不是
! Package MYMODULE Error: My additional remarks. Blank key name in key-value input on line...
。
这似乎是由于 l3keys 使用\__kernel_msg_expandable_error:nn
而不是\msg_error:nn
来引发消息 - 使用\msg_error:nn
会导致所需的错误消息文本:
\ExplSyntaxOn
\tex_scrollmode:D
\documentclass{article}
\cs_new:Nn \MYMODULE_PrintKey:n {\MYMODULE_PrintKeyAndValue:nn {#1}{None}}
\cs_new:Nn \MYMODULE_PrintKeyAndValue:nn {Key: #1. Value: #2.}
\begin{document}
\tex_message:D{^^J^^J------------------------------^^J
Error-message~as~usual,~raised~by~\token_to_str:N\keyval_parse:nnn:\space :^^J
------------------------------^^J^^J}
\keyval_parse:nnn{\MYMODULE_PrintKey:n}{\MYMODULE_PrintKeyAndValue:nn}{, =b}
\tex_message:D{^^J^^J------------------------------^^J
Error-message~as~usual,~raised~by~\token_to_str:N\msg_error:nn\space :^^J
------------------------------^^J^^J}
\msg_error:nn { LaTeX } { kernel/blank-key-name }
\group_begin:
\msg_set:nnn { LaTeX } { kernel/blank-key-name } { MY~ADDITIONAL~REMARKS.~Blank~key~name~in~key-value~input~\msg_line_context: }
\prop_put:Nnn \g_msg_module_name_prop { LaTeX } { MYMODULE }
\tex_message:D{^^J^^J------------------------------^^J
Although~the~message-text~is~changed,~via~\token_to_str:N\keyval_parse:nnn\space~you~still~get~the~error-message~as~usual...^^J
------------------------------^^J^^J}
\keyval_parse:nnn{\MYMODULE_PrintKey:n}{\MYMODULE_PrintKeyAndValue:nn}{, =b}
\tex_message:D{^^J^^J------------------------------^^J
...while~via~\token_to_str:N\msg_error:nn\space~you~get~the~desired~message-text:^^J
------------------------------^^J^^J}
\msg_error:nn { LaTeX } { kernel/blank-key-name }
\group_end:
\end{document}
控制台输出:
prompt$ pdflatex test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-02-18>
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/article.cls
Document Class: article 2020/04/10 v1.4m Standard LaTeX document class
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2020/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
(./test.aux)
------------------------------
Error-message as usual, raised by \keyval_parse:nnn: :
------------------------------
! Undefined control sequence.
<argument> \LaTeX3 error:
Blank key name in key-value input on line 14
l.14 ...ey:n}{\MYMODULE_PrintKeyAndValue:nn}{, =b}
------------------------------
Error-message as usual, raised by \msg_error:nn :
------------------------------
! LaTeX3 Error: Blank key name in key-value input on line 20
Type <return> to continue.
...
l.20 ...ror:nn { LaTeX } { kernel/blank-key-name }
------------------------------
Although the message-text is changed, via \keyval_parse:nnn you still get the e
rror-message as usual...
------------------------------
! Undefined control sequence.
<argument> \LaTeX3 error:
MY ADDITIONAL REMARKS. Blank key name in key-valu...
l.31 ...ey:n}{\MYMODULE_PrintKeyAndValue:nn}{, =b}
------------------------------
...while via \msg_error:nn you get the desired message-text:
------------------------------
! MYMODULE Error: MY ADDITIONAL REMARKS. Blank key name in key-value input on
(MYMODULE) line 37
Type <return> to continue.
...
l.37 ...ror:nn { LaTeX } { kernel/blank-key-name }
(./test.aux) )
(see the transcript file for additional information)
No pages of output.
Transcript written on test.log.
反过来,这引出了一个问题:为什么像 l3keys 这样的包会绕过常规的消息接口?
请不要将我的问题理解为“工作请求”,而应将其理解为拓宽我对当前事态的理解。尤其是因为我的关注点更多是吹毛求疵/学术性质的——\errorcontextlines=...
如果不追踪导致错误消息的处理链到启动用户级宏/顶级宏,我们还能做什么?:-)
答案1
消息系统不允许您“更改消息/模块的名称”,因为它们是消息本身的唯一标识符。但是,您可以(滥用)利用内部模块名称和打印名称不必一致的事实,即
\ExplSyntaxOn
\prop_new:N \l_msg_module_name_prop
\prop_set_eq:NN \l_msg_module_name_prop \g_msg_module_name_prop
\prop_gput:Nnn \g_msg_module_name_prop { LaTeX } { demo }
\keys_set:nn { foo } { bar }
\prop_gset_eq:NN \g_msg_module_name_prop \l_msg_module_name_prop
\ExplSyntaxOff
关于不可重定向消息的问题,最初的设计决定是将内核从重定向中豁免。这个想法是,虽然对于软件包来说,允许消息重定向或完全抑制可能是合理的,但对于来自内核的材料来说,这种情况不太可能发生,因为内核的材料几乎总是具有编程性质。然而,问题变成了决定这条线在哪里。因此,我们正在重新设计这个领域,以坚持\msg_error:nn(nn)
,ETC。:还有一些细节尚待确定,但很快就会更新。