使用xifthen

使用xifthen

我想对读取的每一行数据执行以下处理datatool

if ( (\No = 5 and \B=11111) OR (\No = 5 and \B=22222) ):
  \inserpageA
else if ( (\No = 5) AND (\B not 11111) AND (\B not 22222) ): 
  \inserpageB
else: 
  \No \hspace{1cm} \B  \hspace{5cm} \A

我的代码:

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}
\newcommand{\inserpageA}[2]{%
\subsubsection*{AAA}
\newpage
}
\newcommand{\inserpageB}[2]{%
\subsubsection*{BBB}
\newpage
}
\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
 \No \hspace{1cm} \B  \hspace{3cm}  \A

}%

\end{document}

请说明如何实施上述规则。谢谢。

答案1

有几种方法可以做到这一点。我提出两种解决方案,一种使用xifthen,另一种使用。使用和 中的函数expl3也可以实现。ifthendatatool

请注意,对于 的测试\B,我使用了字符串比较,因为与 相反,内容并不总是数字\No。我在你的逻辑表达式2222中用替换了一个22222(看起来像是你的问题中的一个错误?)。

我按照您编写的方式实现了逻辑测试,但它们可以简化(\No 可以将 = 5 测试分解出来)。

使用xifthen

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{xifthen}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}

\newcommand{\inserpageA}{%
  \subsubsection*{AAA}
  \newpage
}
\newcommand{\inserpageB}{%
  \subsubsection*{BBB}
  \newpage
}

\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
  \ifthenelse{\(\cnttest{\No}{=}{5}\AND \equal{\B}{11111}\)\OR
              \(\cnttest{\No}{=}{5}\AND \equal{\B}{22222}\)}%
    {\inserpageA}%
    {\ifthenelse{\cnttest{\No}{=}{5}\AND
                 \NOT\equal{\B}{11111}\AND
                 \NOT\equal{\B}{22222}}%
       {\inserpageB}%
       {\No\hspace{1cm}\B \hspace{5cm}\A\par}%
    }%
}%

\end{document}

使用expl3

也许你会发现这种expl3方式更易读。与相反xifthen,布尔表达式l3prgexpl3这些事物的模块)使用标准优先规则&&||分别为逻辑与和逻辑或),这很好。

\ExplSyntaxOn请注意,和之间的空格会被忽略\ExplSyntaxOff。如果您在那里需要空格,请使用~\space~在控制字后,可能会像往常一样被忽略,例如,~in\B ~会被忽略,但在扩展\B \space时会插入一个空格标记\space(它是一个扩展到显式空格标记的宏)。

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}

\ExplSyntaxOn

\NewDocumentCommand \lfortiProcessOneRow { }
  {
    \bool_if:nTF
      { % The parentheses below are not necessary, because && has higher
        % priority than || in expl3 (l3prg) boolean expressions.
        ( \int_compare_p:nNn { \No } = { 5 } && \str_if_eq_p:Vn \B {11111} ) ||
        ( \int_compare_p:nNn { \No } = { 5 } && \str_if_eq_p:Vn \B {22222} )
      }
      { \inserpageA }
      {
        \bool_if:nTF
          { \int_compare_p:nNn { \No } = { 5 } &&
            ! \str_if_eq_p:Vn \B {11111}       &&
            ! \str_if_eq_p:Vn \B {22222}
          }
          { \inserpageB }
          { \No \hspace{1cm} \B \hspace{5cm} \A \par }
      }
  }

\ExplSyntaxOff

\newcommand{\inserpageA}{%
  \subsubsection*{AAA}
  \newpage
}
\newcommand{\inserpageB}{%
  \subsubsection*{BBB}
  \newpage
}

\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}{\lfortiProcessOneRow}

\end{document}

两个示例的输出

输出

相关内容