1

I am facing a situation where I am somewhat faced with the modular and conditional assembly of a table which prevents the \begin{} and \end{} definitions from remaining in the same local context. Confusing yes, (see code at end of question), but I don't think this part is all that critical. It is merely the nature of the restriction, which produces the problem that has been described elsewhere, namely: Too long vertical lines in table

This question provides excellent screen shots that describes the problem (i.e. vertical lines of a table extending past the last row) although my table doesn't look much like it or those produced in the accepted answer.

My MWE is here:

\documentclass{article}

\usepackage{xparse}


\usepackage{environ,longtable,threeparttablex,booktabs,multirow,array,adjustbox,supertabular}% table adjustment packages
% change spacing/padding of long table:  https://tex.stackexchange.com/questions/5683/how-to-remove-top-and-bottom-whitespace-of-longtable
\setlength{\LTpre}{0pt}
\setlength{\LTpost}{0pt}

% Wrapping text in multicolumn:  https://tex.stackexchange.com/questions/115668/wrapping-text-in-multicolumn
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
%https://tex.stackexchange.com/questions/70919/vertical-aligning-in-longtable-environment
%\adjustbox{valign=t}{}
%\raisebox{\normalbaselineskip-\height}{#6} & \multicolumn{2}{L{11cm}}{#7}
% changed m to p instead

\makeatletter
    \newcommand\eatpar{\@ifnextchar\par{\expandafter\eatpar\@gobble}\relax}
\makeatother

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn
% this one can't be a held in a local variable because the table paramaters are external
\DeclareDocumentCommand{\TableAssembly}{ m m }{%
    #1 & #2 \\%
}%

\NewDocumentCommand{\BuildTablePortion}{ O{R{2.5cm} | L{12.25cm}} m }%
{%
    \seaton_BuildTablePortion:nn { #1 }{ #2 }%
}%

\cs_new:Npn \seaton_BuildTablePortion:nn #1 #2 %
{%
    \str_case:nnF { #2 }{%
        {START}{%
            \begin{ThreePartTable}%
                \begin{TableNotes}[para,flushleft]%
                \end{TableNotes}%
                \renewcommand\multirowsetup{\raggedleft}%
                \begin{longtable}[l]{#1}%
                }%
                {END}{%
                    \eatpar%
                    %\\\insertTableNotes%
                    \let\\=\relax%
                \end{longtable}%
            \end{ThreePartTable}%
        }%
        % other possible strings
    }{ Failed to recognize instruction string #2}%
}%
\ExplSyntaxOff

\begin{document}
    \BuildTablePortion{START}
        \TableAssembly{1}{2}
        \TableAssembly{1}{3}
    \BuildTablePortion{END}
\end{document}

There is a comment in response to this answer here: https://tex.stackexchange.com/a/61879/69378 that I would like to understand a bit more about in order to properly address the issue.

When you have a newline after \hline and before \end{tabular} TeX assumes you want to add a new row to the table, but upon detecting no data, ends the table. Just remove the newline and you should be set.

Pretty self explanatory, but because the code I am being given to work with is using macros to create the table, fill the table, and close the table, I cannot use this work around of placing all declarations on the same line.

i.e.

\hline \end{longtable} \end{ThreePartTable}%

instead of

\hline%
\end{longtable}%
\end{ThreePartTable}%

I did some reading and to the best of my applications I thought \let\\=\relax%or a new command like \newcommand\eatpar{\@ifnextchar\par{\expandafter\eatpar\@gobble}\relax} might help.

I tried placing them in virtually every permutation relative to the table close block and even in the table population command so I am quite sure there is something that supersedes these manipulations of the relax command that I am unaware of...

The linked question/answer/comments are a few years old, is the table environment really (or still) this sensitive to new lines?

  • This comment (and the answer that it is under) are wrong in all normal contexts (unless \obeylines or \verbatim or similar constructs are in force) – David Carlisle Nov 9 '15 at 7:40
  • 1
    The table environments have never been sensitive to newlines in the source (they are reported to the macro layer as space (for one) or \par (for two) never as a newline. As always, your question would be much easier to answer if you provided a complete small document that demonstrated the problem. the "workarounds" that you mention of having or not having line ends will make no difference so it is hard to guess what problem this is asking about, with no example provided. – David Carlisle Nov 9 '15 at 7:45
  • You are using Expl3 syntax so none of the % at ends of lines are needed. presumably if you are getting a spurious cell on the last row causing vertical lines then \insertTableNotes is generating that, but you don't show its definition. – David Carlisle Nov 9 '15 at 9:02
  • @DavidCarlisle Thanks for looking at this. Now that I am back on the computer with my source code I have update the question with a MWE. I already tried removing the \\\insertTableNotes but the problem persists (as chosen to present in my MWE. Also, the extra `\` before the call seems necessary or I get an align error... – EngBIRD Nov 9 '15 at 15:34
2

You need your main switch to be expandable so I use \DeclareExpandableDocumentCommand and removed \let\\\relax and \eatpar which (a) aren't expandable and (b) can only do harm.

this works

\documentclass{article}

\usepackage{xparse}


\usepackage{environ,longtable,threeparttablex,booktabs,multirow,array,adjustbox,supertabular}% table adjustment packages
% change spacing/padding of long table:  http://tex.stackexchange.com/questions/5683/how-to-remove-top-and-bottom-whitespace-of-longtable
\setlength{\LTpre}{0pt}
\setlength{\LTpost}{0pt}

% Wrapping text in multicolumn:  http://tex.stackexchange.com/questions/115668/wrapping-text-in-multicolumn
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
%http://tex.stackexchange.com/questions/70919/vertical-aligning-in-longtable-environment
%\adjustbox{valign=t}{}
%\raisebox{\normalbaselineskip-\height}{#6} & \multicolumn{2}{L{11cm}}{#7}
% changed m to p instead

\makeatletter
    \newcommand\eatpar{\@ifnextchar\par{\expandafter\eatpar\@gobble}\relax}
\makeatother

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn
% this one can't be a held in a local variable because the table paramaters are external
\DeclareDocumentCommand{\TableAssembly}{ m m }{
    #1 & #2 \\
}

\DeclareExpandableDocumentCommand{\BuildTablePortion}{ O{R{2.5cm} | L{12.25cm}} m }
{
    \seaton_BuildTablePortion:nn { #1 }{ #2 }
}

\cs_new:Npn \seaton_BuildTablePortion:nn #1 #2 
{
    \str_case:nnF { #2 }{
        {START}{
            \begin{ThreePartTable}
                \begin{TableNotes}[para,flushleft]
                \end{TableNotes}
                \renewcommand\multirowsetup{\raggedleft}
                \begin{longtable}[l]{#1}
                }
                {END}{
                \insertTableNotes
                \end{longtable}
            \end{ThreePartTable}
        }
         other possible strings
    }{ Failed to recognize instruction string #2}
}
\ExplSyntaxOff

\begin{document}
    \BuildTablePortion{START}
        \TableAssembly{1}{2}
        \TableAssembly{1}{3}
    \BuildTablePortion{END}
\end{document}

although you may need to conditionally do \\ if there are in fact any notes (it depends how that is defined)

No part of this is in any way related to newlines in the source file.

  • why introduce non-latex syntax \BuildTablePortion{START}...\BuildTablePortion{END} instead of simply making this an environment? \begin{TablePortion}... \end{TablePortion} ??? – David Carlisle Nov 9 '15 at 15:48
  • Thanks! Your solution of course works, and you are 110% right that I should be doing this as an environment that accepts an argument. I have converted my command to DeclareDocumentEnvironment but I think I am getting an error (I think because of expandability). Originally I needed \\\insertTableNotes, then with your expandable solution I don't need the ``, but in an environment it goes back to throwing a missing noalign error. Can I manually force the environment to "expand"? – EngBIRD Nov 9 '15 at 21:07
  • @EngBIRD without an example i can't guess what you have changed, but environment form will be expandable if the underlying command is, so it's teh same it will be expandable unlessit has optional arguments in which case it needs to be defined with \DeclareExpandable... – David Carlisle Nov 10 '15 at 8:03
  • Thanks, even without an example you hit the nail on the head, I am using optional arguments, but I already tried to initialize with \DeclareExpandableDocumentEnvironment, but there is no such command or at least that is how I interpret the error: ! Undefined Control Sequence – EngBIRD Nov 10 '15 at 15:15
  • @EngBIRD you can define the environment foo as \foo and \endfoo using two instances of \DeclareExpandableDocumentCommand – David Carlisle Nov 10 '15 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.