5

I'm trying to define a command which creates a part/chapter/section/subsection/... depending on the last defined part/chapter/section/subsection/...

It should look like this pseudo code:

global string currentSection;

function level(arg, sectioningArgs ...) { 
  switch(arg) {
    case '+' {
      switch(currentSection) {
        case 'none' {
          \part(sectioningArgs)
        }
        case 'part' {
          \chapter(sectioningArgs)
        }
        case 'chapter' {
          \section(sectioningArgs)
        }
        ...
      }
    }
    case '-' {
      ...
    }      
    case '0' {
      ...
    }
  }
}

(just imagine a 'break' after each case ...)

The usage should be like follows:

\documentclass[a4paper,12pt,oneside]{book}

\newcommand{\level}[<?>]{<?>}

\begin{document}
  \level{+}{A part}
  \level{+}{A chapter}
  \level{+}{A section}
  \level{0}{Another section}
  \level{-}{A chapter}
  \level{-}{A part}
\end{document}

Rationale: I often find myself changing subsections to sections and so on in subfiles I include in my main document --- this should automate the process.

Any help is greatly appreciated, thank you in advance.

  • This can't work; you typically start a new part when you're is a section. – egreg Sep 8 '15 at 16:53
5

The keys +, - and 0 are not sufficient, because typically you need to jump up levels when a chapter finishes.

The \level macro has a mandatory argument; it can be +, -, = or an integer (between –1 and 5, extremes included).

I find using +, - or = error prone, unless your editor allows you to fold at \level. However, it's easy to use the absolute level.

\documentclass{book}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\level}{m}
 {
  \mch_level:n { #1 }
 }

\int_new:N \g_mch_level_int

\cs_new_protected:Nn \mch_level:n
 {
  \str_case:nnF { #1 }
   {
    {+}{ \int_gincr:N \g_mch_level_int }
    {-}{ \int_gdecr:N \g_mch_level_int }
    {=}{ }
   }
   { \int_gset:Nn \g_mch_level_int { #1 } }
  \int_case:nnF { \g_mch_level_int }
   {
    {-1}{\part}
     {0}{\chapter}
     {1}{\section}
     {2}{\subsection}
     {3}{\subsubsection}
     {4}{\paragraph}
     {5}{\subparagraph}
   }
   {Beyond limit!}
 }
\ExplSyntaxOff

\begin{document}

\mainmatter

\level{0}{Introduction}

Text

\level{-}{First part}

\level{+}{First chapter}

\level{+}{First section}

\level{+}{First subsection}

\level{=}{Second subsection}

\level{-}{Second section}

\level{+}{First subsection}

\level{=}{Second subsection}

\level{0}[Second chapter]{Second chapter with a very very very long title}

\end{document}

enter image description here

|improve this answer|||||
4

Here is a very elementary implementation that doesn't include error checking (but can be added) and a slight interface change - an optional argument rather than a mandatory one for switching the relative level of the sectional unit.

enter image description here

\documentclass{book}

\newcounter{cursecdepth}
\setcounter{cursecdepth}{-1}
\makeatletter
\@namedef{seclevel@0}{\part}
\@namedef{seclevel@1}{\chapter}
\@namedef{seclevel@2}{\section}
\@namedef{seclevel@3}{\subsection}
\@namedef{seclevel@4}{\subsubsection}
\@namedef{seclevel@5}{\paragraph}
\@namedef{seclevel@6}{\subparagraph}

\newcommand{\level}[1][=]{%
  \ifnum\pdfstrcmp{#1}{+}=0
    \stepcounter{cursecdepth}% Jump down a level
  \else\ifnum\pdfstrcmp{#1}{-}=0
    \addtocounter{cursecdepth}{-1}% Jump up a level
  \else\ifnum\pdfstrcmp{#1}{=}=0
    % Stay at this level
  \else
    \setcounter{cursecdepth}{#1}% Set the current level
  \fi\fi\fi
  \csname seclevel@\arabic{cursecdepth}\endcsname
}
\makeatother
\newcommand{\uplevel}{\addtocounter{cursecdepth}{-1}}
\newcommand{\downlevel}{\stepcounter{cursecdepth}}

\begin{document}

\tableofcontents

\level[+]{A part}
\level[+]{A chapter}
\level[+]{A section}
\level[2]{Another section}
\level[=]{Yet another section}
\level   {Another, final section}
\level[+]{A subsection}
\level[1]{A chapter}
\level[-]{A part}

\end{document}

I've set the counter cursecdepth to -1 at the start, which requires you to use \level[+] to start with a \part. However, it would be more intuitive to start with \level (or \level[0]) as a \part.

Fixed-depth jumping is achieved by setting the optional parameter to a number, where the number indicates the level of the sectional unit:

  0. Part
  1. Chapter
  2. Section
  3. Subsection
  4. Subsubsection
  5. Paragraph
  6. Subparagraph

One can use \uplevel or \downlevel to step the current level as needed.

|improve this answer|||||
  • What if a chapter end with a subsubsection? – egreg Sep 8 '15 at 16:51
  • I decided to accept egreg's answer, because it deals with the issue of `jumping up'. But it was really my fault --- I didn't think of this beforehand and didn't include it in the question. Therefore Werner's answer is correct as well. It's a shame that it's impossible to accept multiple answers. – MCH Sep 8 '15 at 17:38
  • @MCH: You can still vote on the answers; that's different from accepting. I'll update my answer to accommodate for such jumping. – Werner Sep 8 '15 at 17:39

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.