0

With the following code I want to match any word this_example and to replace it with examplethis. I'm using the values extracted from the A column of a csv file. My problem is that \demo{\Fst} does not match any \Fst value, while \demo{this_example} seems to work. Is there a way to expand the values within \Fst in order to pass to l3regex not the command but the value? Thanks in advance.

\documentclass[12pt,a4paper]{report}
\usepackage{longtable}
\usepackage{datatool,filecontents,tabularx,booktabs}
\DTLloaddb[keys={A,B}]{termlog}{my.csv}
\DTLsort{A=ascending}{termlog}

\usepackage{expl3}
\usepackage{l3regex}
\ExplSyntaxOn
\tl_new:N \l_demo_tl
\cs_new:Npn \demo #1 {
    \tl_set:Nn \l_demo_tl {#1}
    \regex_replace_all:nnN { ([^\d]+)\_([^\d]+) } {  \cB\{\c{textbf}\cB\{\2\cE\}\cE\}\1 } \l_demo_tl
    \tl_use:N \l_demo_tl
}
\ExplSyntaxOff

\begin{document}      
\begin{longtable}{llllll}
  \toprule
  \textbf{Col1} & \textbf{Col2} \\
  \midrule
  \DTLforeach{termlog}{%
    \Fst=A,\Snd=B}{%
    \demo{\Fst} & \textit{\Snd}  \\
  }
  \\[-\normalbaselineskip] \bottomrule
\end{longtable}
\end{document}

This is an example of CSV file:

this_is,some
text_to,fold
or,not
  • Can you give an example of the .csv file you're using? – egreg Dec 5 '16 at 16:54
  • Sure, I've edited the post. – jackb Dec 5 '16 at 16:57
  • 3
    Replace \tl_set:Nn by \tl_set:Nx? – Bruno Le Floch Dec 5 '16 at 16:58
  • It worked. I'm a l3regex noob. What is the difference? Thanks – jackb Dec 5 '16 at 16:59
  • No relation with l3regex. \tl_set:Nn means "in this variable, store exactly what follows", whereas \tl_set:Nx first expands the second argument before storing it. A variant which egreg uses is V-type expansion which means "unpack the variable", so for instance you could have used \tl_set:NV (I just read the question a bit too fast). – Bruno Le Floch Dec 5 '16 at 20:55
3

You might use \tl_set:Nx instead of \tl_set:Nn so the argument to \demo is fully expanded. However, I'm not very keen on this approach, because full expansion might be dangerous if the first column contains macros.

\begin{filecontents*}{\jobname.csv}
this_is,some
text_to,fold
or,not
\end{filecontents*}

\documentclass[12pt,a4paper]{report}
\usepackage{longtable}
\usepackage{datatool,filecontents,tabularx,booktabs}
\DTLloaddb[keys={A,B},noheader]{termlog}{\jobname.csv}
\DTLsort{A=ascending}{termlog}

\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand\demo{sm}
 {
  \IfBooleanTF{#1}
   { \jackb_demo:V #2 }
   { \jackb_demo:n {#2} }
 }

\tl_new:N \l_jackb_demo_tl
\cs_new:Npn \jackb_demo:n #1
 {
  \tl_set:Nn \l_jackb_demo_tl {#1}
  \regex_replace_all:nnN { ([^\d]+)\_([^\d]+) } {  \cB\{\c{textbf}\cB\{\2\cE\}\cE\}\1 } \l_jackb_demo_tl
  \tl_use:N \l_jackb_demo_tl
 }
\cs_generate_variant:Nn \jackb_demo:n { V }
\ExplSyntaxOff

\begin{document}      
\begin{longtable}{llllll}
  \toprule
  \textbf{Col1} & \textbf{Col2} \\
  \midrule
  \DTLforeach{termlog}{%
    \Fst=A,\Snd=B}{%
    \demo*{\Fst} & \textit{\Snd}  \\
  }
  \\[-\normalbaselineskip] \bottomrule
\end{longtable}
\end{document}

You can use \demo also elsewhere with the non star form. If you only need it in DTLforeach, just replace the \NewDocumentCommand with

\NewDocumentCommand\demo{m}
 {
  \jackb_demo:V #1
 }

and replace \demo* with \demo.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.