1

I'm trying to read a CSV file into latex and produce a new page for every row in the file. Unfortunately, the file quotes every field, uses semicolons as delimiters, and contains underscores in the header names. I've figured out how to deal with the latter two issues. In order to work around the quoting issue, it seems to be necessary to change the catcode of quotation marks to ignore them (which seems somewhat dangerous to me in case there's a semicolon in one of the quoted fields, but that's a different story).

The following MWE, however, does not compile for me when I also try to load the babel package with the ngerman option, resulting in the error message

! Improper alphabetic constant.
<to be read again> 
                   \active 
l.2 \catcode `"\active

? 

Commenting out the offending line makes the example compile without issues.

\begin{filecontents*}{\jobname.csv}
  "ID";"USER_NAME"
  "1";"Foo Bar"
  "2";"Baz Qüx"
\end{filecontents*}

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel} % <- MWE compiles without this line

\usepackage{csvsimple}

\newcommand*{\makepage}[2]{
  ID: #1 \\
  User: #2 \newpage
}

\begin{document}

\csvreader[
  head to column names,
  /csv/separator=semicolon,
  before reading={\catcode`\"=9}
]{\jobname.csv}{USER_NAME=\username}{\makepage{\ID}{\username}}

\end{document}

Edit: The solution suggested below fixes the compilation error. However, when applying the fix to display the rows of the CSV file in a tabularx environment, any entries after the first row now appear with quotes.

\begin{filecontents*}{\jobname.csv}
  "ID";"FIRST_NAME";"FAMILY_NAME"
  "1";"Foo";"Bar"
  "2";"Baz";"Qüx"
  "3";"Quux";"Quuz Corge"
\end{filecontents*}

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage[ngerman]{babel}
\usepackage{tabularx}
\usepackage{csvsimple}

\begin{document}

\begin{tabularx}{\linewidth}{|l|l|l|c|X|}
  \hline
  \textbf{\#} & \textbf{ID} & \textbf{Name} & \textbf{Check} &
  \textbf{Comment}
  \csvreader[
    head to column names,
    /csv/separator=semicolon,
    before reading={\catcode`\"=9},
    after reading={\catcode`\"=13}
  ]{\jobname.csv}{
    ID=\userid,
    FIRST_NAME=\firstname,
    FAMILY_NAME=\familyname
  }{\\\hline \thecsvrow & \userid & \firstname~\familyname & $\square$ &}
  \\\hline
\end{tabularx}

\end{document}
1

This happens because babel writes in the .aux file (which is read when the \end{document} is executed):

\catcode`"\active

but you used \catcode`\"=9, so that essentially becomes:

\catcode`\active

which raises the Improper alphabetic constant error. The \catcode change is not made inside any group, so its effect will last until changed again.

This wouldn't happen if babel used a backslash before the ": \catcode`\"\active.

To solve it you have to "reactivate" the " after reading the file. You can use the after reading key (and make sure that you use \catcode`\"=13, with a backslash):

\begin{filecontents*}{\jobname.csv}
  "ID";"USER_NAME"
  "1";"Foo Bar"
  "2";"Baz Qüx"
\end{filecontents*}

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel} % <- MWE compiles without this line

\usepackage{csvsimple}

\newcommand*{\makepage}[2]{
  ID: #1 \\
  User: #2 \newpage
}

\begin{document}

\csvreader[
  head to column names,
  /csv/separator=semicolon,
  before reading={\catcode`\"=9},
  after reading={\catcode`\"=13},
]{\jobname.csv}{USER_NAME=\username}{\makepage{\ID}{\username}}

\end{document}
  • Now that mention it, I actually tried that before, but I thought it didn't help cause the problem remained in the context where I'm using the csvreader. You are right though that it fixes the example I posted. After changing the catcode back, I now receive the error '! ngerman: The command "\unskip is undefined. \grmn@dq@error ...and \dq \string #1 is undefined}'. This might have to do with the fact that I'm invoking csvreader inside a tabularx environment though. – nkoep Jan 15 at 19:10
  • @nkoep Hm... The code as I posted works for me. I couldn't reproduce the error you mentioned. Can you show me a MWE that raises that error? – Phelype Oleinik Jan 15 at 19:18
  • Sorry, I explained this badly. I need to read the CSV file in two different situations. I thought the error was the same in both, but it turns out it isn't. The first problem was fixed by your suggestion. In the second situation I need to create a table from the CSV file. In particular, I'm using csvreader inside a tabularx environment (via ltablex). Unfortunately, I couldn't produce an MWE for this problem yet. I'll post one as soon as I identified the problem. – nkoep Jan 15 at 19:46
  • I've figured out what the issue was. In our code, we were using both \usepackage{ngerman} and \usepackage[ngerman]{babel} which raised the error I mentioned above. Removing the former package fixed the compilation error. However, the issue I added to my original post remains. – nkoep Jan 17 at 9:17
0

I've figured it out with some more trial & error. Instead of using the before reading and after reading options, I've wrapped the tabularx environment in its own group with the catcode changed. That seems to have solved all my issues. Maybe someone can shed some light on the reason the other method doesn't work here, but for now I'm satisfied.

\begin{filecontents*}{\jobname.csv}
  "ID";"FIRST_NAME";"FAMILY_NAME"
  "1";"Foo";"Bar"
  "2";"Baz";"Qüx"
  "3";"Quux";"Quuz Corge"
\end{filecontents*}

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amssymb}
\usepackage[ngerman]{babel}
\usepackage{tabularx}
\usepackage{csvsimple}

\begin{document}

\begingroup\catcode`"=9
\begin{tabularx}{\linewidth}{|l|l|l|c|X|}
  \hline
  \textbf{\#} & \textbf{ID} & \textbf{Name} & \textbf{Check} &
  \textbf{Comment}
  \csvreader[
    head to column names,
    /csv/separator=semicolon
  ]{\jobname.csv}{
    ID=\userid,
    FIRST_NAME=\firstname,
    FAMILY_NAME=\familyname
  }{\\\hline \thecsvrow & \userid & \firstname~\familyname & $\square$ &}
  \\\hline
\end{tabularx}
\endgroup

\end{document}

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.