TransWikia.com

Is there a way to check whether we're inside a table?

TeX - LaTeX Asked on May 3, 2021

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).

2 Answers

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
newcommandIfInTableTF[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

Answered by user30471 on May 3, 2021

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

newcommandIfInTableTF{ifvoid@arstrutbox
  expandafter@secondoftwoelse
  expandafter@firstoftwofi}

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.)

Answered by Donald Arseneau on May 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP