Usandoxifthen

Usandoxifthen

Gostaria de implementar o seguinte processamento para cada linha dos meus dados, que é lido com 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

Meu código:

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

Por favor, mostre como implementar a regra acima. Obrigado.

Responder1

Existem várias maneiras de fazer isso. Proponho duas soluções, uma usando xifthene outra usando expl3. Também seria possível com ifthenfunções de datatool.

Observe que para testes em \B, usei comparação de strings porque o conteúdo nem sempre é um número, ao contrário de \No. Substituí um 2222por 22222sua expressão lógica (parece um erro na sua pergunta?).

Implementei os testes lógicos conforme você os escreveu, mas eles poderiam ser simplificados (o \No teste = 5 poderia ser fatorado).

Usandoxifthen

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

Usandoexpl3

Talvez você ache o expl3caminho mais legível. Ao contrário de xifthen, expressões booleanas for l3prg(o expl3módulo para essas coisas) usam regras de precedência padrão para &&and ||(E lógico e OR lógico, respectivamente), o que é bom.

Observe que os espaços são ignorados entre \ExplSyntaxOne \ExplSyntaxOff. Se precisar de um espaço lá, use ~ou \space. ~pode ser ignorado normalmente após uma palavra de controle, por exemplo, o ~in \B ~é ignorado, mas \B \spaceirá inserir um token de espaço quando \spacefor expandido (é uma macro expandindo para um token de espaço explícito).

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

Saída de ambos os exemplos

Saída

informação relacionada