I have some data stored in a CSV file, in this manner:

000000001 @ name @ information @ more information @ some more information

I also have a information.tex file containing the numbers from the first column throughout (this file is \input into my main document):

\chapter{Some information about 000012311}
    This is some text about 000012311 and 000012312\footnote{See also 000012313}.
\chapter{Some other information}
    This text is about 000000001.

I currently use a BASH script which replaces all numbers appearing information.tex matched to the first column of the CSV file with a macro, \mymacro{}{}{}{}, where each {} contains data from a column (second, third, fourth, and fifth).

For e.g., where the input file above contains This text is about 000000001., using the CSV file line above, it becomes This text is about \mymacro{name}{information}{more information}{some more information}., so when compiled, the text is displayed according to the definition of \mymacro. Essentially, I am using BASH to edit information.tex, after which I compile it.

Can I remove the need for BASH and do this directly with LuaTeX or some form of ConTeXt?

  • 3
    Is it possible to create your CSV with commas to separate the contents? Also, does the CSV only contain unique entries? If so, this can most likely be done entirely within LaTeX using datatool. – Werner Jan 18 '12 at 6:27
  • I used "@" because commas appear throughout the contents, however, commas with quotes around the content would be okay. The CSV file is easily changed. There are no duplicate rows and the items appearing in columns 1 and 2 are never identical. I tried datatool, but it seems to have difficulty with UTF-8. – Village Jan 18 '12 at 10:21

My approach is to read all lines from the file, split each line in it's arguments (divided by @) and store the arguments in a lua-table (tableItem) which is added to an other table (dataTable). We give the tableItem a name that we can access each item by name not by index. If we use the first argument of each line for the name we have direct access to the (sub)tables (tableItem) via the given number in the text using a macro called csvData. In this macro one can access the table and its arguments to format a latex-string or do whatever is needed.


        %here one can access the stored arguments of the input line via the table item name

    local input = io.open('datafile.dat', 'r')
   dataTable = {}
    for line in input:lines() do
        local split = string.explode(line,"@")
        tableItem={split[1]}%item name is the first input argument of the line


| improve this answer | |

A simple approach is to call string.explode() for that. As you don't give the exact detail what goes where, I can only show the frame for that:



for line in io.lines("somedata.dat") do
  local line_t = string.explode(line,"@")
  tex.sprint(string.format("\\chapter{%s} Some information about %s",line_t[1],line_t[2]))


where somedata.dat looks like this:

000000001 @ name @ information @ more information @ some more information
000000002 @ name2 @ information2 @ more information2 @ some more information2
| improve this answer | |
  • 1
    @Village If you really want a CSV file, then my answer would be different, of course (it doesn't handle CSV files, but with LPEG it's not difficult). – topskip Jan 18 '12 at 12:26
  • I have a CSV file, but I can convert it to other formats easily with OpenOffice.org. – Village Jan 18 '12 at 12:33

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.