pgf add tag
JeT
**Context**

I start building the `acronym/glossary/nomenclature` part of my project with the `acro` package (dunno if I was right vs `glossary` or `nomencl`).

I record all my entries (and their pgfkey values) in an Excel/csv file (easy to spot double entries and have a global view). 

I could format in `vba` the output code so that I get directly the format

```
\DeclareAcronym{trs}{ 
    short = {TRS}, 
    long  = {Total Return Swap},
	foreign = Swap de performace,
	foreign-babel = english,
	foreign-locale = french,    
    tag = {abbrev},
}
```
but I'd prefer a solution in `LaTeX` to import these `keys` from a simple text file.

**MWE**
![image.png](/image?hash=e88ae1c3b1fabd1849293147245e635c30ff36b00e621808aa4772f2bc619000)
```
\documentclass{article}
\usepackage{acro} 

\begin{filecontents*}[overwrite]{myacrolist.csv}
mnemonic,short,long,foreign,foreign-babel,foreign-locale,tag
trs,TRS,Total Return Swap,Swap de performace,english,french,abbrev
bswap,BS,Swap de base,Basis Swap,english,french,abbrev
brt,BRT,Brent,,,,ticker
wti,WTI,West Texas Intermediate,,,,ticker
% otc,OTC,gré à gré, over-the-counter,english,french,jargon 
\end{filecontents*}


\acsetup{
	make-links,
    first-style = long,
    list/display = used,
    pages/display = first
}

\DeclareAcronym{bswap}{ 
    short = {BS}, 
    long  = {Swap de base},
	foreign = Basis Swap	 ,
	foreign-babel = english,
	foreign-locale = french,    
    tag = {abbrev},
}

\DeclareAcronym{trs}{ 
    short = {TRS}, 
    long  = {Swap de performace},
	foreign = Total Return Swap,
	foreign-babel = english,
	foreign-locale = french,    
    tag = {abbrev},
}

\DeclareAcronym{brt}{ 
    short = {BRT}, 
    long  = {Brent},
    tag = {ticker},
}

\DeclareAcronym{wti}{ 
    short = {WTI}, 
    long  = {West Texas Intermediate},
    tag = {ticker},
}

\begin{document}

\ac{otc} has an accent in french.

\ac{bswap} and \ac{trs} are two type of swaps.

\ac{trs} market is getting bigger.

\ac{brt} is on the european market while \ac{wti} is on the US market.

\ac{brt} and \ac{wti} are two type of petroleum.

\printacronyms[name=Abbreviations, include=abbrev]

\printacronyms[name=Tickers, include=ticker]

\end{document}

```

Top Answer
user 3.14159
You can use `pgfplotstable` to parse the csv file. The code is rather explicit so that it is easier to understand and adjust to your needs. The main command is 
```
\newcommand\CreateAcronymsFromCSV[2][]{%
\pgfplotstableread[col sep=comma]{#2}\acrotable
\pgfplotstablegetrowsof{\acrotable}
\pgfmathtruncatemacro{\acrorownum}{\pgfplotsretval-1}
\pgfplotsinvokeforeach{0,...,\acrorownum}{%
\pgfplotstablegetelem{##1}{mnemonic}\of\acrotable
\let\mymnemonic\pgfplotsretval
\pgfplotstablegetelem{##1}{short}\of\acrotable
\let\myshort\pgfplotsretval
\pgfplotstablegetelem{##1}{long}\of\acrotable
\let\mylong\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign}\of\acrotable
\let\myforeign\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign-babel}\of\acrotable
\let\myforeignbabel\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign-locale}\of\acrotable
\let\myforeignlocale\pgfplotsretval
\pgfplotstablegetelem{##1}{tag}\of\acrotable
\let\mytag\pgfplotsretval
\ifx\myforeign\empty
\expanded{\noexpand\DeclareAcronym{\mymnemonic}{ 
    short = {\myshort}, 
    long  = {\mylong},
    tag = {\mytag},
}}
\else
\expanded{\noexpand\DeclareAcronym{\mymnemonic}{ 
    short = {\myshort}, 
    long  = {\mylong},
	foreign =\myforeign,
	foreign-babel =\myforeignbabel,
	foreign-locale =\myforeignlocale,    
    tag = {\mytag},
}}
\fi
}}%
```
in which the keys that get read out get stored in macros, which is good and bad. Bad because of the usual namespace concerns, and good because it is relatively easy to see what's going on and to make changes. You then only need to say
```
\CreateAcronymsFromCSV{myacrolist.csv}
```
to generate the acronyms.
```
\documentclass{article}
\usepackage{acro} 
\usepackage{pgfplotstable} 
\pgfplotsset{compat=1.18}

\begin{filecontents*}[overwrite]{myacrolist.csv}
mnemonic,short,long,foreign,foreign-babel,foreign-locale,tag
trs,TRS,Total Return Swap,Swap de performance,english,french,abbrev
bswap,BS,Swap de base,Basis Swap,english,french,abbrev
brt,BRT,Brent,,,,ticker
wti,WTI,West Texas Intermediate,,,,ticker
\end{filecontents*}
\newcommand\CreateAcronymsFromCSV[2][]{%
\pgfplotstableread[col sep=comma]{#2}\acrotable
\pgfplotstablegetrowsof{\acrotable}
\pgfmathtruncatemacro{\acrorownum}{\pgfplotsretval-1}
\pgfplotsinvokeforeach{0,...,\acrorownum}{%
\pgfplotstablegetelem{##1}{mnemonic}\of\acrotable
\let\mymnemonic\pgfplotsretval
\pgfplotstablegetelem{##1}{short}\of\acrotable
\let\myshort\pgfplotsretval
\pgfplotstablegetelem{##1}{long}\of\acrotable
\let\mylong\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign}\of\acrotable
\let\myforeign\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign-babel}\of\acrotable
\let\myforeignbabel\pgfplotsretval
\pgfplotstablegetelem{##1}{foreign-locale}\of\acrotable
\let\myforeignlocale\pgfplotsretval
\pgfplotstablegetelem{##1}{tag}\of\acrotable
\let\mytag\pgfplotsretval
\ifx\myforeign\empty
\expanded{\noexpand\DeclareAcronym{\mymnemonic}{ 
    short = {\myshort}, 
    long  = {\mylong},
    tag = {\mytag},
}}
\else
\expanded{\noexpand\DeclareAcronym{\mymnemonic}{ 
    short = {\myshort}, 
    long  = {\mylong},
	foreign =\myforeign,
	foreign-babel =\myforeignbabel,
	foreign-locale =\myforeignlocale,    
    tag = {\mytag},
}}
\fi
}}%

\acsetup{
	make-links,
    first-style = long,
    list/display = used,
    pages/display = first
}
\CreateAcronymsFromCSV{myacrolist.csv}
\begin{document}

\ac{bswap} and \ac{trs} are two type of swaps.

\ac{trs} market is getting bigger.

\ac{brt} is on the european market while \ac{wti} is on the US market.

\ac{brt} and \ac{wti} are two type of petroleum.

\printacronyms[name=Abbreviations, include=abbrev]

\printacronyms[name=Tickers, include=ticker]

\end{document}
```
![Screen Shot 2021-06-12 at 10.10.34 AM.png](/image?hash=ff9abac99edcbe50957612df0ed57a333dfbbe45bb8dc3b7cba61be7c198bdaa)
Answer #2
Skillmon
The following defines the macro `\csvfileprocess` that takes an optional argument with key=value interface, a file name as a mandatory argument, and what to do with each line of that file as a third argument.

The third argument has to be safe inside an `\edef`-expansion. Inside of it you can use `\csvfield{<num>}` to use the value of the `<num>`th column, and `\csvfieldifempty{<num>}` to test whether the `<num>`th column is empty.

The key=value interface supports the following options:

- `delimiter`, the delimiter in the csv between the columns (defaults to `,`)
- `skip-head`, how many lines to skip at the start of the file

With it, the following reads in your csv and calls `\DeclareAcronym` for each line (full code below):

```
\csvfileprocess[skip-head=1]{\jobname.csv}
  {%
    \noexpand\DeclareAcronym{\csvfield{1}}
      {%
        short = {\csvfield{2}},
        long  = {\csvfield{3}},
        \csvfieldifempty{4}{}{foreign={\csvfield{4}},}
        \csvfieldifempty{5}{}{foreign-babel={\csvfield{5}},}
        \csvfieldifempty{6}{}{foreign-locale={\csvfield{6}},}
        \csvfieldifempty{7}{}{tag={\csvfield{7}},}
      }%
  }
```

The entire code:

```
\documentclass{article}
\usepackage{acro} 

\begin{filecontents*}[overwrite]{\jobname.csv}
mnemonic,short,long,foreign,foreign-babel,foreign-locale,tag
trs,TRS,Total Return Swap,Swap de performace,english,french,abbrev
bswap,BS,Swap de base,Basis Swap,english,french,abbrev
brt,BRT,Brent,,,,ticker
wti,WTI,West Texas Intermediate,,,,ticker
\end{filecontents*}

\ExplSyntaxOn
\cs_generate_variant:Nn \seq_set_split:NnV { No }
\cs_generate_variant:Nn \seq_set_split:Nnn { No }
\ior_new:N \g__csvfileprocess_file_ior
\seq_new:N \l__csvfileprocess_line_seq
\cs_new:Npn \__csvfileprocess_tl_restore:N #1
  { \exp_not:n { \tl_set:Nn #1 } { \exp_not:o #1 } }
\cs_new:Npn \__csvfileprocess_int_restore:N #1
  { \exp_not:n { \int_set:Nn #1 } { \exp_not:V #1 } }
% evil function with implementation detail assumptions
\cs_new:Npn \__csvfileprocess_seq_restore:N #1
  { \exp_not:n { \cs_set:Npn #1 } { \exp_not:o #1 } }
\cs_new:Npn \__csvfileprocess_line_processor: {}
\keys_define:nn { csvfileprocess }
  {
     delimiter .tl_set:N = \l__csvfileprocess_delimiter_tl
    ,delimiter .initial:n = {,}
    ,skip-head .int_set:N = \l__csvfileprocess_skip_head_int
  }
\cs_new_protected:Npn \csvfileprocess:nnn #1#2#3
  {
    \keys_set:nn { csvfileprocess } {#1}
    \cs_set:Npn \__csvfileprocess_line_processor: {#3}
    \__csvfileprocess_process_file:n {#2}
  }
\cs_new_protected:Npn \__csvfileprocess_process_file:n #1
  {
    \ior_open:Nn \g__csvfileprocess_file_ior {#1}
    \int_step_inline:nn \l__csvfileprocess_skip_head_int
      { \ior_get:NN \g__csvfileprocess_file_ior \l_tmpa_tl }
    \ior_map_inline:Nn \g__csvfileprocess_file_ior
      {
        \seq_set_split:Non \l__csvfileprocess_line_seq \l__csvfileprocess_delimiter_tl {##1}
        \use:x { \__csvfileprocess_line_processor: }
      }
    \ior_close:N \g__csvfileprocess_file_ior
  }
\NewExpandableDocumentCommand \csvfield { m }
  { \seq_item:Nn \l__csvfileprocess_line_seq {#1} }
\prg_new_conditional:Npnn \csvfileprocess_if_empty_field:n #1 { TF }
  {
    \exp_args:Ne \tl_if_empty:nTF { \seq_item:Nn \l__csvfileprocess_line_seq {#1} }
      \prg_return_true:
      \prg_return_false:
  }
\cs_new_eq:NN \csvfieldifempty \csvfileprocess_if_empty_field:nTF
\NewDocumentCommand \csvfileprocess { O{} m m }
  {
    \use:x
      {
        \exp_not:n { \csvfileprocess:nnn {#1} {#2} {#3} }
        \__csvfileprocess_tl_restore:N \l__csvfileprocess_delimiter_tl
        \__csvfileprocess_int_restore:N \l__csvfileprocess_skip_head_int
        \__csvfileprocess_seq_restore:N \l__csvfileprocess_line_seq
        \exp_not:n { \cs_set:Npn \__csvfileprocess_line_processor: }
          { \exp_not:o \__csvfileprocess_line_processor: }
      }
  }
\ExplSyntaxOff

\acsetup{
	make-links,
    first-style = long,
    list/display = used,
    pages/display = first
}

\csvfileprocess[skip-head=1]{\jobname.csv}
  {%
    \noexpand\DeclareAcronym{\csvfield{1}}
      {%
        short = {\csvfield{2}},
        long  = {\csvfield{3}},
        \csvfieldifempty{4}{}{foreign={\csvfield{4}},}
        \csvfieldifempty{5}{}{foreign-babel={\csvfield{5}},}
        \csvfieldifempty{6}{}{foreign-locale={\csvfield{6}},}
        \csvfieldifempty{7}{}{tag={\csvfield{7}},}
      }%
  }

\begin{document}

\ac{bswap} and \ac{trs} are two type of swaps.

\ac{trs} market is getting bigger.

\ac{brt} is on the european market while \ac{wti} is on the US market.

\ac{brt} and \ac{wti} are two type of petroleum.

\printacronyms[name=Abbreviations, include=abbrev]

\printacronyms[name=Tickers, include=ticker]

\end{document}
```

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.