如何使用 luatex 读取文件

如何使用 luatex 读取文件

我尝试使用 lua 读取文件并将内容设置为文档中的普通文本,但没有成功。这是我的代码:

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

但是虽然 lua 在终端中显示了文件的内容,但没有任何内容打印到文档中。

答案1

编辑:函数的简短版本readtxt()

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

第一个命题:一种解决方案是将行存储在表中,然后逐行“tex.print” (每个参数tex.print都是一行 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}

答案2

io.lines还会关闭文件并在每次调用时在输出中写入新行。TeX自动忽略 -lines 的tex.sprint原因%

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

在此处输入图片描述

答案3

正在写入的文件filecontents如下所示:

%% 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

当 lua 将其读入字符串时,它不进行任何处理。如果 TeX 将其读入,它会忽略注释行,因为从 a%到换行符的所有内容都会被吃掉。此外,TeX 会将换行符转换为空格字符(并将任何双换行符转换为\par标记)。

然后,文件通过 插入到 TeX 流中tex.print。看起来,插入过程就像输入解析器已经完成其工作一样。因此,TeX 假设双换行符已被\pars 替换,并将换行符视为空格标记。但是,它仍然看到该%字符,并准备通过忽略其后直到换行符的所有内容来处理它。但是没有换行符,因此 TeX 会继续丢弃内容,直到它停止(在 的末尾tex.print)。

我不知道是否可以通过正确解释新行来“正确”地解决这个问题,但如果你可以控制文件内容(正如你在这里看到的那样),你可以让 lua 先使用简单的模式匹配删除注释,然后再将数据呈现给 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}

注意\string!这是因为您的 lua 代码嵌入在您的文档中。通常,将 lua 代码放在单独的文件中是避免这种情况的好方法。

得出的结果为:

Reading in text: A B 1.0 20 1.1 21 1.2 22 Finished reading in text.

答案4

另一种可能性(除了@AndrewStacey 的解决方案之外)是string.gmatch()逐行使用和插入文件:

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

如果你想逐字插入文件,你可以使用 -2 catcode 表:

tex.print(-2,text)

这告诉 TeX 不要解释字符串的内容。

相关内容