如何知道表格环境中声明的列数?

如何知道表格环境中声明的列数?

是否有一个参数或方法可以知道有多少已声明tabular给定或有多少个列array

我需要第一次使用后才知道\\

在此处输入图片描述

主要目标是让表格的每个单元格的每个角上都有一个标记,我实际上知道该怎么做。但为此,我使用了一个以列数为参数的命令。我更喜欢自动获得此参数。

\documentclass{article}
\usepackage{array,xparse}

\NewDocumentEnvironment{TikzTable}{md<>O{c}m}{%
\IfNoValueTF{#2}{%
    \begin{#1}[#3]{#4}}{%
    \begin{#1}{#2}[#3]{#4}}
}{\end{#1}}


\begin{document}
\begin{TikzTable}{tabular}[b]{clrm{3cm}}\hline
a&b&c& 4 columns \\% At this point
\hline
1&1&1&1\\
\end{TikzTable}bob

\end{document}

答案1

您可以计算生成的前导码&中的\halign

在此处输入图片描述

\documentclass{article}
\usepackage{array,xparse}

\NewDocumentEnvironment{TikzTable}{md<>O{c}m}{%
\IfNoValueTF{#2}{%
    \begin{#1}[#3]{#4}}{%
    \begin{#1}{#2}[#3]{#4}}
}{\end{#1}}

\makeatletter
\def\zzz#1#2&#3{%
\ifx\zzz#3#1\expandafter\@gobble\else
\expandafter\@firstofone
\fi
{\zzz{\the\numexpr#1+1\relax}#3}}

\def\zz{\noalign{%
\xdef\nocols{\expandafter\zzz\expandafter1\@preamble&\zzz}%
}}
\makeatother

\begin{document}
\begin{TikzTable}{tabular}[b]{clrm{3cm}}
\zz
\hline
a&b&c& \nocols\ columns \\% At this point
\hline
1&1&1&1\\
\end{TikzTable}bob

\end{document}

答案2

使用与 David 相同的想法,但使用更精美的expl3代码;这使得它\nocols可以在每个TikzTable环境中使用,但如果您需要嵌套这些表,则可以在尾随可选参数中自定义名称。

\documentclass{article}
\usepackage{array,xparse}

\NewDocumentEnvironment{TikzTable}{md<>O{c}mO{\nocols}}
 {%
  \IfNoValueTF{#2}
   {%
     \begin{#1}[#3]{#4}
   }{%
     \begin{#1}{#2}[#3]{#4}
   }%
  \noalign{\CountColumns{#5}}
 }
 {\end{#1}}

\ExplSyntaxOn
\NewDocumentCommand{\CountColumns}{m}
 {% count the number of & tokens in \@preamble
  \regex_count:nvN { \cT\& } { @preamble } \l_tmpa_int
  % they're one less than the columns
  \cs_gset:Npx #1 { \int_eval:n { 1 + \l_tmpa_int } }
 }
\cs_generate_variant:Nn \regex_count:nnN { nv }
\ExplSyntaxOff

\begin{document}

\begin{TikzTable}{tabular}[b]{clrm{3cm}}
\hline
a&b&c& This table has \nocols\ columns \\
\hline
1&1&1&1\\
\end{TikzTable}bob

\begin{TikzTable}{tabular}[b]{clrm{3cm}}[\foo]
\hline
a&b&c& This table has \foo\ columns \\
\hline
1&1&1&1\\
\end{TikzTable}bob

\end{document}

在此处输入图片描述

答案3

这是一个基于 LuaLaTeX 的解决方案。它可以处理tabulararraytabular*tabularxtabulary环境,以及TikzTable您在帖子中提出的环境。

最近遇到的tabular类环境的声明列数存储在名为 的 Lua 变量中num_cols。(请注意,无需手动执行任何操作即可获取每个tabular类环境的声明列数 - 计算完全自动完成。)要从 LaTeX 端访问此数字,代码提供了名为 的 LaTeX 宏\numcols

唯一的输入要求是所有\begin{tabular}...{<columnspec>}材料必须位于同一条线上。

请注意,代码设计用于处理诸如\begin{tabular} {@{} c >{$}c<{$} >{\raggedleft\arraybackslash\tt}p{1cm} @{}} \\列数为“3”的情况。解决方案还可以处理更复杂的列定义,例如*{6}{l}

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
%% next few lines from the OP's query
\usepackage{array,xparse}
\NewDocumentEnvironment{TikzTable}{md<>O{c}m}{%
\IfNoValueTF{#2}{%
    \begin{#1}[#3]{#4}}{%
    \begin{#1}{#2}[#3]{#4}}}{%
    \end{#1}}
\usepackage{tabularx,tabulary}

\usepackage{luacode} % for 'luacode' environment
\begin{luacode}
-- Define a global variable (num_cols), set up two 
-- Lua functions, and assign one of them to the    
-- 'process_input_buffer' callback.

-- Initialize counter variable
num_cols = 0 

-- The next function computes the number of columns from
-- contents of string 'zz'
function calc_nums ( zz ) 
    -- retain the first "{....}" substring
    zz = zz:gsub ( "^.-(%b{}).-$", "%1" )
    -- remove outermost pair of curly braces
    zz = zz:sub  ( 2 , -2 )    
    -- expand expressions such as "*{5}{l}" to "lllll"
    zz = zz:gsub ( "%*%s-{(%d-)}%s-(%b{})" , 
                      function ( y , z )
                         z = z:sub ( 2 , -2 )
                         return string.rep ( z , y ) 
                      end )
    -- omit all stuff in curly braces
    zz = zz:gsub ( "%b{}" , "" ) 
    -- some more characters to ignore
    zz = zz:gsub ( "[@!|><%s%*]" , "" ) 
    -- Number of remaining chars in "zz" is the number
    -- of columns in the tabular-like environment.
    num_cols = string.len ( zz ) 
end

-- Next the main Lua function. Scan all input lines. 
-- If we detect start of a tabular-like env., lop off 
-- the prefix and pass the remainder of the input line 
-- to the 'calc_nums' function to determine number of cols.
-- ("%s-" means "0 or more instances of whitespace")
function get_col_spec ( s )
  local zz
  if string.find ( s , "\\begin.-{tabular}" ) then
     zz = s:gsub ( "^.-\\begin.-{tabular}" , "" )
     calc_nums ( zz )
  elseif string.find ( s , "\\begin%s-{array}" ) then
     zz = s:gsub ( "^.-\\begin%s-{array}" , "" )
     calc_nums ( zz )
  elseif string.find ( s , "\\begin%s-{tabular.}" ) then
     zz = s:gsub ( "^.-\\begin%s-{tabular.}%s-%b{}" , "" )
     calc_nums ( zz )
  end
  -- Do nothing if no match occurred.
end

-- Finally, assign 'get_col_spec' to the LuaTeX
-- 'process_input_buffer' callback.
luatexbase.add_to_callback( "process_input_buffer", 
    get_col_spec, "get_cols" )
\end{luacode}
%% LaTeX-side code: a macro to print out the number of columns
\newcommand\numcols{\directlua{tex.sprint(num_cols)}}

\begin{document}

%% Example 1
   \begin{tabular} [b] { | * {6} { m{4mm }|} p { 12mm }|} \multicolumn{3}{@{}l}{\numcols\ columns} 
   \\ \hline a & b & c & d & e & f & g \\ \hline
   \end{tabular}

\bigskip
%% Example 2
\begin{tabular} {@{} c *{2}{>{$}c<{$}} >{\raggedleft\arraybackslash\tt}p{3cm} @{}} 
\hline
a & b & c & \numcols\ columns\\ 
\hline
\end{tabular}

\bigskip
%% Example 3: the 'TikzTable' case
aaa\begin{TikzTable}{tabular}[b]{@{}cllrm{1.55cm}@{}}\hline
a&b&c&d& \numcols\ columns \\
\hline
1&1&1&1&1\\
\hline
\end{TikzTable}zzz

\bigskip
%% Examples 4 to 6: array, tabular*, and tabularx
$\begin{array}{@{}*{6}{c}@{}} \hline a & b & c & d & e & \numcols \\ \hline \end{array}$

\bigskip
\begin{tabular*}{0.5\textwidth}{@{\extracolsep{\fill}}*{7}{l}@{}} \hline
z & y & x & w & v & u & \numcols\\ \hline
\end{tabular*}

\bigskip
\begin{tabularx}{0.7\textwidth}{@{}l*{8}{>{\centering\arraybackslash}X}r@{}} \hline
z & y & x & w & v & u & t & s & r & \numcols\\ \hline
\end{tabularx}

\end{document}

相关内容