我正在编写一份包含代码套件需求和规范的文档,我想创建一个需求可追溯性矩阵,以显示规范的哪一部分涵盖了每个需求。我有一个“手动”创建的需求列表。(我不想自动生成项目编号……文档外的需求将通过编号引用。)
我还有一个仅使用普通枚举环境创建的规范。
如何自动创建需求可追溯性矩阵(表格),其中列出涵盖每个需求的规范部分,如下例所示?第一列是每个需求,第二列列出引用该特定需求的所有规范项目。
\documentclass{article}
\begin{document}
% define \req command to label requirements in description environment
\makeatletter
\newcommand{\req}[1]{
\textbf{R#1}
\def\@currentlabel{R#1}\label{req#1}
}
\makeatother
% requirements are listed and labeled manually in description environment
\begin{description}
\item[\req{1}] First requirement
\item[\req{2}] Second requirement
\begin{description}
\item[\req{2.1}] Requirement 2.1
\begin{description}
\item[\req{2.1.1}] Requirement 2.1.1
\item[\req{2.1.2}] Requirement 2.1.2
\end{description}
\item[\req{2.2}] Requirement 2.2
\end{description}
\end{description}
% specifications are items in enumerate environment with references to
% requirements met at end of each specification
\begin{enumerate}
\item\label{spec1} First specification. \ref{req2.1.2}
\item\label{spec2} Second specification. \ref{req1}
\begin{enumerate}
\item\label{spec3} Third specification. \ref{req1}
\item\label{spec4} Fourth specification. \ref{req2}, \ref{req2.1.1}
\end{enumerate}
\end{enumerate}
% requirement traceability matrix (table) should be auto-generated
% first column is refs to requirement labels manually generated
% second column is refs to specification labels generated in enumerate environment
% for all specifications in which the requirement ref appears in the enumerate
% environment
\begin{table}[h]
\begin{tabular}{|l|l|}
\hline
Requirement & Specification \\ \hline
\ref{req1} & \ref{spec2}, \ref{spec3} \\ \hline
\ref{req2} & \ref{spec4} \\ \hline
\ref{req2.1} & \\ \hline
\ref{req2.1.1} & \ref{spec4} \\ \hline
\ref{req2.1.2} & \ref{spec1} \\ \hline
\ref{req2.2} & \\ \hline
\end{tabular}
\end{table}
\end{document}
答案1
应该为此编写一些软件包,以考虑比我的提案已经允许的更多可能性(1),并保持与您的初始设置相当接近。
(1)例如,按字典顺序对需求进行排序,这里它们从生成的方式来看已经是正确的顺序了。
我还添加了hyperref
检查,以确保自动生成的表格确实具有指向需求和规范的超链接。
\documentclass{article}
\newcommand{\requirements}{}
\providecommand*\phantomsection{}
\makeatletter
\newcommand{\req}[1]{%
\textbf{R#1}%
\phantomsection
\def\@currentlabel{R#1}%
\label{req@#1}%
\g@addto@macro\requirements{{req@#1}}%
\global\@namedef{req@#1@ismetby}{}%
}
\newcommand{\meetsreq}[1]{%
\ref{req@#1}%
\expandafter\g@addto@macro\csname req@#1@ismetby\expandafter\endcsname
\expandafter {\expandafter{\@currentspec}}%
}
\newcommand{\specswithreq}[1]%
% The space before \ref below is intentional and will be swallowed by \xintApply
% It is not mandatory however, the thing works without it too.
{\xintListWithSep{, }{\xintApply { \ref}{\csname #1@ismetby\endcsname }}}
\newcommand{\spec}[1]{\label{spec@#1}\gdef\@currentspec{spec@#1}}
% (update Jan 5, to use \gdef rather than \def in \spec, allowing more flexible usage; has its pros and cons)
\makeatother
\usepackage{xinttools}
\usepackage{hyperref}% check if ok with hyperlinks
\hypersetup{colorlinks=true}
\begin{document}
\begin{description}
\item[\req{1}] First requirement
\item[\req{2}] Second requirement
\begin{description}
\item[\req{2.1}] Requirement 2.1
\begin{description}
\item[\req{2.1.1}] Requirement 2.1.1
\item[\req{2.1.2}] Requirement 2.1.2
\end{description}
\item[\req{2.2}] Requirement 2.2
\end{description}
\end{description}
\begin{enumerate}
\item\spec{1} First specification. \meetsreq{2.1.2}
\item\spec{2} Second specification. \meetsreq{1}
\begin{enumerate}
\item\spec{3} Third specification. \meetsreq{1}
\item\spec{4} Fourth specification. \meetsreq{2}, \meetsreq{2.1.1}
\end{enumerate}
\end{enumerate}
\begin{table}[htbp]
\begin{tabular}{|l|l|}
\hline
Requirement & Specification \\
\hline
\xintFor* #1 in \requirements\do {\ref{#1}&\specswithreq{#1}\\
\hline }%
\end{tabular}
\end{table}
\end{document}
更新根据评论重命名了宏。
一个立即想到的扩展是允许\meetsreq
接受逗号分隔的列表。以下修改后的代码可以实现这一点:
\newcommand{\meetsthisreq}[1]{% (renamed from \meetsreq above)
\ref{req@#1}%
\expandafter\g@addto@macro\csname req@#1@ismetby\expandafter\endcsname
\expandafter {\expandafter{\@currentspec}}%
}
\newcommand{\meetsreq}[1]{% (handles comma separated list)
\xintListWithSep{, }{\xintApply{ \meetsthisreq}{\xintCSVtoList{#1}}}%
}
然后可以使用例如
\item\spec{4} Fourth specification. \meetsreq{2, 2.1.1}