\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\RequirePackage{ifthen}
\begin{document}
\makeatletter
\newcommand{\coreitem}[3]{%
\ifthenelse{\equal{#1}{}}{}{#1 \\}%
\begin{tabular}{l}
\ifthenelse{\equal{#2}{}}{}{#2 \\}%
#1
\begin{minipage}[t]{\textwidth}%
\ifthenelse{\equal{#3}{}}{}{\\ %
\raggedright{#3}}
\end{minipage}
\end{tabular}
}
\coreitem{one \\ one 2}{two -- two 2}{tres -- tres 2} % successful
\makeatother
\end{document}
这是第一次尝试使用\coreitem
:它\\
在第一个参数中涉及一个\ifthenelse
测试并且可以很好地编译。
第二次尝试如下:
\coreitem{one \\ one 2}{two \\ two 2}{tres -- tres 2} % failing
这里唯一的区别是第二个参数中的替换是--
with 。它涉及内部测试,并且编译失败。错误如下:\\
\ifthenelse
tabular
! Argument of \@firstoftwo has an extra }.
<inserted text>
\par
l.23 ...item{one \\ one 2}{two \\ two 2}{tres -- tres 2} % failing
第三次尝试:
\coreitem{one \\ one 2}{two -- two 2}{tres \\ tres 2} % failing
与第一次成功尝试相比,此处的变化是将第三个参数中的替换为--
,\\
即\ifthenelse
在 内包含minipage
,而 本身又在 内tabular
。它在编译时失败并产生以下错误:
...
! Use of \@newline doesn't match its definition.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
#2}\def \reserved@b {#3}\f...
l.23 ...m{one -- one 2}{two -- two 2}{tres \\ tres 2}
具有相同错误的失败代码的简化版本
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\RequirePackage{ifthen}
\begin{document}
\makeatletter
\newcommand{\coreitem}[3]{%
\ifthenelse{\equal{#1}{}}{}{#1 \\}
\begin{minipage}[t]{\textwidth}
\ifthenelse{\equal{#2}{}}{}{#2 \\}
\end{minipage}
}
\noindent
\coreitem{one \\ one 2}{two \\ two 2} % error
\makeatother
\end{document}
下面是一段代码,展示了其中一个答案的问题
\MyIfEmptyF
\\
如果存在的话,即使第一个参数中的引用为空,也会打印其第二个参数:
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\NeedsTeXFormat{LaTeX2e}
\begin{document}
\makeatletter
\newcommand{\MyIfEmptyF}[1]{
\if\relax\detokenize{#1}\relax%
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi}
\makeatother
\makeatletter
\newcommand{\coreitem}[1][2em]{
\def\coreitem@arg@i{#1}
\@ifnextchar[{\coreitem@i}{\coreitem@i[{2em}]}
}
\def\coreitem@i[#1]{
\def\coreitem@arg@ii{#1}
\@ifnextchar[{\coreitem@ii}{\coreitem@ii[{0.2em}]}
}
\def\coreitem@ii[#1]#2#3{
\def\coreitem@arg@iii{#1}
\def\coreitem@arg@iv{#2}
\def\coreitem@arg@v{#3}
\coreitem@iii
}
\def\coreitem@iii#1{
\def\coreitem@arg@vi{#1}
\begin{tabular}{l}
\MyIfEmptyF{\coreitem@arg@iv}{
\coreitem@arg@iv}
\MyIfEmptyF{\coreitem@arg@vi}{\\}
\MyIfEmptyF{\coreitem@arg@vi}{\\}
\coreitem@arg@v
\end{tabular}
}
\makeatother
\noindent
\coreitem{one -- one 2}{two --- two 2}{}
\end{document}
注意,如果至少有两个连续的满足上述条件 i ,则会出现问题\MyIfEmptyF...
。那么打印的数量\\
为 n - 1,n 为连续的数量\MyIfEmptyF...
。
答案1
我认为问题在于tabular
单元格的性质。这些单元格是一个环境,因此包含不同表格单元格内容的参数\ifthen
失败了。对于参数和来说这是正确的#2
,但对于和因为在第一个参数中起作用来说则#3
不是。#1
\\
请注意,我对上述内容完全没有把握,这只是一个猜测。
但是下面的方法确实有效:
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\makeatletter
\newcommand{\MyIfEmptyF}[1]{%
\if\relax\detokenize{#1}\relax%
\expandafter\@gobble%
\else%
\expandafter\@firstofone%
\fi}
\makeatother
\newcommand{\CoreItem}[3]{%
\MyIfEmptyF{#1}{#1\\}%
\begin{tabular}{l}%
\MyIfEmptyF{#2}{#2\\}%
\MyIfEmptyF{#1}{#1\\}%
\begin{minipage}[t]{\textwidth}%
\raggedright #3%
\end{minipage}%
\end{tabular}}
\begin{document}
\noindent
\CoreItem{one -- one 2}{two -- two 2}{tres -- tres 2} % successful
\CoreItem{one \\ one 2}{two -- two 2}{tres -- tres 2} % successful
\CoreItem{one -- one 2}{two \\ two 2}{tres -- tres 2} % successful
\CoreItem{one -- one 2}{two -- two 2}{tres \\ tres 2} % successful
\end{document}
答案2
etoolbox 包命令似乎比 ifthen 更强大。这里 \ifstrequal 和 \ifdefempty 似乎可以很好地替代 \ifthenelse。以下示例使用 \ifstrequal。但它似乎不适用于 \myfunc@arg@iv、\myfunc@arg@v 等参数,其中 \ifdefempty 进入该字段。第二个示例使用后者。该示例显示了 \ifdefempty 在表格中的用法,但它甚至可以在表格中的小页面中工作。
简单命令的解决方案:
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\RequirePackage{etoolbox}
\begin{document}
\makeatletter
\newcommand{\coreitem}[3]{%
\ifstrequal{#1}{}{}{#1 \\}
\begin{minipage}[t]{\textwidth}
\ifstrequal{#2}{}{}{#2 \\}
\end{minipage}
}
\noindent
\coreitem{one \\ one 2}{two \\ two 2} % error
\makeatother
\end{document}
复杂命令的解决方案:
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}
\begin{document}
\makeatletter
\newcommand{\coreitem}[1][2em]{%
\def\coreitem@arg@i{#1}
\@ifnextchar[{\coreitem@i}{\coreitem@i[{2em}]}
}
\def\coreitem@i[#1]{%
\def\coreitem@arg@ii{#1}
\@ifnextchar[{\coreitem@ii}{\coreitem@ii[{0.2em}]}
}
\def\coreitem@ii[#1]#2#3{%
\def\coreitem@arg@iii{#1}
\def\coreitem@arg@iv{#2}
\def\coreitem@arg@v{#3}
\coreitem@iii
}
\def\coreitem@iii#1{%
\def\coreitem@arg@vi{#1}
\begin{tabular}{l}
\ifdefempty{\coreitem@arg@iv}{}{%
\coreitem@arg@iv \\}
\ifdefempty{\coreitem@arg@vi}{}{\\}
\ifdefempty{\coreitem@arg@vi}{}{\\}
\coreitem@arg@v
\end{tabular}
}
\makeatother
\noindent
\coreitem{one \\ one 2}{two --- two 2}{}
\end{document}