将子节的枚举更改为特定格式

将子节的枚举更改为特定格式

我目前正在编写一种需求分析,并想以某种风格列举我的章节和小节:

我的部分应该看起来像正常的,例如“1.1 文件的导入和导出”,但应该定义一个宏“\startLetter”作为标题的第一个字母(这里是“I”)。

以下子节的枚举应以当前 \startLetter 开头,并具有一个递增的三位标识符,该标识符在下一节开始时重置,例如“I001 文本文件导入”。引用这些时,我只想打印字母 + ID,因此“I001”也仍然通过 hyperref 引用。

我当前的设置如下。问题是

  1. 我不知道如何缩短引用,只显示 ID,而不破坏超链接,
  2. 引用时 ID 计数器仍会计数。我确信这是因为宏成为节名称的一部分,因此每次都会重新评估。我该如何停止这种情况?

我研究了 titlesec、xparse 和 etoolbox 的 pretocmd 和 apptocmd,但这需要修补 @ssect 命令(?),而我经验不足,无法编辑 Latex 部分的底层命令。有没有一种“新手可以理解”的方法来解决这个问题?

提前致谢 :)

梅威瑟:

\documentclass[10pt,a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{xstring}
\usepackage{nameref}
\usepackage{hyperref}
\newcommand{\startLetter}{}
\newcounter{reqID}


\newcommand{\reqSection}[1]{%
    \section{#1}
    \renewcommand{\startLetter}{\StrMid{#1}{0}{1}}
    \setcounter{reqID}{1}
}

\newcommand{\leadingZerosID}{%
    \ifnum\value{reqID}<100 0\fi\ifnum\value{reqID}<10 0\fi\arabic{reqID}
}   

\newcommand{\reqSubsection}[1]{%
    \subsection*{\startLetter\leadingZerosID{} #1}
    \stepcounter{reqID}
}

\parindent0mm

\begin{document}
    \chapter{Any chapter}
    \reqSection{Import Export}
    \reqSubsection{Text Files Import}
    \label{lbl:import-text}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \reqSubsection{Text Files Export}
    \label{lbl:export-text}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \reqSubsection{Video Files Import}
    \label{lbl:import-video}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \vspace{1cm}

    I am refering to requirement \nameref{lbl:export-text}.
\end{document}

答案1

假设我正确理解了这个问题,我认为这可以满足您的需要。基本思想是使用普通的子部分,更改其标题以满足您的要求。这消除了计数器的问题,并允许您使用普通命令\ref按 ID 号引用。

\documentclass{book}

\makeatletter
\def\firstchar#1{\firstchar@internal#1\relax}
\def\firstchar@internal#1#2\relax{#1}
\makeatother

\newcommand{\reqSection}[1]{%
\section{#1}
\xdef\startLetter{\firstchar{#1}}
}

\newcommand{\leadingZerosSS}{%
    \ifnum\value{subsection}<100 0\fi\ifnum\value{subsection}<10 0\fi\arabic{subsection}
}   

\renewcommand\thesubsection{\startLetter\leadingZerosSS{}}

\usepackage{hyperref}

\begin{document}
    \chapter{Any chapter}
    \reqSection{Import Export}
    \subsection{Text Files Import}
    \label{lbl:import-text}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \subsection{Text Files Export}
    \label{lbl:export-text}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \subsection{Video Files Import}
    \label{lbl:import-video}
    Some useless blindtext. Some useless blindtext. Some useless blindtext. Some useless blindtext.
    \vspace{1cm}

    I am refering to requirement \nameref{lbl:export-text}.

    I can refer to the ID using \verb+\ref+ rather than \verb+\nameref+, for example \ref{lbl:export-text}
\end{document}

编辑

由于我没有调查的原因,您的\startLetter宏对我来说不起作用,所以我自己写了。这个想法(我从 David Carlisle 的回答中学到的)是\firstchar@internal需要两个参数;#1是它找到的第一个标记 (*),但#2必须以 结尾\relax#1作为结果返回,并被#2忽略。将 (**)\firstchar附加\relax到其参数的末尾并将其发送到\firstchar@internal。所以...

\firschar{abc}
--> \firstchar@internal{abc\relax} 
#1 = a
#2 = bc
--> a

(*)它也可能是一组用括号括起来的,但\subsection{{abc} def}对我来说这似乎不太可能)。

(**) 最初我习惯于a \relax确保 TeX 会找到两样东西\firstchar{a},但实际上这是不必要的,因为在这种情况下#1 = a#2最终会为空。如果您这样做,新实现会导致错误\firstchar{},这是有道理的;旧实现将返回a

相关内容