使用包含 CSV 文件中信息的宏替换匹配的文本

使用包含 CSV 文件中信息的宏替换匹配的文本

我有一些数据存储在 CSV 文件中,方式如下:

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

我还有一个information.tex包含整个第一列的数字的文件(该文件位于\input我的主文档中):

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

我目前使用一个BASH脚本,该脚本用宏替换information.tex与 CSV 文件第一列匹配的所有数字,\mymacro{}{}{}{}其中每个数字{}包含来自某一列(第二、第三、第四和第五)的数据。

例如,上面的输入文件包含This text is about 000000001.,使用上面的 CSV 文件行,它变为This text is about \mymacro{name}{information}{more information}{some more information}.,因此在编译时,文本将根据 的定义显示\mymacro。本质上,我正在使用 BASH 编辑information.tex,然后对其进行编译。

我可以不再需要 BASH 而直接使用 LuaTeX 或某种形式的 ConTeXt 来完成此操作吗?

答案1

我的方法是读取文件中的所有行,将每行拆分为其参数(用 @ 分隔),并将参数存储在 lua 表 ( tableItem) 中,该表将添加到另一个表 ( dataTable)。我们为 tableItem 命名,这样我们就可以通过名称而不是索引访问每个项目。如果我们将每行的第一个参数用作名称,我们就可以使用名为 的宏通过文本中给定的数字直接访问(子)表 (tableItem) csvData。在这个宏中,可以访问表及其参数以格式化 latex 字符串或执行任何需要的操作。

\documentclass{book}

\def\csvData#1{%
    \directlua{
        %here one can access the stored arguments of the input line via the table item name
        d=dataTable[#1];
        tex.sprint(d.arg1..d.arg2..d.arg3..d.arg4..d.arg5)%
    }
}

\def\readDataFile{%
  \directlua{%
    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
        tableItem.arg1=split[1]
        tableItem.arg2=split[2]
        tableItem.arg3=split[3]
        tableItem.arg4=split[4]
        tableItem.arg5=split[5]

        table.insert(dataTable,tableItem)
    end
    input:close()
  }%
}
\makeatother


\begin{document}
\readDataFile
\noindent
\csvData{000000001}.\\
\csvData{000000004}.\\
\csvData{000000007}.\\
\end{document}

答案2

一种简单的方法是调用string.explode()它。由于您没有给出确切的细节,所以我只能显示框架:

\documentclass{book}
\usepackage{luacode}
\begin{document}

\begin{luacode*}

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]))
end
\end{luacode*}

\end{document}

看起来somedata.dat像这样:

000000001 @ name @ information @ more information @ some more information
000000002 @ name2 @ information2 @ more information2 @ some more information2

相关内容