Sphinx
GitHub概要
sphinx-doc/sphinx
The Sphinx documentation generator
トピックス
スター履歴
ドキュメント作成ツール
Sphinx
概要
SphinxはPythonで開発された強力なドキュメント生成ツールです。reStructuredText(rST)をベースとし、APIドキュメント自動生成、学術論文執筆、技術文書作成に特化した豊富な機能を提供します。
詳細
Sphinx(スフィンクス)は2008年にGeorg Brandlによって開発され、Pythonコミュニティの標準的なドキュメントツールとして確立されています。当初はPython公式ドキュメントの作成のために開発され、現在でもPython、Django、Flask等の多くのプロジェクトで使用されています。reStructuredTextマークアップ言語により、構造化された高品質なドキュメントを作成できます。autodoc拡張により、Pythonコードから自動的にAPIドキュメントを生成できます。数学記法、交差参照、索引作成、多言語対応など学術的な文書作成に必要な機能を網羅しています。多様な出力形式(HTML、PDF、ePub、LaTeX等)をサポートし、単一のソースから複数の形式のドキュメントを生成できます。豊富なテーマとエクステンションにより、カスタマイズ性と拡張性を実現しています。Napoleon拡張により、GoogleスタイルやNumPyスタイルのdocstringもサポートします。2025年現在、Read the Docs、Alabaster、Furoなどの人気テーマにより、美しく機能的なドキュメントサイトを構築できます。Sphinx-autodocによるAPI文書自動化、Sphinx-galleryによるサンプル集成、sphinx-needs等の要求管理拡張により、プロフェッショナルなドキュメント作成環境を提供しています。
メリット・デメリット
メリット
- APIドキュメント自動生成: Pythonコードのdocstringから自動的にAPIリファレンス作成
- 多様な出力形式: HTML、PDF、ePub、LaTeX、man等の豊富な出力フォーマット
- 学術文書対応: 数式、引用、索引、交差参照など学術論文作成機能
- 豊富なエクステンション: todo管理、図表生成、テスト実行など多彩な拡張機能
- プロフェッショナル品質: 出版レベルの高品質なドキュメント出力
- テーマシステム: Read the Docs、Alabaster、Furo等の美しいテーマ
- 国際化対応: 多言語ドキュメントの効率的な管理とローカライゼーション
デメリット
- 学習コスト: reStructuredText記法とSphinx設定の習得に時間が必要
- Python依存: Python環境とPythonエコシステムの知識が必要
- 複雑な設定: 高度な機能利用時の設定ファイル(conf.py)の複雑化
- マークダウン非対応: デフォルトではMarkdownサポートなし(拡張で対応可能)
- ビルド時間: 大規模プロジェクトでのドキュメント生成時間の増加
- デザイン制限: テーマカスタマイズにはCSS/HTMLの専門知識が必要
主要リンク
書き方の例
プロジェクトの初期化
# Sphinxのインストール
pip install sphinx
# プロジェクトの作成
sphinx-quickstart docs
# プロジェクト構造
docs/
├── _build/ # 生成されたドキュメント
├── _static/ # 静的ファイル(CSS、JS、画像)
├── _templates/ # カスタムテンプレート
├── conf.py # 設定ファイル
├── index.rst # メインページ
└── make.bat # Windowsビルドスクリプト
基本的なconf.py設定
# Configuration file for the Sphinx documentation builder.
# -- Project information -----------------------------------------------------
project = 'プロジェクト名'
copyright = '2025, 作成者名'
author = '作成者名'
release = '1.0.0'
# -- General configuration ---------------------------------------------------
extensions = [
'sphinx.ext.autodoc', # APIドキュメント自動生成
'sphinx.ext.autosummary', # サマリー自動生成
'sphinx.ext.napoleon', # Google/NumPyスタイルdocstring
'sphinx.ext.viewcode', # ソースコードへのリンク
'sphinx.ext.intersphinx', # 他プロジェクトとの相互参照
'sphinx.ext.mathjax', # 数学記法サポート
'sphinx.ext.githubpages', # GitHub Pages対応
'sphinx.ext.todo', # TODOリスト管理
]
# Templates path
templates_path = ['_templates']
# Language settings
language = 'ja'
# Exclude patterns
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output ------------------------------------------------
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
html_title = 'プロジェクトドキュメント'
html_short_title = 'プロジェクト'
html_logo = '_static/logo.png'
html_favicon = '_static/favicon.ico'
# テーマオプション
html_theme_options = {
'analytics_id': 'G-XXXXXXXXXX',
'logo_only': False,
'display_version': True,
'prev_next_buttons_location': 'bottom',
'style_external_links': False,
'vcs_pageview_mode': '',
'style_nav_header_background': '#2980B9',
'collapse_navigation': True,
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False
}
# -- Options for LaTeX output -----------------------------------------------
latex_elements = {
'papersize': 'a4paper',
'pointsize': '10pt',
'preamble': r'''
\usepackage[utf8]{inputenc}
\usepackage[japanese]{babel}
''',
}
latex_documents = [
('index', 'project.tex', 'プロジェクトドキュメント',
'作成者名', 'manual'),
]
# -- Napoleon settings ------------------------------------------------------
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = True
napoleon_use_rtype = True
# -- Autodoc settings -------------------------------------------------------
autodoc_default_options = {
'members': True,
'member-order': 'bysource',
'special-members': '__init__',
'undoc-members': True,
'exclude-members': '__weakref__'
}
# -- Todo extension settings ------------------------------------------------
todo_include_todos = True
# -- Intersphinx mapping ----------------------------------------------------
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'django': ('https://docs.djangoproject.com/en/stable/', None),
'numpy': ('https://numpy.org/doc/stable/', None),
}
reStructuredTextの基本記法
====================
プロジェクトタイトル
====================
.. contents:: 目次
:depth: 2
概要
====
このプロジェクトは、APIドキュメント生成の例を示しています。
API リファレンス
================
モジュール一覧
--------------
.. autosummary::
:toctree: generated
:recursive:
myproject.core
myproject.utils
myproject.models
詳細API
-------
.. automodule:: myproject.core
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: myproject.models.User
:members:
:special-members: __init__
数式の例
========
インライン数式: :math:`E = mc^2`
ブロック数式:
.. math::
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
注釈とアドモニション
==================
.. note::
これは注意書きです。
.. warning::
これは警告です。
.. tip::
これは便利なヒントです。
.. seealso::
関連情報: :doc:`installation`
コードブロック
==============
Python コード例:
.. code-block:: python
:linenos:
:emphasize-lines: 3,5
def hello_world(name):
"""挨拶関数
Args:
name (str): 名前
Returns:
str: 挨拶メッセージ
"""
return f"Hello, {name}!"
# 使用例
message = hello_world("太郎")
print(message)
テーブル
========
.. csv-table:: 機能比較表
:header: "機能", "対応状況", "備考"
:widths: 30, 20, 50
"自動生成", "✓", "Pythonコードから自動生成"
"テーマ", "✓", "多数のテーマが利用可能"
"PDF出力", "✓", "LaTeX経由でPDF生成"
"多言語", "✓", "国際化機能サポート"
図表
====
.. figure:: _static/architecture.png
:alt: システム構成図
:align: center
:width: 80%
システム全体のアーキテクチャ
相互参照
========
- セクション参照: :ref:`api-reference`
- ドキュメント参照: :doc:`installation`
- 外部参照: :py:func:`json.dumps`
- 用語集: :term:`API`
.. glossary::
API
Application Programming Interface の略
TODOリスト
==========
.. todo::
ユーザー認証機能の実装
.. todolist::
自動APIドキュメント生成
# sample_module.py - サンプルPythonモジュール
"""
サンプルモジュール
このモジュールは、Sphinxのautodoc機能のデモンストレーションです。
"""
from typing import List, Optional, Dict, Any
import json
class DataProcessor:
"""データ処理クラス
様々なデータ処理操作を提供するクラスです。
Attributes:
data (List[Any]): 処理対象のデータリスト
config (Dict[str, Any]): 設定情報
Example:
>>> processor = DataProcessor([1, 2, 3, 4, 5])
>>> result = processor.filter_data(lambda x: x > 3)
>>> print(result)
[4, 5]
"""
def __init__(self, data: List[Any], config: Optional[Dict[str, Any]] = None):
"""コンストラクタ
Args:
data: 処理対象のデータリスト
config: オプション設定。デフォルトは None
Raises:
ValueError: dataが空の場合
"""
if not data:
raise ValueError("データリストは空にできません")
self.data = data
self.config = config or {}
def filter_data(self, condition) -> List[Any]:
"""条件に基づいてデータをフィルタリング
Args:
condition (callable): フィルタリング条件を定義する関数
Returns:
List[Any]: フィルタリング後のデータリスト
Raises:
TypeError: conditionが呼び出し可能でない場合
Note:
この関数は元のデータを変更しません。新しいリストを返します。
Warning:
大量のデータを処理する場合、メモリ使用量に注意してください。
"""
if not callable(condition):
raise TypeError("conditionは呼び出し可能である必要があります")
return [item for item in self.data if condition(item)]
def transform_data(self, transformer) -> List[Any]:
"""データを変換
Args:
transformer (callable): 変換関数
Returns:
List[Any]: 変換後のデータリスト
"""
return [transformer(item) for item in self.data]
def save_to_json(self, filename: str) -> None:
"""データをJSONファイルに保存
Args:
filename: 保存先ファイル名
Raises:
IOError: ファイル書き込みに失敗した場合
"""
try:
with open(filename, 'w', encoding='utf-8') as f:
json.dump(self.data, f, ensure_ascii=False, indent=2)
except Exception as e:
raise IOError(f"ファイル保存に失敗: {e}")
def calculate_statistics(data: List[float]) -> Dict[str, float]:
"""統計情報を計算
数値リストから基本的な統計値を計算します。
Args:
data: 数値のリスト
Returns:
統計情報を含む辞書
* mean: 平均値
* median: 中央値
* std: 標準偏差
* min: 最小値
* max: 最大値
Raises:
ValueError: dataが空または数値でない場合
Example:
>>> stats = calculate_statistics([1, 2, 3, 4, 5])
>>> print(f"平均: {stats['mean']}")
平均: 3.0
See Also:
:py:class:`DataProcessor`: より高度なデータ処理機能
"""
if not data:
raise ValueError("データリストが空です")
if not all(isinstance(x, (int, float)) for x in data):
raise ValueError("すべての要素が数値である必要があります")
n = len(data)
mean = sum(data) / n
sorted_data = sorted(data)
# 中央値の計算
if n % 2 == 0:
median = (sorted_data[n//2 - 1] + sorted_data[n//2]) / 2
else:
median = sorted_data[n//2]
# 標準偏差の計算
variance = sum((x - mean) ** 2 for x in data) / n
std = variance ** 0.5
return {
'mean': mean,
'median': median,
'std': std,
'min': min(data),
'max': max(data)
}
Sphinx拡張の作成
# sphinx_extension_example.py - カスタムSphinx拡張
from docutils import nodes
from docutils.parsers.rst import Directive
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective
class TodoDirective(SphinxDirective):
"""カスタムTODOディレクティブ"""
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
option_spec = {
'priority': str,
'assigned': str,
'due': str,
}
def run(self):
"""ディレクティブの実行"""
env = self.state.document.settings.env
# TODOノードの作成
todo_node = todo('')
todo_node['priority'] = self.options.get('priority', 'medium')
todo_node['assigned'] = self.options.get('assigned', '')
todo_node['due'] = self.options.get('due', '')
# コンテンツの解析
self.state.nested_parse(self.content, self.content_offset, todo_node)
# 環境にTODOを追加
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
env.todo_all_todos.append({
'docname': env.docname,
'lineno': self.lineno,
'todo': todo_node.deepcopy(),
'target': nodes.target(),
})
return [todo_node]
class todo(nodes.Admonition, nodes.Element):
"""TODOノードクラス"""
pass
def visit_todo_node(self, node):
"""TODOノードの訪問(HTML出力)"""
priority = node.get('priority', 'medium')
assigned = node.get('assigned', '')
due = node.get('due', '')
attrs = {'class': f'todo priority-{priority}'}
self.body.append(self.starttag(node, 'div', **attrs))
# ヘッダー情報の追加
self.body.append('<div class="todo-header">')
self.body.append(f'<span class="todo-priority">優先度: {priority}</span>')
if assigned:
self.body.append(f'<span class="todo-assigned">担当: {assigned}</span>')
if due:
self.body.append(f'<span class="todo-due">期限: {due}</span>')
self.body.append('</div>')
def depart_todo_node(self, node):
"""TODOノードの退出(HTML出力)"""
self.body.append('</div>\n')
def purge_todos(app, env, docname):
"""ドキュメント削除時のTODOクリーンアップ"""
if not hasattr(env, 'todo_all_todos'):
return
env.todo_all_todos = [todo for todo in env.todo_all_todos
if todo['docname'] != docname]
def merge_todos(app, env, docnames, other):
"""環境マージ時のTODO統合"""
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
if hasattr(other, 'todo_all_todos'):
env.todo_all_todos.extend(other.todo_all_todos)
def process_todo_nodes(app, doctree, fromdocname):
"""TODOノードの後処理"""
if not app.config.todo_include_todos:
for node in doctree.traverse(todo):
node.parent.remove(node)
def setup(app: Sphinx):
"""拡張のセットアップ"""
app.add_config_value('todo_include_todos', False, 'html')
app.add_node(todo,
html=(visit_todo_node, depart_todo_node),
latex=(visit_todo_node, depart_todo_node),
text=(visit_todo_node, depart_todo_node))
app.add_directive("todo", TodoDirective)
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
app.connect('env-merge-info', merge_todos)
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
テーマカスタマイズ
# カスタムテーマ設定(conf.py内)
# -- HTML output options ----------------------------------------------------
html_theme = 'sphinx_rtd_theme'
# カスタムCSS
html_css_files = [
'custom.css',
]
# カスタムJavaScript
html_js_files = [
'custom.js',
]
# テーマオプションの詳細設定
html_theme_options = {
# サイト設定
'analytics_id': 'G-XXXXXXXXXX',
'analytics_anonymize_ip': False,
# ロゴとタイトル
'logo_only': False,
'display_version': True,
# ナビゲーション
'prev_next_buttons_location': 'bottom',
'style_external_links': False,
'vcs_pageview_mode': '',
# サイドバー
'collapse_navigation': True,
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False,
# 外観
'style_nav_header_background': '#2980B9',
}
# サイドバーの設定
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html',
'searchbox.html',
'donate.html',
]
}
自動デプロイ設定
# .github/workflows/docs.yml - GitHub Actions
name: Build and Deploy Documentation
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Install dependencies
run: |
pip install -r docs/requirements.txt
- name: Build documentation
run: |
cd docs
sphinx-build -b html . _build/html
- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_build/html
開発ワークフロー
# 開発サーバーの起動(自動再ビルド)
sphinx-autobuild docs docs/_build/html
# 標準的なビルドコマンド
cd docs
make html # HTML生成
make latexpdf # PDF生成
make epub # ePub生成
make man # manページ生成
# 特定ファイルのみ再ビルド
sphinx-build -b html -a docs docs/_build/html
# クリーンビルド
make clean
make html
# APIドキュメントの自動生成
sphinx-apidoc -o docs/source myproject
# 多言語対応ビルド
make gettext # 翻訳テンプレート生成
sphinx-intl update -p docs/_build/gettext -l ja # 日本語対応
make -e SPHINXOPTS="-D language='ja'" html # 日本語版生成