Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In the LaTeX Wikibook, we can see a table that gives the depths of the sectioning commands:

part: -1
chapter: 0
section: 1
subsection: 2

etc.

Is there any way to access this information dynamically through either LaTeX2e or L3? Maybe something like

\section_depth { section } :=> 1

EDIT

From what Marco said in the comments, this information may be useful:

$ texdef --tex latex @startsection

\@startsection:
macro:#1#2#3#4#5#6->\if@noskipsec \leavevmode \fi \par \@tempskipa #4\relax 
\@afterindenttrue \ifdim \@tempskipa <\z@ \@tempskipa -\@tempskipa \@afterindentfalse \fi 
\if@nobreak \everypar {}\else \addpenalty \@secpenalty \addvspace \@tempskipa \fi \@ifstar 
{\@ssect {#3}{#4}{#5}{#6}}{\@dblarg {\@sect {#1}{#2}{#3}{#4}{#5}{#6}}}
share|improve this question
    
It's a convention and the number which represents the depth of a sectioning command is the second mandatory argument of \@startsection. –  Marco Daniel Jul 7 '13 at 16:18
add comment

2 Answers

up vote 8 down vote accepted

In the standard classes, but also in memoir and KOMA-Script classes, the level for parts and chapters is not directly available. You can define a command \getsectionlevel in the following way:

\documentclass{book}
%\documentclass{memoir}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\getsectionlevel}{m}
 {
  \sean_get_section_level:N #1
 }

\cs_new_protected:Npn \sean_get_section_level:N #1
 {
  \cs_if_exist:NTF #1
   {
    \str_case_x:nnn { \cs_to_str:N #1 }
     {
      { book } { \cs_gset:cpx { booklevel } { -1 } }
      { part } { \cs_gset:cpx { partlevel } { -1 } }
      { chapter } { \cs_gset:cpx { chapterlevel } { 0 } }
     }
     { \__sean_get_lower_level:No #1 { #1 } }
   }
   {
    \ddt % should be a proper error message
   }
 }
\cs_new_protected:Npn \__sean_get_lower_level:Nn #1 #2
 {
  \__sean_get_lower_level:Nw #1 #2 \q_stop
 }
\cs_new_protected:Npn \__sean_get_lower_level:Nw #1 #2 #3 #4 #5 #6 \q_stop
 {
  \str_if_eq:nxTF { #4 } { \cs_to_str:N #1 }
   {% we're with memoir
    \cs_gset:cpx { \cs_to_str:N #1 level } { #5 }
   }
   {
    \cs_gset:cpx { \cs_to_str:N #1 level } { #4 }
   }
 }
\cs_generate_variant:Nn \__sean_get_lower_level:Nn { No }
\cs_generate_variant:Nn \str_if_eq:nnTF { nx }
\ExplSyntaxOff
\getsectionlevel{\chapter}

\show\chapterlevel

\getsectionlevel{\subsection}

\show\subsectionlevel

The macro \getsectionlevel<command> defines \<command>level.

We do a direct definition for the built-in commands; for lower levels we exploit the fact that they are defined by something like

\newcommand\section{\@startsection {section}{1}{\z@}...

so when we expand once <command> the third bit will be what we are looking for. For memoir one has to use a sligthly different path, because that class adds a hook \@startsection so the argument we need is shifted one place right.

Note that this will go crazy if a package such as titlesec is loaded. Probably it's much simpler to be confident in a normal setup:

  • book -2 (only in memoir)
  • part -1
  • chapter 0
  • section 1
  • subsection 2
  • subsubsection 3
  • paragraph 4
  • subparagraph 5
share|improve this answer
add comment

If package hyperref is loaded, the numbers are encoded in macros \toclevel@<section> and \sectiondepth can be defined as (without error checking):

\newcommand*{\sectiondepth}[1]{\csname toclevel@#1\endcsname}

Otherwise the easiest way is probably to define such a command, e.g.:

\makeatletter
\newcommand*{\secnum@book}{-2}% memoir
% test, if \chapter is defined without defining it
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname chapter\endcsname\relax
  \newcommand*{\secnum@part}{0}% article
\else
  \newcommand*{\secnum@part}{-1}%
  \newcommand*{\secnum@chapter}{0}%
\fi
\newcommand*{\secnum@section}{1}
\newcommand*{\secnum@subsection}{2}
\newcommand*{\secnum@subsubsection}{3}
\newcommand*{\secnum@paragraph}{4}
\newcommand*{\secnum@subparagraph}{5}
\newcommand*{\sectiondepth}[1]{%
  \@ifundefined{secnum@#1}{%
    ??% error: section type is not known
  }{%
    \csname secnum@#1\endcsname
  }%
}
\makeatother
share|improve this answer
1  
The problem is that, in general, there's no way to know: classes might use whatever value for the levels they want. –  egreg Jul 7 '13 at 21:23
    
@egreg: There is counter secnumdepth. A class that uses different values for the section commands for the standard classes would violate the interface of counter secnumdepth. Of course, a class/package could provide additional section levels (e.g. book of class memoir). Thus there is no way to be 100% sure. Also \@startsection does not help, a class can ignore it and use different macros for implementing the document division commands. –  Heiko Oberdiek Jul 7 '13 at 21:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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