1

I have defined two new counters and two macros. The first macro \requirement simply increases the counter requirement. The second macro \subrequirement is basically doing the same but using requriment as reference. Both macros define a new label.

Now I want to pass a already defined label to \subrequirement and use the counter value requirement from the passed label without resetting the actual counter requirement.

\documentclass[a4paper, 12pt]{scrartcl}

\usepackage{etoolbox} % Used anyway in the document
\usepackage{hyperref} % Used if important for question

% Define counter
\newcounter{requirement}
\newcounter{subrequirement}[requirement]

% Define new commands
\newcommand{\requirement}[1]{%
    \refstepcounter{requirement}R\therequirement%
    \label{req:#1}%
}%
\newcommand{\subrequirement}[2][]{%
    \ifstrempty{#1}{%
        \refstepcounter{subrequirement}R\therequirement.\thesubrequirement%
        \label{subreq:#2}%
    }{%
        % use passed label as reference counter
%        \refstepcounter{subrequirement}R\therequirement.\thesubrequirement%
%        \label{subreq:#2}%
    }%
}%

\begin{document}
    Define requirement: \requirement{request} (R1)

    Reference request \ref{req:request}

    Define second requirement: \requirement{need-help} (R2)

    Define subrequirement \subrequirement{need-help-1} (R2.1) and \subrequirement{need-help-2} (R2.2)

    Define subrequirement of with passed reference \subrequirement[request]{request-1} (R1.1 wanted)

    Define requirement \requirement{tex-SX} (R3 is desired)
\end{document}

Edit 1: (dirty) Solution - manuell set subcounter

\documentclass[a4paper, 12pt]{scrartcl}

\usepackage{etoolbox} % Used anyway in the document
\usepackage{xparse}
\usepackage{hyperref} % Used if important for question

% Define counter
\newcounter{requirement}
\newcounter{subrequirement}[requirement]

% Define new commands
\newcommand{\requirement}[1]{%
    \refstepcounter{requirement}R\therequirement%
    \label{req:#1}%
}%

\NewDocumentCommand{\subrequirement}{ O{} O{0} m}{%
    \ifstrempty{#1}{%
        \refstepcounter{subrequirement}R\therequirement.\thesubrequirement%
        \label{subreq:#3}%
    }{%
        % use passed label as reference counter
        \ifnumequal{#2}{0}{%
            R\ref{req:#1}.\thesubrequirement%
        }{%
            R\ref{req:#1}.#2%
        }%
        \label{subreq:#3}%
    }%
}

\begin{document}
    Define requirement: \requirement{request} (R1)

    Reference request \ref{req:request}

    Define second requirement: \requirement{need-help} (R2)

    Define subrequirement \subrequirement{need-help-1} (R2.1) and \subrequirement{need-help-2} (R2.2)

    Define subrequirement of with passed reference \subrequirement[request][1]{request-1} (R1.1 wanted)

    Define requirement \requirement{tex-SX} (R3 is desired)
\end{document}

The edit command provide a second optional argument to set the subcounter manually. The man problem is to overlook if there is a entry with a subcounter already.

2

I use a property list to store the requirement numbers and their current subrequirement number.

When \subrequirement is used without an optional argument, the current requirement number is used.

\documentclass[a4paper, 12pt]{scrartcl}

\usepackage{xparse} 
\usepackage{hyperref}

\ExplSyntaxOn

% user interface
\NewDocumentCommand{\requirement}{m}
 {
  \faltfe_requirement:n { #1 }
 }
\NewDocumentCommand{\subrequirement}{om}
 {
  \IfNoValueTF { #1 }
   {
    \faltfe_requirement_sub:Vn \g_faltfe_requirement_current_tl { #2 }
   }
   {
    \faltfe_requirement_sub:nn { #1 } { #2 }
   }
 }

% variables
\prop_new:N \g_faltfe_requirement_prop
\int_new:N \g_faltfe_requirement_int
\tl_new:N \g_faltfe_requirement_current_tl

\cs_new_protected:Nn \__faltfe_requirement_currentlabel:n
 {
  #1
  \cs_set:cpx { @currentlabel } { #1 }
 }

\cs_new_protected:Nn \faltfe_requirement:n
 {
  \int_gincr:N \g_faltfe_requirement_int
  \prop_gput:Nnx \g_faltfe_requirement_prop
   { #1 }
   { \int_to_arabic:n { \g_faltfe_requirement_int } }
  \prop_if_in:NnF \g_faltfe_requirement_prop { #1@sub }
   {
    \prop_gput:Nnn \g_faltfe_requirement_prop { #1@sub } { 0 }
   }
  \tl_gset:Nn \g_faltfe_requirement_current_tl { #1 }
  % print the number and set the current label
  \use:c { phantomsection }
  R\__faltfe_requirement_currentlabel:n
   { \int_to_arabic:n { \g_faltfe_requirement_int } }
  \label{req:#1}
 }

\cs_new_protected:Nn \faltfe_requirement_sub:nn
 {
  \prop_gput:Nnx \g_faltfe_requirement_prop
   { #1@sub }
   { \int_to_arabic:n { 1 + \prop_item:Nn \g_faltfe_requirement_prop { #1@sub } } }
  % print the number and set the current label
  \use:c { phantomsection }
  R\__faltfe_requirement_currentlabel:n
   {
    \prop_item:Nn \g_faltfe_requirement_prop { #1 }
    .
    \prop_item:Nn \g_faltfe_requirement_prop { #1@sub }
   }
  \label{subreq:#2}
 }
\cs_generate_variant:Nn \faltfe_requirement_sub:nn { V }

\ExplSyntaxOff

\begin{document}

Define requirement: \requirement{request} (R1)

Reference request \ref{req:request}

Define second requirement: \requirement{need-help} (R2)

Define subrequirement \subrequirement{need-help-1} (R2.1)
and \subrequirement{need-help-2} (R2.2)

Define subrequirement of with passed reference
\subrequirement[request]{request-1} (R1.1 wanted)

Define requirement \requirement{tex-SX} (R3 is desired)

\ref{subreq:request-1}

\end{document}

With \use:c { phantomsection } we set (conditionally to hyperref being loaded) an anchor.

enter image description here

With tabularx it's a bit of a problem, because every cell is typeset multiple times and so the values will be incremented correspondingly.

Unfortunately, the package doesn't provide a hook for knowing when the first trial typesetting takes place, so we can only do the increment at the final step.

\documentclass[a4paper, 12pt]{scrartcl}

\usepackage{xparse}
\usepackage{tabularx}
\usepackage{hyperref}

%%% code starts here
\makeatletter
\providecommand{\TX@vwarn}{x} % in case tabularx is not loaded
\makeatother

\ExplSyntaxOn

% user interface
\NewDocumentCommand{\requirement}{m}
 {
  \faltfe_requirement:n { #1 }
 }
\NewDocumentCommand{\subrequirement}{om}
 {
  \IfNoValueTF { #1 }
   {
    \faltfe_requirement_sub:Vn \g_faltfe_requirement_current_tl { #2 }
   }
   {
    \faltfe_requirement_sub:nn { #1 } { #2 }
   }
 }

% variables
\prop_new:N \g_faltfe_requirement_prop
\int_new:N \g_faltfe_requirement_int
\tl_new:N \g_faltfe_requirement_current_tl

\cs_new_protected:Nn \__faltfe_requirement_currentlabel:n
 {
  #1
  \cs_set:cpx { @currentlabel } { #1 }
 }

\cs_new_protected:Nn \faltfe_requirement:n
 {
  \tl_if_empty:cF { TX@vwarn }
   {% we're not doing a trial typesetting, do it 
    \int_gincr:N \g_faltfe_requirement_int
    \prop_gput:Nnx \g_faltfe_requirement_prop
     { #1 }
     { \int_to_arabic:n { \g_faltfe_requirement_int } }
    \prop_if_in:NnF \g_faltfe_requirement_prop { #1@sub }
     {
      \prop_gput:Nnn \g_faltfe_requirement_prop { #1@sub } { 0 }
     }
   }
  \tl_gset:Nn \g_faltfe_requirement_current_tl { #1 }
  % print the number and set the current label
  \phantomsection
  R\__faltfe_requirement_currentlabel:n
   { \int_to_arabic:n { \g_faltfe_requirement_int } }
  \label{req:#1}
 }

\cs_new_protected:Nn \faltfe_requirement_sub:nn
 {
  \tl_if_empty:cF { TX@vwarn }
   {% we're not doing a trial typesetting
    \prop_gput:Nnx \g_faltfe_requirement_prop
     { #1@sub }
     { \int_to_arabic:n { 1 + \prop_item:Nn \g_faltfe_requirement_prop { #1@sub } } }
   }
  % print the number and set the current label
  \phantomsection
  R\__faltfe_requirement_currentlabel:n
   {
    \prop_item:Nn \g_faltfe_requirement_prop { #1 }
    .
    \prop_item:Nn \g_faltfe_requirement_prop { #1@sub }
   }
  \label{subreq:#2}
 }
\cs_generate_variant:Nn \faltfe_requirement_sub:nn { V }

\ExplSyntaxOff
% code ends here

\begin{document}

\begin{tabularx}{\textwidth}{X}
Define requirement: \requirement{request} (R1)
\\
Reference request \ref{req:request}
\\
Define second requirement: \requirement{need-help} (R2)
\\
Define subrequirement \subrequirement{need-help-1} (R2.1)
and \subrequirement{need-help-2} (R2.2)
\\
Define subrequirement of with passed reference
\subrequirement[request]{request-1} (R1.1 wanted)
\\
Define requirement \requirement{tex-SX} (R3 is desired)
\end{tabularx}
\ref{subreq:request-1}

\end{document}
  • This is working like a charm. Unfortunately, my LaTeX3 knowledge goes to zero so I don't understand the code. One more reason to learn it. – faltfe Aug 27 '18 at 9:36
  • There is some pretty wired counting issue when using \requirement inside a tabularx envirement. Is there anything I have to consider? – faltfe Aug 27 '18 at 12:24
  • 1
    @faltfe Added the workaround – egreg Aug 27 '18 at 15:48
  • Your are a TeX legend. I'll test it tomorrow in my real document. – faltfe Aug 27 '18 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.