![在宏中,强制编译失败的最方便的方法是什么?](https://linux22.com/image/480460/%E5%9C%A8%E5%AE%8F%E4%B8%AD%EF%BC%8C%E5%BC%BA%E5%88%B6%E7%BC%96%E8%AF%91%E5%A4%B1%E8%B4%A5%E7%9A%84%E6%9C%80%E6%96%B9%E4%BE%BF%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
在包含一些条件的宏中,搜索与模式匹配的现有宏,我有一个不可能的条件组合。如果用户错误地提供了导致他们陷入这种情况的参数,我希望运行立即失败并显示错误消息。实现这一点的最简单方法是什么?我假设有一个简单的答案,但我搜索了一无所获——一切都是关于排除编译失败的故障。
我正在想象这样的事情:
\usepackage{etoolbox}
\newcommand*{\mycommand}[1]{%
\ifcsdef{somecommandcontaining#1}{
\ifcsdef{someothercommandcontaining#1}{
valid condition 1, do something
}{ %%%%% This combination of conditions is invalid %%%%%
\failthisrun{Invalid parameter '#1'}
}%
}{%
valid condition 2, do something else
}
}
答案1
您可以使用以下方式生成乳胶格式的错误
\PackageError{mypackage}{Invalid parameter '#1'}{dont do that}
对于快速调试错误,您可以简单地使用\AnyUndefinedCommand
(我\ERROR
通常使用)它就会停止
答案2
在 LaTeX 中,您可以将宏用作\stop
“紧急按钮”来中止编译,而不会引发错误消息。
我建议使用 expl3 的 l3msg 包来引发(错误)消息,并可能在通过中止编译之前通知中止\stop
。
“可能”是因为我不知道您使用什么标准将编译/运行归类为“失败” - 是否有错误消息就足够了,或者是否必须存在导致编译中止的情况。
如果你的 LaTeX 发行版是最新的(L3 编程层 <2021-05-18> 或更新),你可以执行以下操作:
\ExplSyntaxOn
\prop_gput:Nnn \g_msg_module_type_prop { MYPREAMBLECODE } {}
\prop_gput:Nnn \g_msg_module_name_prop { MYPREAMBLECODE } {Preamble Code}
\msg_new:nnnn {MYPREAMBLECODE}
{Invalid Parameter}
{Invalid~parameter~'#3'~as~#2~argument~of~macro~#1~\msg_line_context: .}
{Don't~pass~'#3'~as~#2~argument~of~macro~#1! }
\msg_new:nnnn {MYPREAMBLECODE}
{Abort compilation}
{Compilation~is~aborted~now.}
{The~situation~really~is~weird!~Please~fix~the~reported~errors!}
\cs_new:Npn \InvalidParameterErrorStop #1 #2 #3 {
% \msg_error:... etc turn their arguments into strings, but let's make sure
% the control sequence token whose name is to be displayed is stringified with a
% leading backslash regardless the current value of the \escapechar parameter:
\exp_args:Nne \use:n {
\msg_error:nnnnn {MYPREAMBLECODE} {Invalid Parameter}
%\msg_expandable_error:nnnnn {MYPREAMBLECODE} {Invalid Parameter}
}{\iow_char:N \\\cs_to_str:N #1}{#2}{#3}
% --- the following lines lead to aborting the LaTeX-run
% after notifying about imminent abortion:
\msg_note:nn {MYPREAMBLECODE} {Abort compilation}
%\msg_expandable_note:nn {MYPREAMBLECODE} {Abort compilation}
\stop
% --------------------------------------------------------
}
\ExplSyntaxOff
\RequirePackage{etoolbox}
\newcommand*{\mycommand}[1]{%
\ifcsdef{somecommandcontaining#1}{%
\ifcsdef{someothercommandcontaining#1}{%
valid condition 1, do something
}{ %%%%% This combination of conditions is invalid %%%%%
\InvalidParameterErrorStop{\mycommand}{first}{#1}%
}%
}{%
valid condition 2, do something else
}%
}%
\newcommand\somecommandcontainingFooBar{This is defined.}
\documentclass{article}
\begin{document}
\mycommand{FooBar}
\end{document}
终端和.log文件中的输出:
! Preamble Code Error: Invalid parameter 'FooBar' as first argument of macro
(Preamble Code) \mycommand on line 49.
For immediate help type H <return>.
...
l.49 \mycommand{FooBar}
? H
Don't pass 'FooBar' as first argument of macro \mycommand!
?
Preamble Code Info: Compilation is aborted now.
答案3
有 TeX 原始命令\errmessage
。例如:
\def\mycommand#1{%
\ifcsname somecommandcontaining#1\endcsname
\ifcsname someothercommandcontaining#1\endcsname
valid condition 1, do something
\else
\errmessage{Invalid parameter "#1"}%
\fi
\else
valid condition 2, do something else
\fi
}