
다음 예에서는 환경의 자체 정의 카운터가 tabularx
"1"로 시작하지 않음을 보여줍니다. 항상 "1"로 시작하도록 명령을 정의하는 방법을 알 수 없습니다. 아이디어?
\documentclass{article}
\usepackage{enumitem}
\usepackage{cleveref}
\usepackage{etoolbox}
\usepackage{booktabs}
\usepackage{ltxtable}
\usepackage{ltablex}
\makeatletter\newcommand*{%
\CreateCounterIfNotExists}[1]{\begingroup%
\@ifundefined{c@#1}{\newcounter{#1}}{}%
\endgroup}\makeatother
\def\sdef#1{\expandafter\def\csname#1\endcsname}
\newcommand\requirement[3]{%
\CreateCounterIfNotExists{my#1}%
\sdef{themy#1}{#1\arabic{my#1}}%
\refstepcounter{my#1}%
\label{#2} #1\arabic{my#1}: #3%
}
\begin{document}
\requirement{A}{req:foo:a}{Starts with 1}
\requirement{A}{req:foo:b}{continues with 2}
\requirement{B}{req:hop:a}{Starts with 1}
\requirement{B}{req:hop:b}{continues with 2}
\begin{tabularx}{\textwidth}{lX}
\caption{Requirements}\\
\label{tbl:reqs}\\
\toprule
\textbf{Area}& \textbf{Description} \\\midrule
\requirement{C}{req:bar:A}{Starts with 3}
\requirement{C}{req:bar:B}{Continues with 4}
&
This should start with C1 \\\midrule
\end{tabularx}
\end{document}
답변1
tabularx
작업을 수행하는 동안에는 카운터를 정의할 수 없습니다 .
해결책은 필요한 것을 미리 정의 tabularx
하거나 파일을 사용하여 지연된 방식으로 수행하는 것입니다 .aux
.
\documentclass{article}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage{booktabs}
\usepackage{ltxtable}
\usepackage{ltablex}
\usepackage{cleveref}
\makeatletter
\newcommand\requirement[3]{%
\protected@write\@auxout{}{\string\CreateCounter{#1}}%
\@ifundefined{c@my#1}
{#1??: #3}
{\refstepcounter{my#1}\label{#2}#1\arabic{my#1}: #3}%
}
\newcommand{\CreateCounter}[1]{%
\@ifundefined{c@my#1}
{\newcounter{my#1}\global\@namedef{themy#1}{#1\arabic{my#1}}}
{}%
}
\AtEndDocument{\let\CreateCounter\@gobble}
\makeatother
\begin{document}
{\requirement{A}{req:foo:a}{Starts with 1}}
\requirement{A}{req:foo:b}{continues with 2}
\requirement{B}{req:hop:a}{Starts with 1}
\requirement{B}{req:hop:b}{continues with 2}
\noindent
\begin{tabularx}{\textwidth}{lX}
\caption{Requirements}\label{tbl:reqs}\\
\toprule
\textbf{Area}& \textbf{Description} \\
\midrule
\requirement{C}{req:bar:A}{Starts with 1}
\requirement{C}{req:bar:B}{Continues with 2} & This should start with C1 \\
\midrule
\end{tabularx}
\end{document}
처음 \requirement{X}
사용되면 번호가 생성되지 않지만 다음 LaTeX 실행 시에는 번호가 생성됩니다.
답변2
매크로 내에서 카운터를 선언해서는 안 되며, 서문에서 한 번만 선언하고 사용해야 합니다. 그런 다음 tabularx
시험 너비 설정을 수행할 때 그것에 대해 알고 그 값을 보존합니다.
\documentclass{article}
\usepackage{enumitem}
\usepackage{cleveref}
\usepackage{etoolbox}
\usepackage{booktabs}
\usepackage{ltxtable}
\usepackage{ltablex}
\newcounter{myA}\renewcommand\themyA{A\arabic{myA}}
\newcounter{myB}\renewcommand\themyB{B\arabic{myB}}
\newcounter{myC}\renewcommand\themyC{C\arabic{myC}}
\newcommand\requirement[3]{%
\refstepcounter{my#1}%
\label{#2}#1\arabic{my#1}: #3%
}
\begin{document}
\requirement{A}{req:foo:a}{Starts with 1}
\requirement{A}{req:foo:b}{continues with 2}
\requirement{B}{req:hop:a}{Starts with 1}
\requirement{B}{req:hop:b}{continues with 2}
\begin{tabularx}{\textwidth}{lX}
\caption{Requirements}\\
\label{tbl:reqs}\\
\toprule
\textbf{Area}& \textbf{Description} \\\midrule
\requirement{C}{req:bar:A}{Starts with 3}
\requirement{C}{req:bar:B}{Continues with 4}
&
This should start with C1 \\\midrule
\end{tabularx}
\end{document}
답변3
David Carlisle과 egreg가 언급한 솔루션에서와 같이 카운터를 정의하면 안 됩니다 on-the-fly
.
저는 실수로 인한 사용을 방지하기 위해 서문에서만 사용할 수 있는 \NewDocumentCounter
, \DeclareRequirement
, 명령을 제공하는 David Carlisle과 유사한 접근 방식을 사용했습니다 .DeclareRequirements
\documentclass{article}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage{booktabs}
\usepackage{ltxtable}
\usepackage{ltablex}
\usepackage{cleveref}
\usepackage{xparse}
\NewDocumentCommand{\NewDocumentCounter}{m}{%
\ifltxcounter{#1}{%
}{%
\typeout{Creating counter #1}
\newcounter{#1}%
}
}
\NewDocumentCommand{\DeclareRequirement}{m}{%
\NewDocumentCounter{my#1}%
\expandafter\renewcommand\csname themy#1\endcsname{#1\arabic{my#1}}
}%
\listgadd\reqlist{}
\NewDocumentCommand{\DeclareRequirements}{+m}{%
\forcsvlist{\listgadd\reqlist}{#1}
\forlistloop{\DeclareRequirement}{\reqlist}
}%
\makeatletter
\@onlypreamble{\NewDocumentCounter}
\@onlypreamble{\DeclareRequirement}
\@onlypreamble{\DeclareRequirements}
\makeatother
\DeclareRequirements{A,B,C} % Declare all requirement counters in a row ...
\newcommand\requirement[3]{%
\refstepcounter{my#1}%
\label{#2} #1\arabic{my#1}: #3%
}
\begin{document}
\requirement{A}{req:foo:a}{Starts with 1}
\requirement{A}{req:foo:b}{continues with 2}
\requirement{B}{req:hop:a}{Starts with 1}
\requirement{B}{req:hop:b}{continues with 2}
\begin{tabularx}{\textwidth}{lX}
\caption{Requirements}\\
\label{tbl:reqs}\\
\toprule
\textbf{Area}& \textbf{Description} \\\midrule
\requirement{C}{req:bar:A}{Starts with 3 no longer} %\themyC
\requirement{C}{req:bar:B}{Continues with 4 no longer} %\themyC
&
This should start with C1 \\\midrule
\end{tabularx}
\end{document}