根据前两个问题,我发现了另一个问题,但我不知道这可能是一个问题。
问题 1:条件复杂列类型
问题2:通用表定义
但我失败了。如果我调用该命令一次,一切都很好。也许 tablespecification 命令中存在一些错误?
\documentclass{scrreprt}
\usepackage[T1]{fontenc} % Use 8-bit encoding that has 256 glyphs
\usepackage[utf8]{inputenc} % Uses the utf8 input encoding
\usepackage{graphicx} % Required for including images
\usepackage{booktabs,array,ragged2e,multirow,colortbl}
\usepackage[table]{xcolor}
\usepackage{datatool}
\usepackage{longtable} % can be commented out, approach is an very generic method of tablespec
\providecommand{\conta}{\xspace\RIGHTarrow\xspace}
\newcolumntype{M}[1]{>{\hspace{0pt}\raggedright\arraybackslash}m{#1}}
\newcolumntype{Z}[9]{
!{\color{#6}\vrule width #4 #7}
>{\ifnum\pdfstrcmp{#2}{left}=0 \raggedright\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{center}=0 \centering\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{right}=0 \raggedleft\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{zero}=0 \fi
\columncolor{#3}
}
p{#1 #8}
!{\color{#6}\vrule width #5 #7}
}
\makeatletter
\newcommand{\settablespec}[2]{%
\toks@={}%
\@tfor\next:=#2\do{
\toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@\next}
}
\edef#1{\the\toks@}
}
\newcommand{\tablebegin}[2]{
\def\next{\begin{#1}}
\expandafter\next\expandafter{#2}
}
\makeatother
\xdefinecolor{mywhite}{rgb}{1,1,1}
\xdefinecolor{myblack}{rgb}{1,1,1}
\FPupn{vlinedistance}{0.2}
\FPupn{hlinedistance}{0.2}
\FPupn{outerlinedistance}{0.00}
\begin{document}
\providecommand{\hlttextacs}{2.2}
\providecommand{\hlttextbcs}{2.3}
\providecommand{\hlttextccs}{2.2}
\providecommand{\bheaderalacs}{left}
\providecommand{\bheaderalbcs}{center}
\providecommand{\bheaderalccs}{right}
\providecommand{\AAastart}{}
\providecommand{\AAasingle}{}
\providecommand{\AAb}{}
\providecommand{\AAc}{}
\providecommand{\AAbend}{}
\providecommand{\AAcend}{}
\renewcommand{\AAastart}{Z{\hlttextacs}{\bheaderalacs}{myblack}{\outerlinedistance}{0}{myblack}{em}{cm}{text}}
\renewcommand{\AAasingle}{Z{\hlttextacs}{\bheaderalacs}{myblack}{\outerlinedistance}{\outerlinedistance}{myblack}{em}{cm}{text}}
\renewcommand{\AAb}{Z{\hlttextbcs}{\bheaderalbcs}{myblack}{\vlinedistance}{0}{myblack}{em}{cm}{text}}
\renewcommand{\AAc}{Z{\hlttextccs}{\bheaderalccs}{myblack}{\vlinedistance}{0}{myblack}{em}{cm}{text}}
\renewcommand{\AAbend}{Z{\hlttextbcs}{\bheaderalbcs}{myblack}{0}{\outerlinedistance}{myblack}{em}{cm}{text}}
\renewcommand{\AAcend}{Z{\hlttextccs}{\bheaderalccs}{myblack}{0}{\outerlinedistance}{myblack}{em}{cm}{text}}
\providecommand{\mytablespec}[1]{
\ifnum#1=1%
\settablespec{\mytablespec}{%
\AAasingle%
}%
\else%
\fi%
\ifnum#1=2%
\settablespec{\mytablespec}{%
\AAastart%
\AAbend%
}%
\else%
\fi%
\ifnum#1=3%
\settablespec{\mytablespec}{%
\AAastart%
\AAb%
\AAcend%
}%
\else%
\fi%
}%
\mytablespec{2}
\def\mytabletype{longtable}
\tablebegin{\mytabletype}{\mytablespec}
A & CC \tabularnewline
$D$ & DD
\end{\mytabletype}
\mytablespec{2}
\def\mytabletype{longtable}
\tablebegin{\mytabletype}{\mytablespec}
\specialrule{0.00em}{0.0em}{\hlinedistance em}%
A & B \tabularnewline
C & D
\end{\mytabletype}
\end{document}
问题 1:有人能发现这个 bug 吗?问题 2:有没有什么资源可以更深入地了解 tex 代码,值得学习?
答案1
问题是第一次调用时\mytablespec
,\mytablespec
它本身被重新定义。因此,当您第二次调用它时,它具有新定义而不是旧定义。如果您重新定义宏,则不能继续使用其旧定义。它现在有了新定义,并且一次只能有一个定义。
通过选择不同的宏名可以轻松避免此问题。我使用的是\setmytablespec
而不是\mytablespec
。
由于您的定义即使在最好的情况下似乎也只会产生黑色矩形,因此我调整了代码以做一些更有趣的事情。
我也使这个例子变得更简约,尽管它可以进一步简化。
唯一真正重大的变化是
\newcommand{\setmytablespec}[1]{
...
而不是
\providecommand{\mytablespec}[1]{
...
我也在适用的地方进行了替换\newcommand
。\providecommand
应该\providecommand
真正用来定义后备定义,即您想要确保宏具有某些定义,即使它尚未设置。
\newcommand
如果因为宏名已被使用而失败,则会给出错误。在大多数情况下,这或\renewcommand
就是您想要的。
这不会在您的代码中引起任何问题,也\newcommand
不会在这种情况下暴露问题,因为\edef
正在执行覆盖。但我认为最好使用 LaTeX 提供的宏创建命令的正确变体,以便您确实会得到错误(\newcommand
如果宏已定义)、静默忽略(\providecommand
如果宏已定义)或静默重新定义(\renewcommand
如果宏已定义),视情况而定。似乎没有任何明显的理由静默忽略此处定义的宏的现有定义。
\documentclass{scrreprt}
\usepackage[T1]{fontenc} % Use 8-bit encoding that has 256 glyphs
\usepackage[utf8]{inputenc} % Uses the utf8 input encoding
\usepackage{booktabs,array}
\usepackage[table]{xcolor}
\usepackage{datatool}
\usepackage{longtable} % can be commented out, approach is an very generic method of tablespec
\newcommand{\conta}{\xspace\RIGHTarrow\xspace}
\newcolumntype{M}[1]{>{\hspace{0pt}\raggedright\arraybackslash}m{#1}}
\newcolumntype{Z}[9]{
!{\color{#6}\vrule width #4 #7}
>{\ifnum\pdfstrcmp{#2}{left}=0 \raggedright\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{center}=0 \centering\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{right}=0 \raggedleft\arraybackslash \fi
\ifnum\pdfstrcmp{#2}{zero}=0 \fi
\columncolor{#3}
}
p{#1 #8}
!{\color{#6}\vrule width #5 #7}
}
\makeatletter
\newcommand{\settablespec}[2]{%
\toks@={}%
\@tfor\next:=#2\do{
\toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@\next}
}
\edef#1{\the\toks@}
}
\newcommand{\tablebegin}[2]
{
\def\next{\begin{#1}}
\expandafter\next\expandafter{#2}
}
\makeatother
\FPupn{vlinedistance}{0.2}
\FPupn{hlinedistance}{0.2}
\FPupn{outerlinedistance}{0.00}
\begin{document}
\newcommand*{\hlttextacs}{2.2}
\newcommand*{\hlttextbcs}{2.3}
\newcommand*{\hlttextccs}{2.2}
\newcommand*{\bheaderalacs}{left}
\newcommand*{\bheaderalbcs}{center}
\newcommand*{\bheaderalccs}{right}
\newcommand{\AAastart}{Z{\hlttextacs}{\bheaderalacs}{cyan!50!blue!25}{\outerlinedistance}{0}{cyan!50!blue}{em}{cm}{text}}
\newcommand{\AAasingle}{Z{\hlttextacs}{\bheaderalacs}{blue!50}{\outerlinedistance}{\outerlinedistance}{blue}{em}{cm}{text}}
\newcommand{\AAb}{Z{\hlttextbcs}{\bheaderalbcs}{magenta!25}{\vlinedistance}{0}{magenta}{em}{cm}{text}}
\newcommand{\AAc}{Z{\hlttextccs}{\bheaderalccs}{green!50!black!25}{\vlinedistance}{0}{green!25!black}{em}{cm}{text}}
\newcommand{\AAbend}{Z{\hlttextbcs}{\bheaderalbcs}{yellow!30}{0}{\outerlinedistance}{orange}{em}{cm}{text}}
\newcommand{\AAcend}{Z{\hlttextccs}{\bheaderalccs}{blue!50!green!25}{0}{\outerlinedistance}{blue!50!green!75!black}{em}{cm}{text}}
\newcommand{\setmytablespec}[1]{
\ifnum#1=1%
\settablespec{\mytablespec}{%
\AAasingle%
}%
\fi%
\ifnum#1=2%
\settablespec{\mytablespec}{%
\AAastart%
\AAbend%
}%
\fi%
\ifnum#1=3%
\settablespec{\mytablespec}{%
\AAastart%
\AAb%
\AAcend%
}%
\fi%
}%
\setmytablespec{2}
\def\mytabletype{longtable}
\tablebegin{\mytabletype}{\mytablespec}
A & CC \tabularnewline
$D$ & DD
\end{\mytabletype}
\setmytablespec{2}
\def\mytabletype{longtable}
\tablebegin{\mytabletype}{\mytablespec}
\specialrule{0.00em}{0.0em}{\hlinedistance em}%
A & B \tabularnewline
C & D
\end{\mytabletype}
\setmytablespec{3}
\def\mytabletype{longtable}
\tablebegin{\mytabletype}{\mytablespec}
\specialrule{0.00em}{0.0em}{\hlinedistance em}%
A & B &E \tabularnewline
C & D &F
\end{\mytabletype}
\setmytablespec{1}
\def\mytabletype{tabular}
\tablebegin{\mytabletype}{\mytablespec}
\specialrule{0.00em}{0.0em}{\hlinedistance em}%
E \tabularnewline
F
\end{\mytabletype}
\end{document}