Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I tried to read a file with lua and set the content as normal text in my document, but I didn't worked it out. Here my code:

\documentclass{scrartcl}
\usepackage{luatextra}
\usepackage{filecontents}

\begin{filecontents}{testdata.dat}
  A  B
  1.0 20
  1.1 21
  1.2 22
\end{filecontents}

\begin{luacode}
  function readtxt()
    file = io.open("testdata.dat", "r")
    text = file:read("*all")
    print(text)
    return tex.print(text) 
  end
\end{luacode}

\begin{document}
  \directlua{readtxt()}
\end{document}

But nothing is printed to the document although lua diplays the content of the file in the terminal.

share|improve this question
    
That might be related to special characters in testdata.dat. The filecontents package seems to add a few lines at the beginning. Have you tried to disable any further interpretation in tex.print? This can be achieved by using tex.print(-2, text). –  Alexander Feb 12 '13 at 10:01
    
Yes I tried this, but then it messes up the linebreaks and replaces them with the \Omega letter. –  Reza Feb 12 '13 at 10:10
    
In your MWE, use a filecontents* environment (note the star!) and the result will be good. –  Paul Gaborit Feb 12 '13 at 10:21
    
@Reza Would it be correct to assume that you'll want to do further processing on the data here? Will that be in Lua or in TeX (as the line-end business will be important only in the second case).? –  Joseph Wright Feb 12 '13 at 10:30
    
@JosephWright Yes that's correct, I want to pass it to a pgfplotstable, like this I can perhaps circumvent escaping every tex character, like underscore etc... –  Reza Feb 12 '13 at 13:06
show 3 more comments

4 Answers

up vote 10 down vote accepted

Edit: a short version of readtxt() function.

\begin{luacode*}
  function readtxt()
    file = io.open("testdata.dat", "r")
    tex.print(string.split(file:read("*a"),"\n"))
  end
\end{luacode*}

First proposition: a solution consists to store lines in a table and to "tex.print" the lines one by one (each argument of tex.print is a single line of TeX).

\documentclass{scrartcl}
\usepackage{luatextra}
\usepackage{filecontents}

\begin{filecontents}{testdata.dat}
  A  B
  1.0 20
  1.1 21
  1.2 22
\end{filecontents}

\begin{luacode}
  function readtxt()
    file = io.open("testdata.dat", "r")
    for line in file:lines() do
      print(line)
      tex.print(line)
    end
  end
\end{luacode}

\begin{document}
  \directlua{readtxt()}
\end{document}
share|improve this answer
    
Great solution. IMO even better: for line in file:lines() do tex.print(line) end - no need for the extra variable and perfectly clear. –  topskip Feb 12 '13 at 11:34
    
@topskip Thanks. I edited my answer... –  Paul Gaborit Feb 12 '13 at 16:27
add comment

The file being written by filecontents looks like this:

%% LaTeX2e file `testdata.dat'
%% generated by the `filecontents' environment
%% from source `luareadfile' on 2013/02/12.
%%
  A  B
  1.0 20
  1.1 21
  1.2 22

When lua reads that in to the string, it does no processing. If TeX were to read that in, it would ignore the comment lines since everything from a % to a newline gets eaten up. Moreover, TeX would translate the newlines to space characters (and translate any double newlines to \par tokens).

The file then gets inserted into the TeX stream via tex.print. This, it would appear, is inserted as if the input parser has already done its job. So TeX assumes that double newlines have already been replaced by \pars and treats a newline character as simply a space token. However, it still sees the % character and is prepared to deal with it by ignoring anything after it up to a newline. But there are no newlines, so TeX keeps discarding stuff until it is stopped (at the end of the tex.print).

I don't know if it is possible to fix this "properly" by getting the new lines to be interpreted correctly, but if you have control over the file contents (as you appear to here) you could get lua to strip out the comments first using a simple pattern match before presenting the data to TeX.

\documentclass{scrartcl}
%\url{http://tex.stackexchange.com/q/97822/86}
\usepackage{luatextra}
\usepackage{filecontents}

\begin{filecontents}{testdata.dat}
  A  B
  1.0 20
  1.1 21
  1.2 22
\end{filecontents}

\begin{luacode}
  function readtxt()
    file = io.open("testdata.dat", "r")
    text = file:read("*all")
    clean = string.gsub(text,'%%[^\string\n]*',"")
    print(clean)
    return tex.print(clean) 
  end
\end{luacode}

\begin{document}
Reading in text:
  \directlua{readtxt()}
Finished reading in text.
\end{document}

Notice the \string! That's because your lua code is embedded in your document. It's usually a good idea to avoid that by having the lua code in a separate file.

This produces:

Reading in text: A B 1.0 20 1.1 21 1.2 22 Finished reading in text.
share|improve this answer
add comment

io.lines also closes the file and tex.sprint writes a new line in the output for every call. The reason why the %-lines are ignored by TeX automatically

\documentclass[a5paper]{article}
\usepackage{luacode,fancyvrb}
\pagestyle{empty}
\begin{filecontents}{testdata.dat}
  A  B
  1.0 20
  1.1 21
  1.2 22
\end{filecontents}

\begin{luacode*}
  function readtxt(filename,suffix)
    suffix = suffix or ""
    for line in io.lines(filename) do tex.sprint(line..suffix) end
  end
\end{luacode*}

\begin{document}
\VerbatimInput[frame=single]{testdata.dat}

\directlua{readtxt("testdata.dat")}

\directlua{readtxt("testdata.dat","\string\\par")}
\end{document}    

enter image description here

share|improve this answer
    
This is the right way to implement readtxt for this qn. Minor tweak: suffix = suffix or "" is the idiomatic way to define optional parameters in Lua. –  Charles Stewart Feb 14 '13 at 9:23
    
@CharlesStewart: you are right, I edited the code! –  Herbert Feb 14 '13 at 11:09
add comment

Another (besides @AndrewStacey's solution) possibility is to use string.gmatch() and insert the file line by line:

\documentclass{scrartcl}
\usepackage{luatextra}
\usepackage{filecontents}

\begin{filecontents}{testdata.dat}
  A  B
  1.0 20
  1.1 21
  1.2 22
\end{filecontents}

\begin{luacode*}
  function readtxt()
    file = io.open("testdata.dat", "r")
    text = file:read("*all")
    file:close()
    for x in string.gmatch(text,"[^\n]+") do
        tex.print(x)
    end
  end
\end{luacode*}

\begin{document}
  \directlua{readtxt()}
\end{document}

And if you want to insert your file verbatim, you can use the -2 catcode table:

tex.print(-2,text)

Which tells TeX not to interpret the contents of the string.

share|improve this answer
1  
I like this one better than mine. –  Loop Space Feb 12 '13 at 10:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.