我想在可扩展函数内进行一些错误检查。但我发出错误信号的尝试没有得到正确处理,而是返回到输入流——这与我的预期相反。
代码如下:
\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.25cm}
\usepackage{xparse}
\ExplSyntaxOn
\msg_new:nnnn {testing}{testing}{illegal~property}{}
%% property list
\prop_new:N \g__ace_all_properties_plist
%% setter
\cs_new_protected:Npn \__ace_set_property:nn #1#2
{
\prop_gput:Nnn \g__ace_all_properties_plist { #1 } { #2 }
}
%% getter
\cs_new:Npn \__ace_get_property:n #1
{
\prop_get:Nn \g__ace_all_properties_plist { #1 }
}
%%--- User interface for settr and gettr
\DeclareDocumentCommand{\settr}{ m m }
{
\__ace_set_property:nn { #1 }{ #2 }
}
\DeclareExpandableDocumentCommand{\gettr}{ m }
{
\prop_if_in:NnTF \g__ace_all_properties_plist { #1 }
{
\__ace_get_property:n { #1 }
}
{
%% this next line does not get executed
%% even when there #1 is not in the list
%<var 1>%\msg_info_text:n { #1 ~ is ~ not ~ defined }
\msg_fatal_text:n { testing}
}
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\settr{displacement}{10}%
This picture gets processed correctly\par
\begin{pspicture}(0,0)(10,10)
\pstGeonode[PointName=default,PointSymbol=default,PosAngle=0](0,0){A}(0,1){B}
\pstTranslation[DistCoef=\gettr{displacement}]{A}{B}{A}[C]
\end{pspicture}
\vspace{1cm}
No error signaled here $\rightarrow$
\gettr{unknownproperty}
\vspace{1cm}
This picture should signal an error when commented line uncommented\par
\begin{pspicture}(0,0)(10,10)
\pstGeonode[PointName=default,PointSymbol=default,PosAngle=0](0,0){A}(0,1){B}
%\pstTranslation[DistCoef=\gettr{unknown-property}]{A}{B}{A}[C]
\end{pspicture}
\end{document}
\msg_term:x
最初,我认为这是从可扩展函数中调用保护函数的问题。但是,即使使用 using ,我的错误也无法正确触发\mgs_fatal_text:n
。后一种方法并不是我真正想要的。但以任何方式发出错误信号都会很好。
编辑
根据@DavidCarlisle 的建议,我尝试更换
\msg_fatal_text:n{ testing }
和
\ERROR
因此,编译停止了,但由于发出了错误类型的错误消息,我可以想象我会浪费很多时间来寻找错误的错误。因此,\ERROR
我没有尝试
\use:c { Attempting ~ to ~ call ~ undefined ~ property -> {#1} }
我认为至少这样,我会得到一个错误,更清楚地表明真正的问题是什么。但这根本不是一个错误——与我的预期相反。
答案1
如果您实际上想要在仅扩展上下文(例如\write
或 PS)中生成错误\special
,通常的方法就是使用未定义的命令,例如\ERROR
您无法从那里触发任何其他错误(并且 LaTeX3 无法真正改变这一点)。
! Undefined control sequence.
l.1 ...ptingToCallUndefinedPropertyunknownproperty
\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.25cm}
\usepackage{xparse}
\ExplSyntaxOn
\msg_new:nnnn {testing}{testing}{illegal~property}{}
%% property list
\prop_new:N \g__ace_all_properties_plist
%% setter
\cs_new_protected:Npn \__ace_set_property:nn #1#2
{
\prop_gput:Nnn \g__ace_all_properties_plist { #1 } { #2 }
}
%% getter
\cs_new:Npn \__ace_get_property:n #1
{
\prop_get:Nn \g__ace_all_properties_plist { #1 }
}
%%--- User interface for settr and gettr
\DeclareDocumentCommand{\settr}{ m m }
{
\__ace_set_property:nn { #1 }{ #2 }
}
\DeclareExpandableDocumentCommand{\gettr}{ m }
{
\prop_if_in:NnTF \g__ace_all_properties_plist { #1 }
{
\__ace_get_property:n { #1 }
}
{
%% this next line does not get executed
%% even when there #1 is not in the list
%<var 1>%\msg_info_text:n { #1 ~ is ~ not ~ defined }
\foo{ Attempting To Call Undefined Property #1 }
}
}
\ExplSyntaxOff
{\catcode`\@=0
@catcode`\\=12
@gdef@foo#1{@scantokens{\#1}}}
\pagestyle{empty}
\begin{document}
\settr{displacement}{10}%
This picture gets processed correctly\par
\begin{pspicture}(0,0)(10,10)
\pstGeonode[PointName=default,PointSymbol=default,PosAngle=0](0,0){A}(0,1){B}
\pstTranslation[DistCoef=\gettr{displacement}]{A}{B}{A}[C]
\end{pspicture}
\vspace{1cm}
No error signaled here $\rightarrow$
\gettr{unknownproperty}
\vspace{1cm}
This picture should signal an error when commented line uncommented\par
\begin{pspicture}(0,0)(10,10)
\pstGeonode[PointName=default,PointSymbol=default,PosAngle=0](0,0){A}(0,1){B}
%\pstTranslation[DistCoef=\gettr{unknown-property}]{A}{B}{A}[C]
\end{pspicture}
\end{document}
(上午)大卫的把戏很有趣:
{
\catcode`\|=0
|catcode`\\=12
|gdef|throwundefined#1{|scantokens{\#1}}
}
\throwundefined{x}
答案2
翻译@DavidCarlisle 的巧妙手法:
\cs_new:Npn \foo #1
{
\tl_rescan:nn
{
\char_set_catcode_escape:N \@
}{
@#1
}
}