在宏中,强制编译失败的最方便的方法是什么?

在宏中,强制编译失败的最方便的方法是什么?

在包含一些条件的宏中,搜索与模式匹配的现有宏,我有一个不可能的条件组合。如果用户错误地提供了导致他们陷入这种情况的参数,我希望运行立即失败并显示错误消息。实现这一点的最简单方法是什么?我假设有一个简单的答案,但我搜索了一无所获——一切都是关于排除编译失败的故障。

我正在想象这样的事情:

\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
}

相关内容