0

Apologies if this is a trivial problem, I've seen a lot of similar posts, but i have not been able to solve this.

Setup:

I have created a table based on this answer. I have created a function for defining a section to reference and calling \input based on the provided path. (based on the first true/false entry) - in both cases i add the data to the table, it's just a question of showing the path to the file or a clickable reference.

\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
}
  • Note: testLabel/Ref are just wrapping label/ref.
  • Note: curTestName+curTestFilePath are set so I can reference them in the inserted file.

Usage

This works for manual entries ie. \testDefine{false}{23.3}{someName}{validPathToFile}

But not for entries from a database file: db.csv

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

Reading via datatool package:

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

And so my question is why - where am i missing some expansion?

Attempts

I have read several posts in here and tried using \expandafter, \Expand, \edef and \NewDocumentCommand accordingly to force the expansion prior to the \testDefine call but to no avail. I suspect it's the mixture of boolean logic with the expansion which might complicate things as i often get an error about that - but I hope someone in here has a nice solution!

  • Note: The solution must run in overleaf!
yo'
  • 51,322
Malle
  • 3
  • 2

1 Answers1

0

Overleaf is not really an issue: Overleaf is just a nice web interface for maintaining .tex-input-files. For compiling documents Overleaf uses the TeX distribution TeX Live. In the menu of Overleaf you can select which TeX Live release to use for compiling (TeX Live 2023, TeX Live 2022, TeX Live 2021 etc.)


With \DTLforeach* every iteration is done within its own local scope/group.

With the \DTLforeach*-loop you might need to toplevel-expand the macros which are placeholders for entries in the fields of database records.

As you did not deliver a minimal complete compilable reproducible and verifiable example, I cannot judge whether every iteration being done in its own local scope does matter.

If the local scope doesn't matter, you can probably do

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

Or

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

If the local scope does matter, you can probably accumulate stuff in a scratch-token-register:

\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

Or

\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

Or accumulate stuff in a scratch-macro:

\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

Or

\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
Ulrich Diez
  • 28,770