使用命令包装一行上的每个单元格

使用命令包装一行上的每个单元格

我想用一些宏来构造表格。我已经创建了一个具有可变列数的环境。其中一个宏应该创建一行没有垂直线的条目。我已经用过\multicolumn它了。它工作正常,但我必须写出所有多列调用,因此它只能用于一种大小。相反,我更喜欢像下面\lyrics这样执行命令。\chords

如何实现?我猜想需要进行某种解析或拆分,然后再进行包装和连接。这个答案用逗号分隔地址。我还没有找到用 & 符号分隔的方法。但如果可以分隔,我想从那时起某些循环就会起作用。

或者,我使用了如下描述的列样式方法这里。也许可以采取类似的方法。但显然命令\multicolumn不能在列本身之前保持未完成状态,然后在列之后完成。

我意识到,对于这个特定问题,另一种去除垂直线的方法就足够了,但我仍然认为以这种方式包装单元格是一个有趣的问题。因此,任何有关这两个问题的帮助都将不胜感激!


这是一个例子。

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[finnish]{babel}

\newenvironment{sheets}[1]{%
    \newcommand{\chords}[1]{##1 \\ \multicolumn{1}{l}{} \\[-1em]}
    \newcommand{\lyrics}[4]{\multicolumn{1}{l}{##1} & \multicolumn{1}{l}{##2} & \multicolumn{1}{l}{##3} & \multicolumn{1}{l}{##4} \\[0.5em]}
    \begin{tabular}{l*{\numexpr#1-1}{|l}}
}{\end{tabular}}

\begin{document}

\begin{sheets}{4}
    \chords{C & C & Am & G}
    \lyrics{Paada daa pa paada}{daa, pa paada}{daa paapa da da}{daa}
    \chords{C Dm & C & C G & C}
    \lyrics{Daa paada da paa da}{daa papaa paada}{da pa pa pa daa daa}{daa}
\end{sheets}

% I'd like to be able to write:
% \begin{sheets}{4}
%     \chords{C & C & Am & G}
%     \lyrics{Paada daa pa paada & daa, pa paada & daa paapa da da & daa}
%     \chords{C Dm & C & C G & C}
%     \lyrics{Daa paada da paa da & daa papaa paada & da pa pa pa daa daa & daa}
% \end{sheets}

\end{document}

它看起来是这样的。

示例图像

答案1

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
%\usepackage[finnish]{babel}

\makeatletter
%%----------------------------------------------------------------------
%% Exchange two arguments:
%%......................................................................
\newcommand\UD@exchange[2]{#2#1}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\expandafter\expandafter\@firstoftwo{ }{}%
  \@secondoftwo}{\expandafter\expandafter\@firstoftwo{ }{}\@firstoftwo}%
}%
%%----------------------------------------------------------------------
%% Expandable extraction of first item of ampersand-list:
%%......................................................................
%%
%% \UD@ExtractFirstAmpersandArg{<ampersand list>}
%%
%% yields:
%% 
%% <first item/first ampersand-delimited argument from ampersand-list>
%%
%% <ampersand-list> is considered a sequence of ampersand-delimited arguments.
%%
%% The <first item/first ampersand-delimited argument from ampersand list> 
%% will be extracted. The remainder of the <ampersand list> will be discarded.
%%
%% Due to \romannumeral0-expansion, the result will be delivered after
%% two expansion-steps/after having \UD@ExtractFirstAmpersandArg "hit" via
%% two \expandafter(-chains).
%%......................................................................
\newcommand\UD@gobbledot{}\def\UD@gobbledot.{}%
\newcommand\UD@gobbletoampersand{}\long\def\UD@gobbletoampersand#1&{}%
\newcommand\UD@removeampersand{}\long\def\UD@removeampersand#1&{#1}%
\newcommand\UD@RemoveFromAmpersandTillUD@SelDOm{}%
\long\def\UD@RemoveFromAmpersandTillUD@SelDOm#1&#2\UD@SelDOm{#1&}%
\newcommand\UD@ExtractFirstAmpersandArg[1]{%
  \romannumeral0%
  \UD@ExtractFirstAmpersandArgLoop{.#1&\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstAmpersandArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@gobbletoampersand#1}%
  {%
     \UD@exchange{ }{\expandafter\expandafter\expandafter}%
     \expandafter\UD@gobbledot\UD@removeampersand#1%
  }%
  {%
    \expandafter\UD@ExtractFirstAmpersandArgLoop
    \expandafter{\UD@RemoveFromAmpersandTillUD@SelDOm#1}%
  }%
}%
%%----------------------------------------------------------------------
%% Check whether argument contains ampersand which is not nested in
%% braces:
%%......................................................................
%% \UD@CheckWhetherNoAmpersand{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no ampersand>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains ampersand>}%
\newcommand\UD@CheckWhetherNoAmpersand[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@gobbletoampersand#1&}%
}%
%%----------------------------------------------------------------------
%% \lyricsb{<ampersand-list>}
%%
%% iterates on <ampersand-list> and wraps each element into
%% \multicolumn{1}{l}{<element>} and separates the calls to
%% \multicolumn by " & " and attaches " \\[0.5em]".
%%
%% E.g.,  \lyricsb{ A & B & C }
%% yields 
%% \multicolumn{1}{l}{ A } & \multicolumn{1}{l}{ B } & \multicolumn{1}{l}{ C }
%%
%% If you wish, you can move the definition of \lyricsb into the
%% definition of the sheets-environment.
%%......................................................................
\newcommand\lyricsb{\romannumeral0\lyricsAmpersandloop{ }}%
\newcommand\lyricsAmpersandloop[2]{%
   \UD@CheckWhetherNoAmpersand{#2}{%
      #1\multicolumn{1}{l}{#2} \\[0.5em]%
   }{%
     \expandafter\UD@exchange\expandafter{\expandafter{\UD@gobbletoampersand#2}}{%
       \expandafter\lyricsAmpersandloop\expandafter{%
         \romannumeral0\UD@exchange{ }{\expandafter\expandafter\expandafter}%
         \expandafter\UD@exchange
         \expandafter{%
         \expandafter{%
         \romannumeral0\UD@exchange{ }{\expandafter\expandafter\expandafter}%
         \UD@ExtractFirstAmpersandArg{#2}}}%
         {#1\multicolumn{1}{l}} & %
       }%
     }%
   }%
}%
%%----------------------------------------------------------------------
\makeatother

\newenvironment{sheets}[1]{%
    \newcommand{\chords}[1]{##1 \\ \multicolumn{1}{l}{} \\[-1em]}
    \newcommand{\lyrics}[4]{\multicolumn{1}{l}{##1} & \multicolumn{1}{l}{##2} & \multicolumn{1}{l}{##3} & \multicolumn{1}{l}{##4} \\[0.5em]}
    \begin{tabular}{l*{\numexpr#1-1}{|l}}%
}{\end{tabular}}

\begin{document}

\begin{sheets}{4}
    \chords{C & C & Am & G}
    \lyrics{Paada daa pa paada}{daa, pa paada}{daa paapa da da}{daa}
    \chords{C Dm & C & C G & C}
    \lyrics{Daa paada da paa da}{daa papaa paada}{da pa pa pa daa daa}{daa}
\end{sheets}

\bigskip    

% I hope I did everything correctly and you are able to write:
\begin{sheets}{4}
    \chords{C & C & Am & G}
    \lyricsb{Paada daa pa paada & daa, pa paada & daa paapa da da & daa}
    \chords{C Dm & C & C G & C}
    \lyricsb{Daa paada da paa da & daa papaa paada & da pa pa pa daa daa & daa}
\end{sheets}

\end{document}

在此处输入图片描述

相关内容