3

I have a syntax highlighting program that outputs LaTeX code. The generated code can be used in regular text or in a tabular to do more advanced layouts.

The generated LaTeX output includes \my@eol at the end of each line, which is essentially defined as \par. Of course, this works in regular text but not in tables, so I'd like to conditionally use \cr if I'm in a table.

How do I check if I'm currently in an alignment (tabular, array, halign, etc.)?

Originally I defined my@eol in terms of \\, which worked in tabular as well, but based on the comment of Barbara Beeton in When to use \par and when \\, \newline, or blank lines I changed to using \par. Now I need to find a way to switch between \par and \cr as needed.

Here's what I've tried: I looked at the implementation of tabular, and noticed that it redefined \par and \\ (the latter to \@arraycr, which eventually expands to \cr), so one solution would be to check whether \\ or \par has been redefined, but that sounds very brittle. I read the documentation of tabular as well.
Then I looked at various sources of documentation to see if TeX has any sort of conditional (like \ifvmode) for alignments, but I couldn't find one.
Finally I also looked at the implementation of \halign (it calls init_align) in the source code of TeX, but I didn't manage to spot anything directly relevant (it seems to just change to vmode and set up align_state when entering an halign, but I'm not sure how to access align_state from TeX).

3
  • Are you free to use LuaLaTeX?
    – Mico
    Aug 3, 2020 at 5:49
  • \\ can change meaning (and do different things) in the tabular depending on the columntype, and if you use e.g. \centering. If you want to be sure to end a tabular row you should better use \tabularnewline. Aug 3, 2020 at 9:44
  • 1
    @Mico not really, but I'm curious to know what a LuaLaTeX solution might look like!
    – Clément
    Aug 3, 2020 at 12:58

2 Answers 2

2

To see what environment you are currently in you can look at the value of \@currenvir: inside a tabular or array environment etc it will be tabular or array, respectively. This will not work for \halign. Nested environments will not be detected either, but that's probably OK in your use-case.

To make these tests I think that the easiest approach is to use \str_case:onF from LaTeX3. The code below defines a command \IfInTableTF that you use as:

\IfInTableTF{true code}{false code}

The name is perhaps not the best name since array, tabular and tabularx environments all test positive. All the command does is define a new boolean and then use \str_case:onF to turn it on if we are in one of our favourite environments and turn it off otherwise. Here is the code:

\documentclass{article}
\usepackage{expl3}
\makeatletter
\ExplSyntaxOn
\bool_new:N \l_clement_if_in_table_bool% a boolean for table manners
\newcommand\IfInTableTF[2]
{
  \str_case:onF { \@currenvir }% check current environment
  {
      {array}    { \bool_set_true:N \l_clement_if_in_table_bool  }
      {tabular}  { \bool_set_true:N \l_clement_if_in_table_bool  }
      {tabularx} { \bool_set_true:N \l_clement_if_in_table_bool  }
  }{               \bool_set_false:N \l_clement_if_in_table_bool }
  \bool_if:NTF \l_clement_if_in_table_bool {#1} {#2}
}
\ExplSyntaxOff
\makeatother

\begin{document}

  \IfInTableTF{in table}{Not in table}

  \begin{tabular}{c}
    one \\
    two \\
    \IfInTableTF{in table}{Not in table}
  \end{tabular}

  \[
    \begin{array}{c}
      1 \\
      2 \\
      \IfInTableTF{in array}{Not in array}
    \end{array}
  \]

  \IfInTableTF{in table}{Not in table}

\end{document}

and here is the expected output:

enter image description here

2

The test \ifvoid\@arstrutbox seems to work well at detecting being inside a tabular or array no matter how deeply nested below that alignment.

\newcommand\IfInTableTF{\ifvoid\@arstrutbox
  \expandafter\@secondoftwo\else
  \expandafter\@firstoftwo\fi}

Other candidates could be \ifx\\\@arraycr but that can be fooled by \raggedright; and \@ifundefined{@preamble} but some packages leave an empty definition when not in use.

(The tabu package does global setting of \@arstrutbox but appears to explicitly set it void when not in use.)

You must log in to answer this question.

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