# Latex reformat text structure

Say I have a file of abbreivations.txt

&Estimated &Time of &Arrival
&North, &East, &West, &South
&Special &Weapons &And &Tactics
&W&ireless &F&idelity


and the latex \abbrtable{abbreivations.txt}

I want this command to generate the following a table containing two coloums equivalent to the regex

• Coloum 1: [^&]*&(\w)[^&]* -> \1
• Coloum 2: &(\w) -> \\textbf{\1}

I.e. for the sample file this would be:

\begin{longtable}{ll}
\textbf{ETA} & \textbf{E}stimated \textbf{T}ime of \textbf{A}rrival\\
\textbf{NEWS} & \textbf{N}orth, \textbf{E}ast, \textbf{W}est, \textbf{S}outh\\
\textbf{SWAT} & \textbf{S}pecial \textbf{W}eapons \textbf{A}nd \textbf{T}actics\\
\textbf{WiFi} & \textbf{W}\textbf{i}reless \textbf{F}\textbf{i}delity
\end{longtable}


I would like a method that would support extension i.e.

&1$, &3$, &2\$, etc. to specify order of the arguments

&{...} to specify sequence of several characters, or not alpha symbols i.e. &{Wi}reless &{Fi}delity

&? to specify sequence is character is in abbreviation only i.e. &{Wi}reless &?{-}&{Fi}delity -> \textbf{Wi-Fi} & \textbf{Wi}reless \textbf{Fi}delity

&+ to specify lowercase characters be converted to uppercase i.e. &+{Wi}reless &?{-}&+{Fi}delity -> \textbf{WI-FI} & \textbf{Wi}reless \textbf{Fi}delity

I believe PgfplotsTable may provide part of the answer using syntax along the lines of

\pgfplotstableset{
columns/1/.style={string replace={[^&]*&(\w)[^&]*}{\\textbf{\1}}},
columns/1/.style={string replace={&(\w)}{\\textbf{\1}}},
}


I believe I would be however more looking to use the preproc/expr={...} command but no idea what the prepossessing code I would need is.

However I really want a way to parse it an handle the extensions I listed, however this should just evolve two command \abbrprasec1{...} and \abbrprasec2{...} which would take the entire string for the cell and parse it into the correct format.

The other way I've considered is using an external python script that would generate latex from the file, I can find enough online about invoking scripts to handle this method, but it would be less portable than a solution using only latex packages.

So is their a reasonable way to chive this with just latex, or should I just go with the less portable python script option?

P.S. This is only one example of several structure I want to create so I want answers that explain how to build the parser/conversion macro rather that an exact solution to this specific problem.

EDIT:

I believe the following code may work, based on the current answer by "egreg"

\newcommand{\abbr_c1}[2]{
\IfEqCase{#1}{
{+}{\expandafter\MakeUppercase\expandafter\textbf\expandafter{#2}}
{-}{\expandafter\MakeLower\expandafter\textbf\expandafter{#2}}
{?}{\expandafter\textbf\expandafter{#2}}
{}{\expandafter\textbf\expandafter{#2}}
}[\PackageError{abbr}{Undefined Control Sequence}{}]
}

\newcommand{\abbr_c2}[2]{
\IfEqCase{#1}{
{+}{\expandafter\textbf\expandafter{#2}}
{-}{\expandafter\textbf\expandafter{#2}}
{?}{}
{}{\expandafter\textbf\expandafter{#2}}
}[\PackageError{abbr}{Undefined Control Sequence}{}]
}

\pgfplotstableset{
columns/1/.style={
preproc cell content/.code={
\tl_set:Nn \l_abbr_cell {#1}
\regex_replace_all:nnN{ ([^\&]*)\&([-+?]?)\{?((?<=\{)[^\}]*(?=\})|(?<!\{)\w)\}?([^\&]*) }{ \c{abbr_c1}\cB\{\2\cE\}\cB\{\3\cE\} }\l_abbr_cell
\tl_use:N \l_abbr_cell
}
},
columns/1/.style={
preproc cell content/.code={
\tl_set:Nn \l_abbr_cell {#1}
\regex_replace_all:nnN{ ([^\&]*)\&([-+?]?)\{?((?<=\{)[^\}]*(?=\})|(?<!\{)\w)\}?([^\&]*) }{ \1\c{abbr_c2}\cB\{\2\cE\}\cB\{\3\cE\}\4 }\l_abbr_cell
\tl_use:N \l_abbr_cell
}
},
}

• I would probably also use python, but Im interested in the solution in pure LaTeX ! – Gwendal Grelier Jun 26 '18 at 6:19

The powerful l3regex module of expl3 at the rescue!

First we read the file line by line; each line is massaged first isolating the groups &<char> and discarding the rest, then similarly but enclosing <char> in \textbf. Then the results are added to the table body that's eventually delivered in the longtable.

\begin{filecontents*}{\jobname.abv}
&Estimated &Time of &Arrival
&North, &East, &West, &South
&Special &Weapons &And &Tactics
&W&ireless &F&idelity
\end{filecontents*}

\documentclass{article}
\usepackage{longtable}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\abbrtable}{m}
{
\glenflet_abbrtable:n { #1 }
}

\ior_new:N \g_glenflet_abbrtable_stream
\tl_new:N \l_glenflet_abbrtable_body_tl
\tl_new:N \l_glenflet_abbrtable_entry_a_tl
\tl_new:N \l_glenflet_abbrtable_entry_b_tl

\cs_new_protected:Nn \glenflet_abbrtable:n
{
\tl_clear:N \l_glenflet_abbrtable_body_tl
\ior_open:Nn \g_glenflet_abbrtable_stream { #1 }
\ior_map_inline:Nn \g_glenflet_abbrtable_stream
{
\glenflet_abbrtable_entry:n { ##1 }
}
\begin{longtable}{ll}
Abbreviation & Meaning \\
\hline
\tl_use:N \l_glenflet_abbrtable_body_tl
\end{longtable}
}

\cs_new_protected:Nn \glenflet_abbrtable_entry:n
{
\tl_set:Nn \l_glenflet_abbrtable_entry_a_tl { #1 }
\tl_set_eq:NN \l_glenflet_abbrtable_entry_b_tl \l_glenflet_abbrtable_entry_a_tl
\regex_replace_all:nnN
{ \& (.) [^\&]* }
{ \1 }
\l_glenflet_abbrtable_entry_a_tl
\regex_replace_all:nnN
{ \& (.) ([^\&]*) }
{ \c{textbf}\cB\{\1\cE\}\2 }
\l_glenflet_abbrtable_entry_b_tl
\tl_put_right:Nx \l_glenflet_abbrtable_body_tl
{
\exp_not:N \textbf { \exp_not:V \l_glenflet_abbrtable_entry_a_tl }
&
\exp_not:V \l_glenflet_abbrtable_entry_b_tl
\exp_not:N \\
}
}
\ExplSyntaxOff

\begin{document}

\abbrtable{\jobname.abv}

\end{document}


For the requested extensions some more work is needed, but this is the idea.

• Can you add some comments to your code, I believe I worked out how \regex_replace_all:nnN worked (see edit to my question), however, I'm not real sure how your code is working. – Glen Fletcher Jun 27 '18 at 5:20