如何在函数调用之前从 DLTforeach 扩展

如何在函数调用之前从 DLTforeach 扩展

如果这是一个小问题,我深感抱歉,我已经看到很多类似的帖子,但我无法解决这个问题。

设置:

我已经基于此创建了一个表格回答。我创建了一个函数,用于定义要引用的部分并\input根据提供的路径进行调用。(基于第一个真/假条目)——在这两种情况下,我都会将数据添加到表中,这只是显示文件路径或可点击引用的问题。

\newcommand{\testDefine}[4]{
    \setboolean{enableTest}{#1}
    \ifthenelse{\boolean{enableTest}}{      %If enabled - add section, create label, add table entry, set curTestName, set curTestFilePath, insert test file
        \section{#3}\testLabel{#4}
        \addtotable{#1,#2,#3,\testRef{#4}}
        \renewcommand\curTestName{#3}
        \renewcommand\curTestFilePath{#4}
        % \textbf{#4}
        \input{#4}
    }{\addtotable{#1,#2,#3,#4}}   %else - add table entry
}
  • 注意:testLabel/Ref 只是包装标签/参考。
  • 注意:设置了 curTestName+curTestFilePath,以便我可以在插入的文件中引用它们。

用法

这适用于手动输入。\testDefine{false}{23.3}{someName}{validPathToFile}

但不适用于数据库文件中的条目:db.csv

To Test,Latest,Test Name, Reference
false,23.1,someName,validPathToFile

通过 datatool 包读取:

\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{   % call each iteration:
    \testDefine{\enabled}{\latest}{\testName}{\reference}
}

所以我的问题是为什么——我在哪里缺少一些扩展?

尝试

我读过这里的几篇文章,并尝试使用、和\expandafter相应\Expand地在调用之前强制扩展,但无济于事。我怀疑这是布尔逻辑与扩展的混合,这可能会使事情变得复杂,因为我经常会遇到这样的错误——但我希望这里有人有一个很好的解决方案!\edef\NewDocumentCommand\testDefine

  • 注意:解决方案必须在 overleaf 中运行!

答案1

Overleaf 并不是一个真正的问题:Overleaf 只是一个用于维护 .tex 输入文件的漂亮 Web 界面。对于编译文档,Overleaf 使用 TeX 发行版 TeX Live。在 Overleaf 的菜单中,您可以选择使用哪个 TeX Live 版本进行编译(TeX Live 2023、TeX Live 2022、TeX Live 2021 等)。


每次迭代都\DTLforeach*在其自己的本地范围/组内完成。

使用\DTLforeach*-loop 您可能需要顶层扩展宏,这些宏是数据库记录字段中条目的占位符。

由于您没有提供最小完整、可编译、可重现和可验证的示例,因此我无法判断在其自身本地范围内进行的每次迭代是否重要。

如果本地范围不重要,你可以这样做

\newcommand\PassFirstToSecond[2]{#2{#1}}%
\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \expandafter\PassFirstToSecond\expandafter{\reference}{%
    \expandafter\PassFirstToSecond\expandafter{\testName}{%
      \expandafter\PassFirstToSecond\expandafter{\latest}{%
        \expandafter\PassFirstToSecond\expandafter{\enabled}{%
          \testDefine
        }%
      }%
    }%
  }%
}%

或者

\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \expanded{%
    \unexpanded{\testDefine}%
    {\unexpanded\expandafter{\enabled}}%
    {\unexpanded\expandafter{\latest}}%
    {\unexpanded\expandafter{\testName}}%
    {\unexpanded\expandafter{\reference}}%
  }%
}

如果本地范围确实很重要,那么您可能可以在临时令牌寄存器中积累东西:

\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newtoks\scratchtoks
\csname @ifdefinable\endcsname\stopromannumeral{\chardef\stopromannumeral=`\^^00}%
\global\scratchtoks={}%
\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \global\scratchtoks\expandafter=\expandafter{%
    \the\expandafter\scratchtoks
    \romannumeral
    \expandafter\PassFirstToSecond\expandafter{\reference}{%
      \expandafter\PassFirstToSecond\expandafter{\testName}{%
        \expandafter\PassFirstToSecond\expandafter{\latest}{%
          \expandafter\PassFirstToSecond\expandafter{\enabled}{%
            \stopromannumeral\testDefine
          }%
        }%
      }%
    }%
  }%
}%
\the\scratchtoks

或者

\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newtoks\scratchtoks
\global\scratchtoks={}%
\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \global\scratchtoks\expandafter=\expandafter{%
    \the\expandafter\scratchtoks
    \expanded{%
      \unexpanded{\testDefine}%
      {\unexpanded\expandafter{\enabled}}%
      {\unexpanded\expandafter{\latest}}%
      {\unexpanded\expandafter{\testName}}%
      {\unexpanded\expandafter{\reference}}%
    }%
  }%
}%
\the\scratchtoks

或者在临时宏中积累内容:

\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\scratchmacro{}%
\csname @ifdefinable\endcsname\stopromannumeral{\chardef\stopromannumeral=`\^^00}%
\gdef\scratchmacro{}%
\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \xdef\scratchmacro{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\scratchmacro
      \romannumeral
      \expandafter\PassFirstToSecond\expandafter{\reference}{%
        \expandafter\PassFirstToSecond\expandafter{\testName}{%
          \expandafter\PassFirstToSecond\expandafter{\latest}{%
            \expandafter\PassFirstToSecond\expandafter{\enabled}{%
              \stopromannumeral\testDefine
            }%
          }%
        }%
      }%
    }%
  }%
}%
\scratchmacro

或者

\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\scratchmacro{}%
\gdef\scratchmacro{}%
\DTLforeach*{testDb}% database label
{\enabled=To Test,\latest=Latest,\testName=Test Name, \reference=Reference}
{% call each iteration:
  \xdef\scratchmacro{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\scratchmacro
      \expanded{%
        \unexpanded{\testDefine}%
        {\unexpanded\expandafter{\enabled}}%
        {\unexpanded\expandafter{\latest}}%
        {\unexpanded\expandafter{\testName}}%
        {\unexpanded\expandafter{\reference}}%
      }%
    }%
  }%
}%
\scratchmacro

相关内容