expl3 - 如何将一个模块的消息转换为另一个模块的消息?

expl3 - 如何将一个模块的消息转换为另一个模块的消息?

通过 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。:还有一些细节尚待确定,但很快就会更新。

相关内容