2

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
1

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

enter image description here

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

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.