我对以下情况感到很沮丧:我正在编写一份文档,其中的需求以需求 ID 作为行首(我在枚举环境中使用这些需求)。我想在 DATATOOL 数据库中收集需求,并在文档末尾以表格形式输出这些需求。
无论我尝试什么,以下宏都可以正常工作,因为它会在枚举环境中添加具有正确需求 ID 的需求行,但是当我在最后显示表格时,它不会在“reqKey”列中添加输出需求 ID - 我怀疑对“\@reqID”变量访问的某些东西不起作用。
非常感谢您的帮助。
\DTLnewdb{reqs}
\DTLnewdbcolumn{reqs}{reqKey}
\DTLnewdbcolumn{reqs}{reqText}
...
\makeatletter
\newcommand\req@nomen@count[1]{%
\@ifundefined{c@#1}
{% the counter doesn't exist
\newcounter{#1}\setcounter{#1}{1}%
}
{% the counter exists
\stepcounter{#1}%
}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[2][0]{%
\req@nomen@count{#2}%
\ifthenelse{\equal{#1}{0}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{
\DTLnewrow{reqs}
\ifthenelse{\equal{#1}{0}}
{\renewcommand{\@reqID}{\req{#2}}}
{\renewcommand{\@reqID}{\req{#1}{#2}}}
\item[\textcolor{blue}{[\@reqID]}]#3%
\DTLnewdbentry{reqs}{reqKey}{\@reqID}
\DTLnewdbentry{reqs}{reqText}{#3}
}
\makeatother
...
\begin{document}
\begin{enumerate}
\itemReq{reqCategory}{Requirement text, can be lengthy}
\end{enumerate}
...
\DTLdisplaylongdb{reqs}
\end{document}
根据要求编辑我想分享一个最小调整(根据 esdd 的解决方案)的示例:
\documentclass{article}
\usepackage{enumitem}
\usepackage{fmtcount}
\usepackage{datatool}
\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}
\makeatletter
% macro creating a new latex counter for every new entitiy name and requirement
\newcommand\req@nomen@count[1]{%
\@ifundefined{c@#1}
{% the counter doesn't exist
\newcounter{#1}\setcounter{#1}{1}%
}%
{% the counter exists
\stepcounter{#1}%
}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[2][0]{%
\ifthenelse{\equal{#1}{0}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{
\req@nomen@count{#2}%
\DTLnewrow{reqs}%
\ifthenelse{\equal{#1}{0}}
{\renewcommand{\@reqID}{\req{#2}}}
{\renewcommand{\@reqID}{\req[#1]{#2}}}%
\item[{[\@reqID]}]#3%
\dtlexpandnewvalue%
\DTLnewdbentry{reqs}{reqKey}{\@reqID}%
\DTLnewdbentry{reqs}{reqText}{#3}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}
这段代码还有另一个问题:表中的ID始终是文本中计数器最高的ID。
答案1
更新
\dtlexpandnewvalue
似乎只展开一次。因此,您必须使用附加参数来执行\req
该操作\arabic{<countername>}
。
使用您更改的示例:
\documentclass{article}
\usepackage{fmtcount}
\usepackage{datatool}
\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}
\makeatletter
% macro creating a new latex counter for every new entitiy name and requirement
\newcommand\req@nomen@count[1]{%
\@ifundefined{c@#1}
{% the counter doesn't exist
\newcounter{#1}\setcounter{#1}{1}%
}%
{% the counter exists
\stepcounter{#1}%
}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[3][0]{%
\ifthenelse{\equal{#1}{0}}
{REQ.#2.\padzeroes[3]{\decimalnum{#3}}}
{REQ.#2.\padzeroes[3]{\decimalnum{#3}}.\padzeroes[2]{\decimalnum{#1}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{%
\req@nomen@count{#2}%
\DTLnewrow{reqs}%
\ifthenelse{\equal{#1}{0}}
{\renewcommand{\@reqID}{\req{#2}{\arabic{#2}}}}
{\renewcommand{\@reqID}{\req[#1]{#2}{\arabic{#2}}}}%
\item[{[\@reqID]}]#3%
\dtlexpandnewvalue%
\DTLnewdbentry{reqs}{reqKey}{\@reqID}%
\DTLnewdbentry{reqs}{reqText}{#3}%
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}
结果:
但也许你可以避免命令的嵌套:
\documentclass{article}
\usepackage{fmtcount}
\usepackage{datatool}
\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}
\makeatletter
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{%
\@ifundefined{c@#2}{\newcounter{#2}}{}%
\stepcounter{#2}%
\DTLnewrow{reqs}%
\ifthenelse{\equal{#1}{0}}
{\renewcommand{\@reqID}{REQ.#2.\padzeroes[3]{\decimalnum{\arabic{#2}}}}}
{\renewcommand{\@reqID}{REQ.#2.\padzeroes[3]{\decimalnum{\arabic{#2}}}.\padzeroes[2]{\decimalnum{#1}}}}%
\item[{[\@reqID]}]#3%
\dtlexpandnewvalue%
\DTLnewdbentry{reqs}{reqKey}{\@reqID}%
\DTLnewdbentry{reqs}{reqText}{#3}%
}
\makeatother
\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}
结果和上面一样。
旧答案
使用以下代码时,打印数据库时仅使用计数器的最后一个值。
datatool
默认不展开添加的值。显示表格时原有定义有效。所以打印出来的键都是空的。
要在添加到数据库时扩展值,reqs
请使用\dtlexpandnewvalue
的定义\@regID
。
此外,我认为您不想介入计数器,\req
因为\req
每次执行两次\@regID
:一次作为参数打印\item
,一次添加到数据库。
并且我改变了另一行代码,因为\req
它采用了一个可选参数和一个强制参数(而不是两个强制参数)。
在下面的例子中,我还使用包enumitem
来定义自己的 listenvironment reqDecsr
。
\documentclass{article}
\usepackage{fmtcount}
\usepackage{xcolor}
\usepackage{longtable}
\usepackage{enumitem}
\newlist{reqDescr}{description}{1}
\setlist[reqDescr]{leftmargin=8em}
\usepackage{datatool}
\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}
\makeatletter
\newcommand\req@nomen@count[1]{%
\@ifundefined{c@#1}
{% the counter doesn't exist
\newcounter{#1}\setcounter{#1}{1}%
}
{% the counter exists
\stepcounter{#1}%
}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[2][0]{%
%\req@nomen@count{#2}% <- remove it here
\ifthenelse{\equal{#1}{0}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
{REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{%
\req@nomen@count{#2}% <- use it here
\DTLnewrow{reqs}%
\ifthenelse{\equal{#1}{0}}
{\renewcommand{\@reqID}{\req{#2}}}
{\renewcommand{\@reqID}{\req[#1]{#2}}}% <- changed
\item[\textcolor{blue}{[\@reqID]}]#3%
\dtlexpandnewvalue% <- added
\DTLnewdbentry{reqs}{reqKey}{\@reqID}%
\DTLnewdbentry{reqs}{reqText}{#3}%
}
\makeatother
\begin{document}
\begin{reqDescr}
\itemReq{reqCategory}{Requirement text, can be lengthy.}
\end{reqDescr}
...
\DTLdisplaylongdb{reqs}
\end{document}
结果:
如果条目较长,那么您可以替换
\DTLdisplaylongdb{reqs}
比如
\begin{longtable}{lp{.65\textwidth}}
\textbf{reqKey}&\multicolumn{1}{l}{\textbf{reqText}}\\
\endhead
\DTLforeach*{reqs}{\Key=reqKey,\Text=reqText}{\DTLiffirstrow{}{\tabularnewline}\Key&\Text}
\end{longtable}
顺便说一句:请始终提供 MWE。这样我们就不必猜测编译您的代码需要哪些包。