2

I am trying to create a tabular environment that captures the contents of table cells for an associated Lua module. The Lua module will then reformat the tabular data and export as C/C++ and VHDL source files to minimize transcription errors from the pdf design specification.

This example preamble defines a couple of macros to capture the cell data:

\documentclass{article}

\usepackage{array}
\usepackage{luacode}

%
% Capture a tablular cell's contents.
% The \endCell token serves as an end-of-cell marker and is never defined.
%
\long\def\startCell#1\endCell{%
    % This normally calls a function in a separate Lua module.
    % Just print the cell contents to stdout for this example.
    \luadirect{print("Cell ***" .. [==[#1]==] .. "***")}%
    % Then put the original cell contents back into the TeX stream.
    #1%
}

%
% This macro normally calls a Lua function in a separate module to process the
% cell data captured in the current row. Print to stdout for testing instead.
%
\newcommand\processRow{\luadirect{print("=== End of row ===")}}

A tabular environment (using the array package) then captures columns 2 and 3:

\begin{document}

\begin{tabular}{
    l % Don't capture data from the first column.
    >{\startCell}l<{\endCell}
    >{\startCell}l<{\endCell\processRow}
}
    1 & 2 & 3 \cr
    4 & 5 & 6 \cr
    7 & 8 & 9 \cr
\end{tabular}

\end{document}

Processing with lualatex shows the expected cell captures for columns 2 and 3 in the terminal:

...
Cell ***\ignorespaces 2 \unskip ***
Cell ***\ignorespaces 3 \unskip ***
=== End of row ===
Cell ***\ignorespaces 5 \unskip ***
Cell ***\ignorespaces 6 \unskip ***
=== End of row ===
Cell ***\ignorespaces 8 \unskip ***
Cell ***\ignorespaces 9 \unskip ***
=== End of row ===
...

The table in the pdf output is also correct:
pdf output

The problem: This doesn't work if the \\ macro is used in place of the \cr macro to end rows. Using a table body of

    1 & 2 & 3 \\
    4 & 5 & 6 \\
    7 & 8 & 9 \\

captures one cell, but then fails:

...
Cell ***\ignorespaces 2 \unskip ***

! Use of \@@array doesn't match its definition.
\@ifnextchar ... \reserved@d =#1\def \reserved@a {
                                                  #2}\def \reserved@b {#3}\f...

l.32     4 &
           5 & 6 \\
?

Commenting out \usepackage{luacode} and the \luadirect references results in a slightly different error, which is identical under both lualatex and pdflatex:

...
! Misplaced \cr.
\reserved@c ->\ifnum 0=`{}\fi \cr 

l.32     4 &
           5 & 6 \\
? 

Using a similar but non-capturing tabular preamble does not generate the error:

    l
    >{\relax}l<{\relax}
    >{\relax}l<{\relax}

The lualatex version is as follows:

$ lualatex --version
This is LuaTeX, Version 1.07.0 (TeX Live 2018)

Using \cr to end rows will probably work for this application, but why does this cell-capturing logic break the \\ macro? Is there a better way to capture tabular cell data for a Lua script?

2
  • Welcome to TeX-SE! Are you aware of the collcell package?
    – user121799
    Jun 21, 2019 at 6:05
  • @marmot: No, I was not aware of collcell. It looks pretty close to what I am trying to do and will try it out! Jun 21, 2019 at 6:13

1 Answer 1

4

I will be happy to delete this but using collcell seems to solve your problem.

\documentclass{article}
\usepackage{array}
\usepackage{collcell}
\usepackage{luacode}
\newcommand\processRow{\luadirect{print("=== End of row ===")}}
\newcommand\mymacroE[1]{\luadirect{print("Cell ***" .. [==[#1]==] .. "***")}#1}
\newcommand\mymacroF[1]{\mymacroE{#1}\processRow}
\newcolumntype{E}{>{\collectcell\mymacroE}c<{\endcollectcell}}
\newcolumntype{F}{>{\collectcell\mymacroF}c<{\endcollectcell}}
\begin{document}
\begin{tabular}{
    l % Don't capture data from the first column.
    EF
}
    1 & 2 & 3 \\
    4 & 5 & 6 \\
    7 & 8 & 9 \\
\end{tabular}
\end{document}
1
  • Very nice! This approach also removes the superfluous tokens that showed up in the cell data with my attempt. Jun 21, 2019 at 6:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .