使用 \ifthenelse 对 \def 定义进行嵌套测试会导致“!缺少 \endcsname 插入”

使用 \ifthenelse 对 \def 定义进行嵌套测试会导致“!缺少 \endcsname 插入”

我正在尝试从定义中得出定义(我不知道是否应该这样称呼),这里有一个例子(已更新以明确我的实际目的):

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{ifthen}
\usepackage{lipsum}

\def\street{num. 1, my street}
\def\block{my block}
\def\town{my town, my zipcode}
\def\state{my state}

\def\doordetails{%
  \ifthenelse{\equal{\street}{}}{}{\street}%
  \ifthenelse{\equal{\street}{} \or \equal{\street}{}}{}{, }%
  \ifthenelse{\equal{\block}{}}{}{\block}}

\def\regiondetails{%
  \ifthenelse{\equal{\town}{}}{}{\town}%
  \ifthenelse{\equal{\town}{} \or \equal{\state}{}}{}{, }%
  \ifthenelse{\equal{\state}{}}{}{\state}}


\begin{document}
\ifthenelse{\equal{\doordetails}{}}{}{\doordetails}
\ifthenelse{\equal{\doordetails}{} \or \equal{\regiondetails}{}}{}{~~~\textbullet~~~}%
\ifthenelse{\equal{\regiondetails}{}}{}{\regiondetails}}
\end{document}

但是尝试构建时出现此错误

! Missing \endcsname inserted.
<to be read again> 
\let 
l.15 \ifthenelse{\equal{\doordetails}{}}{xxx}{xxx}
                                    \\%

答案1

您正在使用原始\def,因此您可以直接使用其他相关的原语,而不依赖于 LaTeX 包:

\def\street{num. 1, my street}
\def\block{my block}
\def\town{my town, my zipcode}
\def\state{my state}

\def\doordetails{%
  \street
  \ifx\relax\street\block\relax \else , \fi
  \block 
}
\def\regiondetails{%
  \town
  \ifx\relax\town\state\relax   \else , \fi
  \state
}

\doordetails
\ifx\relax\doordetails\regiondetails\relax\else ~~~$\bullet$~~~\fi
\regiondetails

答案2

我可能没有正确解释 OP 关于文本项目符号的逻辑(何时出现,何时不出现),但重点是您可以使用简单\if\ifx解决嵌套条件。

当宏为空白或已填充时,使用\ifx\empty\<macro-name>,如果宏扩展为某物或无,则使用\if\relax\<macro-name>\relax

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{ifthen}
\usepackage{lipsum}

\def\street{num. 1, my street}
\def\block{my block}
\def\town{my town, my zipcode}
\def\state{my state}

\def\doordetails{%
  \ifx\street\empty
    \block
  \else
    \street
    \ifx\block\empty
    \else
      , \block
    \fi
  \fi
}

\def\regiondetails{%
  \ifx\town\empty
    \state
  \else
    \town
    \ifx\state\empty
    \else
      , \state
    \fi
  \fi
}

\def\alldetails{
\if\relax\doordetails\relax
  \regiondetails
\else
  \doordetails
  \if\relax\regiondetails\relax
  \else
    ~~~\textbullet~~~\regiondetails
  \fi
\fi}
\begin{document}
\alldetails

\def\street{}\alldetails

\def\town{}\alldetails

\def\block{}\alldetails

\end{document}

在此处输入图片描述

答案3

不能嵌套\ifthenelse调用。

这是一个替代品,但请注意一些区别:\or应该是||和括号应该直接使用,而不是像\(\)那样\ifthenelse。代码来自https://tex.stackexchange.com/a/546445/4427进行了一些更改。这些条件是完全可扩展的,因此可以嵌套。

\documentclass[a4paper,12pt]{article}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifthenelse}{mmm}
 {
  \bool_if:nTF { #1 } { #2 } { #3 }
 }
\cs_new_eq:NN \numtest     \int_compare_p:n
\cs_new_eq:NN \oddtest     \int_if_odd_p:n
\cs_new_eq:NN \fptest      \fp_compare_p:n
\cs_new_eq:NN \dimtest     \dim_compare_p:n
\cs_new_eq:NN \deftest     \cs_if_exist_p:N
\cs_new_eq:NN \namedeftest \cs_if_exist_p:c
\cs_new_eq:NN \eqdeftest   \token_if_eq_meaning_p:NN
\cs_new_eq:NN \streqtest   \str_if_eq_p:ee
\cs_new_eq:NN \emptytest   \tl_if_blank_p:n
\cs_new_eq:NN \booleantest \legacy_if_p:n
\ExplSyntaxOff

\newcommand\doordetails{%
  \xifthenelse{\emptytest{\street}}{}{\street}%
  \xifthenelse{\emptytest{\street} || \emptytest{\block}}{}{, }%
  \xifthenelse{\emptytest{\block}}{}{\block}%
}

\newcommand\regiondetails{%
  \xifthenelse{\emptytest{\town}}{}{\town}%
  \xifthenelse{\emptytest{\town} || \emptytest{\state}}{}{, }%
  \xifthenelse{\emptytest{\state}}{}{\state}%
}


\begin{document}

\newcommand\street{num. 1, my street}
\newcommand\block{my block}
\newcommand\town{my town, my zipcode}
\newcommand\state{my state}

\xifthenelse{\emptytest{\doordetails}}{}{\doordetails}
\xifthenelse{\emptytest{\doordetails} || \emptytest{\regiondetails}}{}{~~~\textbullet~~~}%
\xifthenelse{\emptytest{\regiondetails}}{}{\regiondetails}

\end{document}

在此处输入图片描述

相关内容