📖

MkDocsによるドキュメント作成

2021/02/22に公開
1

📌 はじめに

mkdocs は 静的サイトジェネレータです。コンテンツは基本的に markdown 形式で記述したソースファイルになります。またHTML形式のファイルを使うことも出来ます。この記事では Windows で個人的な最低限の作成環境をまとめました。

MkDocs

📌 mkdocs のインストール

python をインストールします。今回は 3.9 で試しました。なお、私の環境は Windows+miniconda で構築しています。

次に pip を使って mkdocs をインストールします。

pip install mkdocs

動作環境は次のとおりです。

python                       3.9.5
mkdocs                       1.4.2
mkdocs-material              8.5.11
mkdocs-material-extentions   1.1.1
pymdown-extensions           9.9

📌 プロジェクトの作成

実行に必要な最低限のフォルダとファイルを作成するコマンドが用意されています。例えば test というプロジェクトを作成する場合は以下のコマンドを実行します。

mkdocs new test

実行したカレントフォルダに test というフォルダが作られ、その中にも初期ファイルが作成されます。今後、mkdocs のコマンドを実行する場合は プロジェクトフォルダ(test)に作業ディレクトリにしておきます。

コンテンツのソースファイルは docs フォルダに入れます。(設定で別のフォルダに変更することが出来ます)

📌 ビルド

サイトに必要なファイルを生成するにはビルドを行います。ビルドは以下のコマンドを実行します。

mkdocs build

正常に生成されると site フォルダに作成されます。インターネット上に公開する場合はこのフォルダ内をアップロードします。

ビルドした内容を公開する前に、ローカルで確認したい場合は serve コマンドを実行し、サーバーを起動します。

mkdocs serve

コマンドの出力に Serving on http://127.0.0.1:8000 のようにアドレスとポート番号が表示されますので、そのアドレスをブラウザに入力して確認することが出来ます。

serve を実行している間はファイルの追加や変更が検知されて自動的にビルドされます。

📌 mkdocs.yml

mkdocs.yml ファイルを編集することでドキュメントの構成やカスタマイズを行うことができます。このファイルにはサイトのタイトルやテーマ、拡張機能の設定などを記述します。プロジェクトの作成を行うと、このファイルは自動で作成されます。

📌 ドキュメントの構成

mkdocs.ymlのnavに指定します。例えば次のようになります。

nav:
  - 初期画面: index.md
  - introduction.md
  - material.md
  - section1:
      section1-1:
        section1-1-1:
          section1-1-1.md
      section1-2:
        section1-2-1:
          section1-2-1.md
  - section2:
    - page2-1.md
    - page2-2.md

📌 カスタマイズ

ここからがメインになります。デフォルトの状態でも悪くはないのですが、便利な機能を追加したり、見た目をもっと美しくしたりすることでそれなりに満足できるドキュメントが作成できるような環境を構築します。

📌 Materialテーマ

mkdocs にはテーマの機能があります。率直に言って、標準のテーマやreadthedocsもイマイチなので、テーマを自作しないのであればMaterialテーマ1択だと思います。このドキュメントではMaterialテーマを使用することを前提とします。

このテーマを使う場合はインストールする必要があります。以下のコマンドを実行してインストールします。

pip install mkdocs-material

そして mkdocs.yml で theme に material を指定します。

theme:
  name: material

📌 カラー

テーマカラーを指定できます。指定できるカラーは次のとおりです。

red, pink, purple, deep purple, indigo,
blue, light blue, cyan, teal,
green, light green, lime, yellow, 
amber, orange, deep orange, brown,
grey, blue grey, black,, white

テーマカラーは theme.palette.primary で指定します。

theme:
  palette:
    primary: pink

ライトテーマやダークテーマといったようにテーマを切り替えるボタンを追加できます。
次のように指定します。

theme:
  palette:
    - scheme: default
      primary: pink
      toggle:
        icon: material/brightness-7
        name: Switch to dark mode
    - scheme: slate
      toggle:
        icon: material/brightness-4
        name: Switch to light mode

検索ボックスの左側にテーマを切り替えるボタンが追加され、ボタンを押すとテーマを切り替えることができます。
各テーマごとに色をcssで調整することもできます。

[data-md-color-scheme=default] {
  --md-default-fg-color--light: #222 !important;
}
[data-md-color-scheme=slate] {
  --md-default-fg-color--light: #fefefe !important;
  --md-typeset-a-color: #fc0 !important;
}

📌 フォント

通常フォントと固定幅フォントをそれぞれ指定できます。フォントはGoogleFontにあるものを指定できます。必要なcssファイルも自動で設定してくれますので、カスタムcssで登録する必要はありません。

theme:
  font:
    text: Noto Sans JP
    code: Inconsolata

📌 言語

複数の言語を指定できます。

extra:
  alternate:
    - name: English
      link: /en/
      lang: en
    - name: Japanese
      link: /
      lang: ja

検索ボックスの隣に言語を切り替えるボタンが追加されます。各ドキュメントはリンク先になるように配置すればよいようです。

📌 ロゴ、ファビコン、ホームページ

それぞれ、次のように設定できます。

theme:
  logo: assets/logo.png
  favicon: images/favicon.png

extra:
  homepage: https://example.com

📌 クッキー使用の同意

一般データ保護規則(GDPR)によりEU圏内からのアクセスがあった場合にサイトでCookieを利用して情報収集している場合は確認を取る必要があります。Googleアナリティクスなどを使用していれば必要になります。
Materialテーマにはクッキーの使用について同意するポップアップを表示する機能が用意されています。使い方は次のようになります。

extra:
  consent:
    title: Cookie consent
    description:
      We use cookies to recognize your repeated visits and preferences, as well
      as to measure the effectiveness of our documentation and whether users
      find what they're searching for. With your consent, you're helping us to
      make our documentation better.

標準でGoogleアナリティクスとGitHubが有効になっています。追加したい場合は extra.content.cookies で指定します。

extra:
  consent:
    cookies:
      analytics: Custom name

他に、ポップアップのボタンをカスタマイズできます。通常は「承認」と「管理」が表示されます。それ以外だと「拒否」があります。

extra:
  consent:
    actions:
      - accept
      - manage
      - reject

📌 ナビゲーション

🔹タブ

タブは theme.features で有効にします。

theme:
  features:
    - navigation.tabs

トップレベルのセクションがタブになります。画面をスクロールするとタブ画面が隠れますが、常に表示したい場合は navigation.tabs.sticky を追加します。

theme:
  features:
    - navigation.tabs
    - navigation.tabs.sticky

🔹セクションの折り畳み

階層が深いコンテンツの場合、サイドバーにあるセクション一覧で折り畳む機能が入っています。それを無効にして全てフラットに表示したい場合、navigation.sections を指定します。

theme:
  features:
    - navigation.sections

また、navigation.expandを指定すると、最初からすべて展開された状態になります。

theme:
  features:
    - navigation.expand

セクションごとにインデックスページを指定する場合、navigation.indexes を指定します。

theme:
  features:
    - navigation.indexes

ドキュメントの構成は次のようにします。

nav:
  - Section:
    - section/index.md
    - Page 1: section/page-1.md
    - Page 2: section/page-2.md

この場合、section/index.mdがセクションの項目に統合されます。

🔹トップに戻るボタン

navigation.topを追加します。確認したところ、常時ではなく上方向にスクロールしたときに表示されます。

theme:
  features:
    - navigation.top

🔹サイドバーを無効化

タブを有効にしているなど、サイドバーを無効にしたい場合、コンテンツ側で次のように指定します。

---
hide:
  - navigation
---

📌 検索

プラグインとして実装されました。検索プラグインは標準で入っています。日本語検索を有効にする場合は次のようにします。

plugins:
  search:
    lang: 'ja'

📌 Googleアナリティクス

Googleアナリティクスは次のように設定します。

extra:
  analytics:
    provider: google
    property: UA-XXXXXXXX-X

📌 ブログ

まだ実験段階ですが、ブログ機能がプラグインとして実装されているようです。今はスポンサーのみ使用することができるようです。興味のある人はSetting up a blogを参照してください。

📌 ヘッダーとフッター

タイトルバー

タイトルバーは常時表示されますが、header.autohideを有効にすることで隠れるようになります。

theme:
  features:
    - header.autohide

🔹ソーシャルリンク

TwitterやFacebook、GitHubなどのアイコンを設定できます。

extra:
  social:
    - icon: fontawesome/brands/twitter
      link: https://twitter.com/mebiusbox2
      name: mebiusbox2 on Twitter
    - icon: fontawesome/brands/github
      link: https://github.com/mebiusbox/MkDocsTest

🔹著作権表記

次のように指定します。最初に © とする場合はダブルクォーテーションで囲みます。

site_name: Mkdocs Test
copyright: "© 2022 mebiusbox"

🔹ジェネレータの表記

フッターにMkDocsで生成されたことが自動で表示されますが、これを非表示にできます。

extra:
  generator: false

🔹Prev/Nextリンクの非表示

各ページには前/次のページリンクが表示されますが、これを非表示にしたい場合、ページ側で指定します。

---
hide:
  - footer
---

🔹Gitリポジトリリンクの設定

右上にGitリポジトリのリンクを追加できます。自動でスター数とフォーク数が表示されます。

repo_url: https://github.com/mebiusbox/MkDocsTest
repo_name: mebiusbox/MkDocsTest

アイコンを変更したい場合、次のようにします。

theme:
  icon:
    repo: fontawesome/brands/github

例えば、GitLabアイコンにしたい場合は次のようになります。

theme:
  icon:
    repo: fontawesome/brands/gitlab

📌 コメント機能

giscusがサポートされています。手順としては次のようになります。

  1. (GitHubで) 対象のリポジトリにgiscusアプリをインストールする(GitHubをフリー版で利用しているならパブリックである必要があります)
  2. (GitHubで)リポジトリのDiscussionsを有効にする
  3. giscusで必要な情報を入力する。設定は特に必要がなければ初期のままでいいです。「giscusを有効にする」のところに表示されるコードをコピーする
  4. (MkDocsで) カスタムテーマを有効にする
  5. (MkDocsで) コメントのテンプレートを編集してペーストする

カスタムテーマを有効にするには次のようにします。

theme:
  custom_dir: overrides

コメントテンプレート(overrides/partials/comments.html)ファイルを作成して、以下をペーストします。

{% if page.meta.comments %}
  <h2 id="__comments">{{ lang.t("meta.comments") }}</h2>
  <!-- Insert generated snippet here -->

  <!-- Synchronize Giscus theme with palette -->
  <script>
    var giscus = document.querySelector("script[src*=giscus]")

    /* Set palette on initial load */
    var palette = __md_get("__palette")
    if (palette && typeof palette.color === "object") {
      var theme = palette.color.scheme === "slate" ? "dark" : "light"
      giscus.setAttribute("data-theme", theme) 
    }

    /* Register event handlers after documented loaded */
    document.addEventListener("DOMContentLoaded", function() {
      var ref = document.querySelector("[data-md-component=palette]")
      ref.addEventListener("change", function() {
        var palette = __md_get("__palette")
        if (palette && typeof palette.color === "object") {
          var theme = palette.color.scheme === "slate" ? "dark" : "light"

          /* Instruct Giscus to change theme */
          var frame = document.querySelector(".giscus-frame")
          frame.contentWindow.postMessage(
            { giscus: { setConfig: { theme } } },
            "https://giscus.app"
          )
        }
      })
    })
  </script>
{% endif %}

このコードにある <!-- Insert generated snippet here --> の下に、giscusでコピーしたコードをそのまま貼り付けます。これで設定完了です。

📌 GitHub Pages

mkdocs には GitHub Pages にデプロイするコマンドが用意されています。

GitHub でリポジトリを作成し、クローンして mkdocs のプロジェクトを構築して、以下のコマンドを実行します。

mkdocs gh-deploy

これだけでデプロイすることが出来ます。

🔹GitHub Actionsを使ったデプロイ

GitHub Actionsを使ってリポジトリからビルドして公開するには、GitHub Actionsのワークフローファイル(.github/workflows/ci.yml)を作成します。

name: ci 
on:
  push:
    branches:
      - master 
      - main
permissions:
  contents: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: 3.x
      - run: pip install mkdocs-material
      - run: mkdocs gh-deploy --force

CIが正常終了すれば、<username>.github.io/<repository>に配置されます。

📌 数式

数式を使うことができます。いくつか設定が必要になります。まず、javascriptファイルを用意します。ここでは docs/js/mathjax.js とします。

window.MathJax = {
  tex: {
    inlineMath: [["\\(", "\\)"]],
    displayMath: [["\\[", "\\]"]],
    processEscapes: true,
    processEnvironments: true
  },
  options: {
    ignoreHtmlClass: ".*|",
    processHtmlClass: "arithmatex"
  }
};

document$.subscribe(() => {
  MathJax.typesetPromise()
})

次にmkdocs.ymlでjavascriptファイルを追加します。

extra_javascript: 
  - js/mathjax.js
  - https://polyfill.io/v3/polyfill.min.js?features=es6
  - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js

そして、数式拡張機能を有効にします。

markdown_extensions:
  - pymdownx.arithmatex:
      generic: true

これで設定完了です。数式は、ブロックの場合 $$...$$\[...\]、インラインの場合 $...$\(...\) とします。

$$
P\cdot Q = \|P\|\|Q\|\cos\alpha \tag{1}
$$

📌 警告文

拡張機能 Admonition を使うと、文書内にメモ、ヒント、警告などが目立つようなスタイルで表示してくれます。Admonition も含め、これから紹介する機能は material テーマをインストールすると一緒にインストールされます。

使う場合は mkdocs.yml で使うように指定します。

markdown_extensions:
  - admonition

マークダウンでは !!! Note のように使います。
例えば以下のような内容の場合:

!!! Note
    これはノートです。

!!! Tip
    ヒントです。

!!! Warning
    これは警告です
    
!!! Danger
    これは危険です。

!!! Success
    これは成功です。

!!! Failure
    これは失敗です。

!!! Bug
    これはバグです。

!!! summary
    これは概要です。

📌 詳細ブロック

警告文拡張機能に似ていますが、こちらは折り畳みブロックです。詳細ブロックでは !!! の代わりに ??? を使います。

markdown_extensions:
  - pymdownx.details
??? Note
    これはノートです。

??? Tip
    ヒントです。

📌 定義リスト

定義リストは定義語のリストを作成する拡張機能です。この拡張機能を使用するには def_list を追加する必要があります。

markdown_extensions:
  - def_list

使い方は以下のようになります。

定義語
:    ここに説明を書きます

これは次のように表示されます。

📌 注釈

拡張機能 footnotes を使います。使用する場合、footnotes を有効にします。

markdown_extensions:
  - footnotes

注釈をつけるには、つけたい言葉の後ろに [^1] のように記述します。

Mkdocs とは静的サイトジェネレータです。
コンテンツは基本的に markdown[^1] 形式で記述したソースファイルになります。

[^1]: 文書を記述するための軽量マークアップ言語のひとつ

上記の場合、次のように表示されます。

2017-05-04_21h26_47

📌 アイコンと絵文字

ドキュメント中にアイコンや絵文字を使うことができます。アイコンには以下のものが使えます。

使用するには、次のようにします。

markdown_extensions:
  - attr_list
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_svg

次のように使います。

:material-at: 
:woman_gesturing_no:
:simple-dogecoin:
:fontawesome-regular-face-laugh-wink:
:octicons-link-external-16: [MkDocs](http://www.mkdocs.org/)

絵文字は次のように使います。

ここに \:smile: と記述すると :smile: になります

2017-05-06_18h55_26

絵文字の種類を確認する場合は以下のサイトが便利です。

EMOJI CHEAT SHEET

📌 SmartSymbols

SmartSymbols を使うと一部のシンボルを特定の文字の組み合わせで変換してくれます。拡張機能リストに pymdownx.smartsymbols を追加します。

markdown_extensions:
  - pymdownx.smartsymbols

2017-05-06_19h25_56

拡張機能を有効にした状態だと、上記の特定文字に一致するところがすべて変換されてしまいます。ですが、個別に有効・無効を設定することができます。詳しくは以下を参照してください。

SmartSymbols

📌 Keys

PCでのキーボード操作を説明するときにキーコードを解りやすく装飾してくれる拡張機能です。ただし、material テーマのみ使えます。使用するには拡張機能リストに pymdownx.keys を追加します。

markdown_extensions:
  - pymdownx.keys

使い方は以下のようになります。

詳細は以下を参照してください。

Keys

📌 コードハイライト

コードハイライトを有効にするには次のようにします。

markdown_extensions:
  - pymdownx.highlight:
      use_pygments: true
      noclasses: true
      pygments_style: monokai
      linenums: true

pygmentsを使ってハイライトをしないのであれば、use_pygments, noclasses, pygments_style は不要です。

コードは fenced code blocks (` ` `) バッククォートを書いて囲みます。

    ```
    #include <iostream>
    void main() {
      std::cout << "Hello world!" << std::endl;
    }
    ```

mkdocs-codehilite

行番号を表示する場合は linenums を設定します。コードの表示では前後のスペース(マージン)をなくして表示しているものをよく見るようになりました。そこでスタイルシートを使って対応してみます。次のような内容をスタイルシートに追加します。

.md-typeset pre {
  color: #f8f8f2;
}
.md-typeset .highlighttable {
  margin-left:-20px;
  margin-right: -20px;
  border-radius: 0;
}
.md-typeset .highlighttable > * {
  --md-code-bg-color: #222 !important;
  --md-code-fg-color: #fefefe !important;
}
.md-typeset .highlighttable .linenos .linenodiv pre span {
  background-color: #222 !important;
  color: #fefefe !important;
}
.md-typeset .highlighttable .md-clipboard:before,
.md-typeset .highlighttable .md-clipboard:after {
  color: rgba(240,240,240,.8);
}
.md-typeset .highlighttable .md-clipboard:hover:before,
.md-typeset .highlighttable .md-clipboard:hover:after {
  color: rgba(102,217,224,1);
}

これを適用すると次のように表示されます。

行番号が場合によってコードとずれる場合があります。その場合もcssで調整します。

.md-typeset .highlighttable .linenos .linenodiv pre {
  line-height: 15pt;
}

コード番号の表示をブロックごとに変えたい場合は linenums を使います.

```c++ linenums="1"
#include <iostream>
void main() {
std::cout << "Hello world!" << std::endl;
}
```
```c++ linenums="0"
#include <iostream>
void main() {
std::cout << "Hello world!" << std::endl;
}
```

また、個別に行をハイライト表示できます.hl_linesで行を指定します.

```c++ hl_lines="2 3"
#include <iostream>
void main() {
std::cout << "Hello world!" << std::endl;
}
```

📌 コードフェンス

さまざまなブロックをネストして使用できるようになります。

markdown_extensions:
  - pymdownx.superfences

コードフェンスを使えば次のような書き方ができます。

!!! Note
    ここは注釈ブロックです。

    ```yml
    markdown_extensions:
      - pymdownx.superfences
    ```

また、コードフェンスの機能を使ってMermaidで作図できます。

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format

次のように使います。

``` mermaid
graph LR
A[Start] --> B{Error?};
B -->|Yes| C[Hmm...];
C --> D[Debug];
D --> B;
B ---->|No| E[Yay!];
```

``` mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
    John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```

📌 タスクリスト

markdown_extensions:
  - pymdownx.tasklist:
      custom_checkbox: true
      clickable_checkbox: true

custom_checkboxを有効にするとチェックボックスの見た目が良くなります(推奨らしいです)。clickable_checkboxを有効にするとクリックで切り替えられるようになります(どこかに保存されるわけではないのでページを再読み込みすればリセットされます).

- [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit
- [ ] Vestibulum convallis sit amet nisi a tincidunt
    * [x] In hac habitasse platea dictumst
    * [x] In scelerisque nibh non dolor mollis congue sed et metus
    * [ ] Praesent sed risus massa
- [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque

📌 タブブロック

ドキュメント内でタブがついたブロックを作ることができます。

markdown_extensions:
  - pymdownx.tabbed:
      alternate_style: true

次のように使います。

=== "Unordered list"

    * Sed sagittis eleifend rutrum
    * Donec vitae suscipit est
    * Nulla tempor lobortis orci

=== "Ordered list"

    1. Sed sagittis eleifend rutrum
    2. Donec vitae suscipit est
    3. Nulla tempor lobortis orci

📌 ボタン

markdown_extensions:
  - attr_list

次のように使います。

[Subscribe to our newsletter](#){ .md-button }

[Subscribe to our newsletter](#){ .md-button .md-button--primary }

📌 見出しのカスタマイズ

見出しは先頭にアイコンをつけたり,下線を追加すると格段に見やすくなります。ここでは material テーマに対して見出しを調整します。

まず,アイコンは Font Awesome を使えば画像を用意しなくても表示することができます。例えば次のようなアイコンを指定してみます。

<i class="fa fa-arrow-circle-right" aria-hidden="true"></i>

そうすると以下のように表示されます。

mkdocs-header-custom-50

続いて見出しを調整します。個人的に GitLab Documentation が見やすいのでそれを真似てみます。スタイルシートに以下を追加します。

.md-typeset h1 {
  /*font-size: 24pt;*/
  font-weight: bold;
  color: #000;
  border-bottom: solid 2px #f18b21;
  padding-bottom: 5px;
}
.md-typeset h2 {
  border-bottom: 1px dotted #888;
}

フォントサイズはお好みのサイズを指定してください。これは次のように表示されます。

mkdocs-header-custom-css-50

見出しにアイコンを入れるのは面倒なのでcssで設定する方法は次のとおりです。

.md-typeset h3:before {
  font-family: "FontAwesome";
  font-weight: 900;
  content: "\f0a9";
  margin-right: 5px;
}

📌 PDF 出力

以前はMkDocsでPDF出力をあれこれ挑戦しましたが、無理にMkDocsで出力するのはやめた方がいいです。もし、PDFを出力したいのなら、印刷をそれなりにサポートしているドキュメントシステムを利用しましょう。例えば、Sphinxやmdbookなどです。

📌 サンプルプロジェクト

以下にリポジトリがあります。また、デプロイ先のリンクも記載してありますので、参考にしてください。

Discussion

heg_podheg_pod

ローカルPCで立ち上げて日記として使い始めたのですが、こちらの記事のおかげで一気に自分好みのスタイルと機能を備えたものになりました。ありがとうございます。