TransWikia.com

How can I reference the current (sub)section number?

TeX - LaTeX Asked by jvriesem on March 7, 2021

I want to create a macro that dynamically returns the current chapter, section, subsection (etc.) I’m in. I’ve created a macro called getCurrentSectionNumber that does this, but it lacks the ability to figure out how many levels deep it is and shorten/lengthen the result accordingly. This macro should essentially return the full numbering text of the most recent subsection, section, or chapter where it was invoked.

This macro should produce the following text at the given places.

  • A: “1”
  • B: “1.1”
  • C: “1.1.1”
  • D: “1.1.2”
  • E: “1.2”
  • F: “1.2.1”
  • G: “1.2.2”

Note that at A, it prints “1.??” because there is no section defined at that point. Locations C, D, F, and G all omit the subsection.

Example:

documentclass{report}
usepackage{etoolbox}


newcommandgetcurrentref[1]{%
 ifnumequal{value{#1}}{0}
  {??}
  {thevalue{#1}}%
} 
newcommand{getCurrentSectionNumber}{getcurrentref{chapter}.getcurrentref{section}}


begin{document}

chapter{My Example}
A: Current number is getCurrentSectionNumber

section{Section One-point-One}
    B: Current number is getCurrentSectionNumber
    subsection{subsection one-point-one-point-one}
        C: Current number is getCurrentSectionNumber
    subsection{subsection one-point-one-point-two}
        D: Current number is getCurrentSectionNumber
section{Section Two}
    E: Current number is getCurrentSectionNumber
    subsection{subsection one-point-two-point-one}
        F: Current number is getCurrentSectionNumber
    subsection{subsection one-point-two-point-two}
        G: Current number is getCurrentSectionNumber

end{document}

Example’s Output:

output of the example code given above

Any help would be appreciated. Thanks!

4 Answers

You mean something like this? We simply use the fact that the "lower" section number is always 0 when that sectioning level is not used at the moment.

documentclass{report}

makeatletter
newcommand{getCurrentSectionNumber}{%
  ifnumc@section=0 %
  thechapter
  else
  ifnumc@subsection=0 %
  thesection
  else
  ifnumc@subsubsection=0 %
  thesubsection
  else
  thesubsubsection
  fi
  fi
  fi
}

makeatother

begin{document}

chapter{My Example}
A: Current number is getCurrentSectionNumber %1

section{Section One-point-One}
    B: Current number is getCurrentSectionNumber % 1.1
    subsection{subsection one-point-one-point-one}
        C: Current number is getCurrentSectionNumber % 1.1.1
    subsection{subsection one-point-one-point-two}
        D: Current number is getCurrentSectionNumber % 1.1.2
section{Section Two}
    E: Current number is getCurrentSectionNumber % 1.2
    subsection{subsection one-point-two-point-one}
        F: Current number is getCurrentSectionNumber % 1.2.1
    subsection{subsection one-point-two-point-two}
        G: Current number is getCurrentSectionNumber % 1.2.2

end{document}

Answered by yo' on March 7, 2021

Here is another way compared to the good answer from tohecz, using simply the fact that the label command refers to the last sectioning command called.

documentclass{book}

usepackage[hidelinks]{hyperref}
newcounter{GN}
setcounter{GN}{0}
newcommand{GetNumber}[0]{stepcounter{GN}label{GN:theGN}ref{GN:theGN}}

begin{document}

chapter{Foo}
Current number is: GetNumber
section{Bar}
Current number is: GetNumber
subsection{Baz}
Current number is: GetNumber
subsection{Baz2}
Current number is: GetNumber
section{Bar2}
Current number is: GetNumber

end{document}

And here the output:

Output

EDIT Here is an improved version of my MWE to show the robustness of the method to the equation and float.

documentclass{book}

usepackage{float}
usepackage[hidelinks]{hyperref}
newcounter{GN}
setcounter{GN}{0}
newcommand{GetNumber}[0]{stepcounter{GN}label{GN:theGN}ref{GN:theGN}}

begin{document}

chapter{Foo}
Current number is: GetNumber
section{Bar}
Current number is: GetNumber
subsection{Baz}

begin{equation}c=a+bend{equation}

noindent
Current number is: GetNumber
subsection{Baz2}

begin{figure}[H]
caption{Figure to test the robustness}
end{figure}

Current number is: GetNumber
section{Bar2}
Current number is: GetNumber

end{document}

and here is its output, however as pointed out by tohecz and egreg in the comments, this solution works only if you call GetNumber out of an environment where a counter has been refstepped.

Output2

Answered by Ludovic C. on March 7, 2021

You have to examine each counter from top down and stop when you reach one that has the value zero.

documentclass{book}
usepackage{xparse}
ExplSyntaxOn
NewDocumentCommand{getCurrentSectionNumber}{}
 {
  jvri_get_current:
 }
% the list of examined counters
clist_const:Nn c_jvri_counters_clist 
 {
  chapter,section,subsection,subsubsection,paragraph,subparagraph
 }

% for storing the previous counter name
tl_new:N l_jvri_previous_tl

cs_new_protected:Npn jvri_get_current:
 {
  tl_set:Nn l_jvri_previous_tl { part } % for safety
  clist_map_inline:Nn c_jvri_counters_clist
   {
    int_compare:nTF { arabic{##1} = 0 }
     {% if the counter is zero, break and use the former the<counter>
      clist_map_break:n { use:c { the l_jvri_previous_tl } }
     }
     {% store the counter's name
      tl_set:Nn l_jvri_previous_tl { ##1 }
     }
   }
 }
ExplSyntaxOff

begin{document}

Zero: getCurrentSectionNumber (will have no output)

chapter{My Example}
A: Current number is getCurrentSectionNumber

section{Section One-point-One}
B: Current number is getCurrentSectionNumber

subsection{subsection one-point-one-point-one}
C: Current number is getCurrentSectionNumber

subsection{subsection one-point-one-point-two}
D: Current number is getCurrentSectionNumber

section{Section Two}
E: Current number is getCurrentSectionNumber

subsection{subsection one-point-two-point-one}
F: Current number is getCurrentSectionNumber

subsection{subsection one-point-two-point-two}
G: Current number is getCurrentSectionNumber

chapter{Again}
H: Current number is getCurrentSectionNumber

end{document}

This is easily extendable to manage also lower levels.

You'll see that after “Zero:” there will be nothing; it can be added a check whether the final sequence is empty.

enter image description here

enter image description here

Answered by egreg on March 7, 2021

If you are able to retrieve the current sectioning level (lets call it currsecnumdepth), you could also use plain old ifcase:

newcommand*{getCurrentSectionNumber}{ifcasecurrsecnumdepththechapterorthesection
orthesubsectionorthesubsubsectionortheparagraphorthesubparagraphfi}

In the following example, I provided a (admittedly unpleasent) way to make sure that the premise of my above sentence holds:

documentclass{report}

makeatletter
newcountcurrsecnumdepth
%verbose from the standard classes, except line 4
renewcommand{chapter}{if@openrightcleardoublepageelseclearpagefi
                        thispagestyle{plain}%
                        global@topnumz@
                        globalcurrsecnumdepthz@
                        @afterindentfalse
                        secdef@chapter@schapter}
%verbose from latex.ltx, except line 2
renewcommand{@startsection}[6]{%
  globalcurrsecnumdepth=#2
  if@noskipsec leavevmode fi
  par
  @tempskipa #4relax
  @afterindenttrue
  ifdim @tempskipa <z@
    @tempskipa -@tempskipa @afterindentfalse
  fi
  if@nobreak
    everypar{}%
  else
    addpenalty@secpenaltyaddvspace@tempskipa
  fi
  @ifstar
    {@ssect{#3}{#4}{#5}{#6}}%
    {@dblarg{@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}
makeatother

newcommand*{getCurrentSectionNumber}{ifcasecurrsecnumdepththechapterorthesection
orthesubsectionorthesubsubsectionortheparagraphorthesubparagraphfi}

begin{document}

chapter{My Example}
A: Current number is getCurrentSectionNumber

section{Section One-point-One}
    B: Current number is getCurrentSectionNumber
    subsection{subsection one-point-one-point-one}
        C: Current number is getCurrentSectionNumber
    subsection{subsection one-point-one-point-two}
        D: Current number is getCurrentSectionNumber
section{Section Two}
    E: Current number is getCurrentSectionNumber
    subsection{subsection one-point-two-point-one}
        F: Current number is getCurrentSectionNumber
    subsection{subsection one-point-two-point-two}
        G: Current number is getCurrentSectionNumber

end{document}

currsecnmb demo

Answered by Ruben on March 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP