LaTeX セクション見出し (@startsection) の解説とプログラミング

2025-05-27

「@startsection」は、LaTeX のソースコード内部で定義されている、章、節、項などのセクションの見出しを生成するための非常に基本的なコマンドです。LaTeX がドキュメントの構造を理解し、適切に見出しを整形・出力するために使われています。

もう少し詳しく見ていきましょう。

「typesetting sectional unit headings」 は、まさにこの「@startsection」の主な役割を表しています。つまり、ドキュメントの階層構造における各セクション(章、節、小節など)の見出しを、LaTeX の定義に従って組版(文字を配置して印刷に適した形にすること)する、という意味合いになります。

具体的には、「@startsection」コマンドは、以下のような処理を行います。

  • ヘッダーやフッターへの影響
    セクションの開始が、ページヘッダーやフッターの内容に影響を与える場合があります。
  • 目次への登録
    必要に応じて、生成された見出しを目次(Table of Contents)に登録するための情報を記録します。
  • 見出し前後の空白の調整
    見出しの前後に入る垂直方向の空白量を調整し、ドキュメント全体のレイアウトを整えます。
  • セクション番号の生成と出力
    \chapter, \section などのコマンドで指定されたセクションレベルに応じて、自動的に番号を生成し、見出しの一部として出力します(例えば、「第1章」や「1.1 節」など)。

「@startsection」コマンドの基本的な構造(概念的なものです)

\@startsection{<name>}{<level>}{<indent>}{<beforeskip>}{<afterskip>}{<style>}
              {<numberwidth>}{<subindent>}{<prefix>}{<after-title>}

それぞれの引数は以下のような意味を持ちます。

  • <after-title>: 見出しテキストの直後に挿入するコマンド(例: 行末の空白を吸収するための \par など)。
  • <prefix>: 番号の前に付加する文字列(例: \thechapter.\ のように、章番号とピリオド、そして空白)。
  • <subindent>: 番号の後、見出しテキストが始まる位置までのインデント量。
  • <numberwidth>: セクション番号の幅。番号がこの幅を超えると、次の行に折り返されます。
  • <style>: 見出しのテキストを整形するためのコマンド(例: \normalfont\Large\bfseries など)。
  • <afterskip>: 見出しの後に挿入する垂直方向の空白量。正の値にすると、見出しと次のテキストの間に空白が挿入されます。負の値にすると、次のテキストとの間に空白が挿入され、段落のインデントを打ち消す効果があります。
  • <beforeskip>: 見出しの前に挿入する垂直方向の空白量。負の値にすると、直前のテキストとの間に空白が挿入されません。
  • <indent>: 左マージンからのインデント量。
  • <level>: セクションの階層レベルを示す数値(例: \chapter は -1, \section は 1, \subsection は 2 など)。
  • <name>: セクションコマンドの名前(例: chapter, section, subsection など)。

普段の LaTeX プログラミングで直接「@startsection」を使うことは稀です。通常は、\chapter, \section, \subsection などの高レベルなセクションコマンドを使用します。これらの高レベルコマンドの内部で、「@startsection」が適切な引数を伴って呼び出され、見出しの組版が行われています。

しかし、「@startsection」の仕組みを理解することで、LaTeX がどのようにドキュメントの構造を処理し、見出しを生成しているのか、より深く理解することができます。また、高度なカスタマイズを行う際に、この低レベルなコマンドの知識が役立つことがあります。



「@startsection」は低レベルなコマンドであり、通常は直接使用しませんが、パッケージ開発者や高度なカスタマイズを行うユーザーが扱うことがあります。そのため、関連するエラーやトラブルシューティングは、主にセクション関連の挙動をカスタマイズした際に発生しやすいと言えます。

以下に、よくあるエラーとその対処法をいくつか挙げます。

見出しの体裁が意図しないものになる

  • トラブルシューティング
    • <style> に指定したコマンド(例: \normalfont, \Large, \bfseries など)が LaTeX で正しく定義されているか確認してください。スペルミスやコマンドの存在を確認しましょう。
    • 複数のスタイル指定が競合している可能性があります。不要なスタイル指定を削除したり、順序を変更したりして試してみてください。
    • カスタムフォントを使用している場合は、そのフォントが正しく読み込まれているか確認してください。
    • 他のパッケージのスタイル定義が影響を与えている可能性があります。問題が発生するようになったタイミングで導入したパッケージがあれば、一時的に無効化して確認してみましょう。
  • 原因
    \@startsection の引数 <style> に指定したフォントやサイズ、スタイルに関するコマンドが正しくない、または意図した効果を発揮していない。

見出し前後の空白が意図しないものになる

  • トラブルシューティング
    • これらの引数の値が、意図した垂直方向の距離になっているか確認してください。単位(例: pt, em, ex) の指定ミスがないかも確認しましょう。
    • 負の値を指定した場合の挙動を正しく理解しているか確認してください。特に <afterskip> に負の値を指定すると、次の段落のインデントに影響を与えることがあります。
    • 他のパッケージが余白に関する設定を変更している可能性があります。一時的に問題のありそうなパッケージを無効化して確認してみましょう。
  • 原因
    \@startsection の引数 <beforeskip><afterskip> に不適切な値が設定されている。

セクション番号が意図しない形式になる、または表示されない

  • トラブルシューティング
    • <prefix> にセクション番号を出力するためのコマンド(例: \thechapter.\)が正しく記述されているか確認してください。
    • セクション番号の形式を変更したい場合は、\renewcommand などを用いて関連するカウンタの表示形式(例: \arabic, \roman, \Alph)を変更する必要があります。\thechapter, \thesection などのコマンドがどのように定義されているか確認しましょう。
    • セクション番号が表示されない場合は、\setcounter などでカウンタが意図せず 0 に設定されていないか確認してください。また、\setcounter{secnumdepth}{<level>} の設定で、指定したレベルまでのセクションに番号を振るようになっているか確認してください。
  • 原因
    \@startsection の引数 <prefix> の指定が誤っている、または関連するカウンタ(例: chapter, section)の設定がおかしい。

目次にセクションが正しく登録されない

  • トラブルシューティング
    • カスタムコマンド内で \@startsection を使用している場合は、適切なタイミングで \addcontentsline{toc}{<section-level>}{<heading-text>} を呼び出しているか確認してください。<section-level>chapter, section, subsection など、目次におけるセクションのレベルを指定します。<heading-text> は目次に表示するテキストです。
  • 原因
    \@startsection 自体は目次への登録処理を行いません。通常は、\chapter, \section などの高レベルコマンドの中で \addcontentsline コマンドが呼び出され、目次への登録が行われます。低レベルなカスタマイズで \@startsection を直接使用している場合は、\addcontentsline の呼び出しを忘れている可能性があります。
  • 原因
    複数のカスタマイズやパッケージの相互作用によって、予期しない挙動が発生することがあります。
  • 通常のドキュメント作成においては、\chapter, \section, \subsection などの高レベルコマンドと、それらをカスタマイズするための標準的な方法(例: \title, \author, \date コマンドや \usepackage{titlesec} など)を使用することが推奨されます。
  • 直接 \@startsection を操作する場合は、LaTeX の内部構造を十分に理解している必要があります。安易な変更は、ドキュメントの体裁を大きく崩す可能性があります。
  • \@startsection は LaTeX の内部コマンドであり、その挙動は LaTeX のバージョンや使用しているクラスファイル、パッケージによって異なる場合があります。


例1: @startsection の基本的な挙動の観察

以下の例は、標準的な \section コマンドが内部でどのように \@startsection を呼び出しているかを(概念的に)示すものです。実際の LaTeX カーネルのコードはより複雑ですが、基本的な考え方は理解できるかと思います。

\documentclass{article}
\usepackage{amsmath}

\makeatletter
% \section の内部処理を簡略化したイメージ
\newcommand{\mysection}[1]{%
  \@startsection{section}{1}{\z@}{3.5ex \@plus 1ex \@minus .2ex}{2.3ex \@plus .2ex}{\normalfont\Large\bfseries}{#1}%
}
\makeatother

\begin{document}

\tableofcontents

\section{標準のセクション}
これは標準のセクションです。

\mysection{カスタムセクション}
これは \verb|\mysection| で作成したカスタムセクションです。体裁が標準の \verb|\section| と似ていることに注目してください。

\subsection{標準のサブセクション}
これは標準のサブセクションです。

\end{document}

この例では、\makeatletter\makeatother で囲まれた部分で、内部コマンドである \@startsection を利用した新しいコマンド \mysection を定義しています。

  • \@startsection{section}{1}{\z@}{3.5ex \@plus 1ex \@minus .2ex}{2.3ex \@plus .2ex}{\normalfont\Large\bfseries}{#1}: \@startsection を呼び出しています。各引数の意味は以下の通りです。
    • section: <name>。内部的な識別子です。
    • 1: <level>\section と同じレベル(章の下)であることを示します。
    • \z@: <indent>。左マージンからのインデントはなし(0pt)。
    • 3.5ex \@plus 1ex \@minus .2ex: <beforeskip>。見出しの前の垂直方向の空白。伸縮性のある長さです。
    • 2.3ex \@plus .2ex: <afterskip>。見出しの後の垂直方向の空白。伸縮性のある長さです。
    • \normalfont\Large\bfseries: <style>。通常のフォント、大きなサイズ、太字で整形します。
    • #1: 見出しのテキスト。\mysection に与えられた引数がここに入ります。
  • \newcommand{\mysection}[1]{...}: 引数を一つ取る新しいコマンド \mysection を定義します。

このコードをコンパイルすると、\mysection で作成した見出しは、標準の \section とほぼ同じ体裁で出力されます。ただし、目次への登録など、\section が持つ他の機能は \mysection には実装されていません。

例2: @startsection を利用した番号なしセクションの作成

\@startsection<numberwidth>0pt に設定し、<prefix> を空にすることで、番号なしのセクションを作成できます。

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\nosection}[1]{%
  \@startsection{nosection}{1}{\z@}{3.5ex \@plus 1ex \@minus .2ex}{2.3ex \@plus .2ex}{\normalfont\Large\bfseries}{0pt}{\z@}{}{#1}%
}
\makeatother

\begin{document}

\tableofcontents

\section{標準のセクション}
これは標準のセクションです。

\nosection*{番号なしセクション (目次には登録されない)}
これは \verb|\nosection*| で作成した番号なしセクションです。

\nosection{番号なしセクション (目次に登録される)}
これは \verb|\nosection| で作成した番号なしセクションです。

\subsection{標準のサブセクション}
これは標準のサブセクションです。

\end{document}

この例では、\nosection コマンドを作成しています。

  • \nosection* のように * をつけたコマンドは、通常、目次やヘッダーへの登録を行いません。これは \@startsection の直接の機能ではなく、高レベルコマンドの定義によるものです。上記の例では、\nosection は目次に登録されますが、\nosection* のような機能は別途実装する必要があります(ここでは省略しています)。
  • <prefix> を空にすることで、番号自体が出力されません。
  • <numberwidth>0pt に設定することで、セクション番号のためのスペースをなくしています。

例3: @startsection の引数を変更して体裁をカスタマイズする

以下の例では、<style><beforeskip> などの引数を変更して、セクションの体裁を大きく変えています。

\documentclass{article}
\usepackage{amsmath}
\usepackage{color}

\makeatletter
\newcommand{\fancysection}[1]{%
  \@startsection{fancysection}{1}{\z@}{1.0em}{1.0em}{\color{blue}\itshape\Huge}{#1}%
}
\makeatother

\begin{document}

\tableofcontents

\section{標準のセクション}
これは標準のセクションです。

\fancysection{派手なセクション}
これは \verb|\fancysection| で作成した、青色でイタリック体の巨大なセクションです。

\subsection{標準のサブセクション}
これは標準のサブセクションです。

\end{document}

この例では、\fancysection コマンドを作成し、

  • <beforeskip><afterskip>1.0em に設定することで、見出し前後の空白を小さくしています。
  • <style>\color{blue}\itshape\Huge に設定することで、青色でイタリック体の非常に大きなフォントで見出しを出力します。

これらの例からわかるように、\@startsection の各引数を調整することで、セクション見出しの体裁(フォント、サイズ、色、前後の空白、番号の有無など)を細かく制御することができます。



主な代替方法は以下の通りです。

標準のセクションコマンドと再定義

最も基本的な方法は、LaTeX が標準で提供している \chapter, \section, \subsection などのコマンドを、\renewcommand を用いて再定義することです。ただし、これらのコマンドは内部で \@startsection を呼び出しているだけでなく、目次への登録やヘッダー・フッターへの影響など、より高レベルな機能も持っているため、完全に再定義する場合は注意が必要です。

より一般的なのは、セクション見出しの体裁を制御するためのフックコマンドを利用する方法です。例えば、\section コマンドが \@startsection を呼び出す際に、特定のスタイル設定コマンドを実行するように定義されている場合があります。これらのスタイル設定コマンドを \renewcommand で再定義することで、間接的にセクションの体裁を変更できます。

\documentclass{article}
\usepackage{amsmath}

\renewcommand{\section}{\@startsection{section}{1}{\z@}{3.5ex \@plus 1ex \@minus .2ex}{2.3ex \@plus .2ex}{\normalfont\Large\bfseries\color{red}}}

\begin{document}

\section{再定義されたセクション}
このセクションは赤字で表示されます。

\subsection{標準のサブセクション}
サブセクションは標準のままです。

\end{document}

この例では、\section コマンドの定義を \renewcommand で上書きし、\@startsection<style> 引数に \color{red} を追加しています。これにより、すべての \section の見出しが赤字で表示されるようになります。

titlesec パッケージの利用

titlesec パッケージは、セクション見出しの体裁を柔軟かつ強力にカスタマイズするための非常に一般的なパッケージです。このパッケージを利用すると、\@startsection の各引数に対応する設定項目を、より直感的で高レベルなコマンドを通じて制御できます。

\documentclass{article}
\usepackage{amsmath}
\usepackage{titlesec}
\usepackage{color}

% \section の体裁をカスタマイズ
\titleformat{\section}
  {\normalfont\Large\bfseries\color{blue}} % フォーマット(フォント、サイズ、太字、色)
  {\thesection} % ラベル(番号)
  {1em} % セクション番号とテキストの間の水平方向のスペース
  {} % 見出しテキストの前に行うこと
  {} % 見出しテキストの後に行うこと

% \subsection の体裁をカスタマイズ
\titleformat{\subsection}
  {\normalfont\large\itshape\color{green}}
  {\thesubsection}
  {0.5em}
  {}
  {}

\begin{document}

\tableofcontents

\section{カスタマイズされたセクション}
このセクションは青字で太字で大きく表示されます。

\subsection{カスタマイズされたサブセクション}
このサブセクションは緑字でイタリック体でやや小さく表示されます。

\end{document}

この例では、\titleformat コマンドを使って、\section\subsection の体裁をそれぞれカスタマイズしています。各引数の意味はコメントの通りです。titlesec パッケージは、より複雑なレイアウトや、見出し前後の装飾などを実現するための豊富な機能を提供しています。

クラスファイルのオプションやコマンドの利用

多くの LaTeX クラスファイル(例: article, book, report など)は、セクション見出しの基本的な体裁を制御するためのオプションやコマンドを提供しています。これらのオプションやコマンドを利用することで、クラスファイルが提供する範囲内で、比較的簡単にセクションスタイルを変更できます。

例えば、article クラスにはセクション番号のスタイルを変更するようなオプションはあまりありませんが、book クラスなどでは、章の番号付けに関するオプションなどが提供されている場合があります。

また、クラスファイルによっては、特定のセクションレベルの体裁を変更するための専用コマンドを提供していることもあります。クラスファイルのドキュメントを確認することが重要です。

パッケージによるセクションスタイルの変更

sectsty パッケージなど、特定のセクションスタイルを提供するパッケージを利用することもできます。これらのパッケージは、あらかじめ定義された様々なセクションスタイルを提供しており、簡単にドキュメントの雰囲気を変えることができます。

\documentclass{article}
\usepackage{amsmath}
\usepackage{sectsty}
\usepackage{color}

\sectionfont{\color{red}\Large\bfseries}
\subsectionfont{\color{blue}\itshape\large}

\begin{document}

\section{パッケージでスタイル変更したセクション}
このセクションは赤字で太字で大きく表示されます。

\subsection{パッケージでスタイル変更したサブセクション}
このサブセクションは青字でイタリック体でやや大きく表示されます。

\end{document}

\@startsection はセクション見出し組版の根幹ですが、直接操作する代わりに、以下のより高レベルな方法を利用することが一般的です。

  • sectsty などのセクションスタイル提供パッケージの利用
  • クラスファイルが提供するオプションやコマンドの利用
  • titlesec パッケージによる柔軟なカスタマイズ
  • 標準のセクションコマンドと、体裁制御のためのフックコマンドの再定義