使用 luacode 循环并打印代码

使用 luacode 循环并打印代码

我打算使用pgfplots一个包含多列的 CSV 文件来打印多个图,每个图一列。这是针对单个列实现的方法:

\documentclass[12pt]{article}

% lua
\usepackage{luacode}

% Maths
\usepackage{amsmath, amssymb}

% Tikz
\usepackage{tikz}   
\usetikzlibrary{datavisualization}

% pgf   
\usepackage{pgfmath}    % calculations
\usepackage{pgfplots}
    \pgfplotsset{
        compat=1.18,
        width=\textwidth%
    }

% Chem
\usepackage{chemgreek}
\usepackage{chemformula}    % formulas quimicas

\begin{document}
\begin{tikzpicture}
\pgfplotsset{
    height= 9cm
}
\begin{axis}
    [
        title=  {\ch{column 1}},
        xlabel= {\chemlambda Wavelenght (nm)},
        ylabel= {Molar Absorptivity},
        xmin= 350, xmax= 850,
        ymin= 0,
    ]

    \addplot%
        [white]
        table[
            col sep=comma, 
            header=true,
            x index=0,
            y index=1,
        ]   { file.csv };
    
\end{axis}
\end{tikzpicture}
\end{document}

对于该文件你可以简单地写入:

a,b,c,d
1,1,2,3
2,1,4,9
3,1,8,27
4,1,24,81

在 TXT 文件中并重命名为 CSV。

到目前为止我已设法使用luacode*如下方法重写:

...
\begin{document}

\begin{luacode*}
    
chem = { 
    "\\ch{column 1}", 
    "\\ch{column 2}", 
    "\\ch{column 3}" 
}
    
for i=1,3,1
do
    
    tex.sprint(
    [[
        \begin{tikzpicture}
          \pgfplotsset{height=9cm}
          \begin{axis}[
    ]],
            'title=', chem[1], ',\n',
    [[
            xlabel= {\chemlambda Wavelenght (nm)},
            ylabel= {Molar Absorptivity},
            xmin= 350, xmax= 850,
            ymin= 0,
          ]
          
            \addplot[white] 
                table[
                    col sep=comma, 
                    header=true, 
                    x index=0,
    ]], 
    '               y index=', 1, "\n",
    [[
                ] {file.csv};
            
          \end{axis}
          \end{tikzpicture}
    ]]
    )
    
end

\end{luacode*}

\end{document}
  • 由于某种原因,即使我使用luacode*应该解释\为的环境\,但这并没有发生在单行字符串中,所以我不得不添加\\
  • 循环将从 1 索引到 3,并更改'y index=', 1'y index=', index'title=', chem[1]'title=', chem[index]

问题是它不起作用,我不断收到以下错误消息:

包 pgfplots 错误:抱歉,提供的绘图命令未知或不受 pgfplots 支持!忽略它..

这意味着 lua 打印了一些错误的东西,所以我决定简单地用printas 代替tex.sprint,得到以下内容:

\begin{tikzpicture}
\pgfplotsset{height=9cm}
\begin{axis}[
        title=  \ch{column 1}   ,
        xlabel= {\chemlambda Wavelenght (nm)},
    ylabel= {Molar Absorptivity},
    xmin= 350, xmax= 850,
    ymin= 0,
]

    \addplot[white]
                table[
                    col sep=comma,
                    header=true,
                    x index=0,
                        y index=    1   
            ] {file.csv};
    
\end{axis}
\end{tikzpicture}
...

请注意,与原始代码相比,每次字符串块中断时都会发生某些事情,并且会添加空间以某种方式破坏代码。

我尝试过的事情:

  • 为每个字符串块编写一个单独的tex.sprint代码试图修复它,但它似乎使情况变得更糟,在每个字符串块的末尾添加一个换行符tex.print
  • 替代,但也tex.sprint(...)不起作用tex.sprint(table.concat({...},''))

注意:顺便说一句,如果您知道一种更好的循环方法也可以提供帮助,我会尝试使用,lua因为对我来说这似乎是可能的,而且我看到人们使用循环的其他方法似乎很难理解或非常冗长和不切实际。

答案1

  • 由于某种原因,即使 im(sic) 使用luacode*应该解释\为的环境\,但这并没有发生在单行字符串中,所以我不得不添加\\

环境luacode*正常运行并传递\给 Lua,无需更改。您需要\\在字符串中使用,因为您仍然必须遵循 Lua 语法规则。(否则,例如,\n在字符串中写换行符或使用其他转义序列将是不可能的。)

这意味着 lua 打印了一些错误的东西,所以我(原文如此)决定简单地用printas 代替tex.sprint,得到以下内容:

[...]

请注意,与原始代码相比,每次字符串块中断时都会发生某些事情,并且会添加空间以某种方式破坏代码。

在 Lua 中,,不是字符串连接运算符,而是用于分隔参数。因此,您要求print打印多个单独的字符串。因此它会自动添加制表符来分隔它们。当然,如何处理多个参数与如何处理多个参数print完全无关。tex.printtex.sprint

那么,让我们来探讨一下实际问题。

既然您正在使用tex.sprint,让我们看看它的文档:

TeX 将每个字符串参数视为一种特殊的输入行,使其适合用作部分行输入机制:[...]

这告诉我们很多事情:

  1. tex.sprint与 相对,tex.print是用于创建“部分行”。由于您尝试模拟从 TeX 代码读取的多个完整行,因此您可能会这样做不是想要“部分线条”但想要正常线条。因此使用tex.print而不是tex.sprint

  2. 多个参数不仅被连接起来,还被视为单独的“部分行”,如文档后面所定义,或在使用时被视为单独的行tex.print。由于您想要模拟将变量插入行中间的代码,因此您需要在将线段传递给 TeX 之前将它们连接起来。(正如您尝试的那样table.concat

  3. 可能最重要的一点也是最微妙的一点:“每个字符串参数都被视为 [...] 输入行 [...]”。它从未声称字符串参数的每一行都成为输入行,但整个参数被视为行。您与 TeX 的交互处于系统相关部分的下一级,系统相关部分将文件拆分为单独的行,因此您必须自己处理这个问题。现在,您可能认为您正在传递多行,但从 TeX 的角度来看,您正在传递一个非常大的行,而该行恰好在中间有 Unicode 行尾标记。由于行尾标记几乎从不出现在输入行的中间(因为它通常会结束一行并被输入文件处理程序过滤掉),TeX 代码会对您尝试传递给它的这个奇怪的字符感到困惑。

    要解决这个问题,您必须自己将字符串分成单独的行,然后可以单独传递给 TeX。例如,可以使用 来完成string.explode(..., '\n')

如果你应用所有这些,你会得到

\documentclass[12pt]{article}
% lua
\usepackage{luacode}
% Maths
\usepackage{amsmath, amssymb}
% Tikz
\usepackage{tikz}   
\usetikzlibrary{datavisualization}


% pgf   
\usepackage{pgfmath}    % calculations
\usepackage{pgfplots}
    \pgfplotsset{
        compat=1.18,
        width=\textwidth%
    }

% Chem
\usepackage{chemgreek}
\usepackage{chemformula}    % formulas quimicas
\usepackage{chemfig}        % Estruturas quimicas


\begin{document}
\begin{luacode*}
    
    chem = { "\\ch{column 1}", "\\ch{column 2}", "\\ch{column 3}" }
    
    tex.print(string.explode(table.concat{
    [[
        \begin{tikzpicture}
          \pgfplotsset{height=9cm}
          \begin{axis}[
    ]],
            'title=', chem[1], ',\n',
    [[
            xlabel= {\chemlambda Wavelenght (nm)},
            ylabel= {Molar Absorptivity},
            xmin= 350, xmax= 850,
            ymin= 0
          ]
          
            \addplot[white] 
                table[
                    col sep=comma, 
                    header=true, 
                    x index=0,
    ]], 
    '               y index=', 1, "\n",
    [[
                ] {file.csv};
            
          \end{axis}
          \end{tikzpicture}
    ]]
    }, '\n'))

\end{luacode*}

\end{document}

相关内容