Guidedog マニュアル 0.2.0
言語
このページの内容
Guidedog / ドキュメント 0.2.0

テンプレート

テンプレートは表示を決めるもので、本文を複製するものではありません。Guidedog は HTML に Jinja、PDF に Typst を使います。

Guidedog のテンプレートは普通のプロジェクトファイルです。自由に開いて編集できます。guidedog quickstart は実際に使うテンプレートをプロジェクトに配置します。

  • _templates/layout.html は Jinja で HTML サイトの構造を定義します。
  • _templates/book.typ は Typst で PDF のレイアウト、文字組み、表紙を定義します。
  • _static/guidedog.css と _static/guidedog.js は既定のスタイルとブラウザーの動作を提供します。

テンプレートは外部パッケージやバイナリのキャッシュではなく、プロジェクト内にあります。編集後、guidedog build で再ビルドし、guidedog serve で確認できます。

HTML テンプレート

Guidedog は内蔵の Jinja エンジンで layout.html を描画します。一つの巨大なファイルにする必要はありません。部分テンプレート、マクロ、段階的な継承に分けられます。

テンプレートの分割

templates_path のディレクトリ内で、テンプレートを複数のファイルやサブディレクトリに分けられます。初期値は ["_templates"] です。

my-docs/
├── conf.toml
├── index.rst
└── _templates/
    ├── layout.html
    ├── base.html
    ├── partials/
    │   ├── header.html
    │   ├── navigation.html
    │   ├── searchbox.html
    │   └── footer.html
    └── macros/
        └── components.html

Guidedog は templates_path のファイルとサブディレクトリを走査します。取り込みやインポートには、そのディレクトリからの相対パスを使います。

リスト 1 _templates/layout.html
{% extends "base.html" %}

{% block header %}
  {% include "partials/header.html" %}
{% endblock %}

{% block footer %}
  {% include "partials/footer.html" %}
{% endblock %}

Jinja マクロも別ファイルに定義し、必要な場所でインポートできます。

リスト 2 _templates/macros/components.html
{% macro badge(label, type="info") %}
  <span class="badge badge-{{ type }}">{{ label }}</span>
{% endmacro %}
リスト 3 テンプレートでマクロを使う
{% import "macros/components.html" as ui %}
{{ ui.badge("New", type="success") }}

!layout.html によるテーマの継承

既定のテーマの一部分だけを変えるなら、ページ全体を書き直す必要はありません。Sphinx と同じ感嘆符の構文で、組み込みのレイアウトを継承できます。

リスト 4 _templates/layout.html
{# Inherit Guidedog's built-in layout #}
{% extends "!layout.html" %}

{# Inject custom metadata or web fonts into the document head #}
{% block extrahead %}
  {{ super() }}
  <link rel="stylesheet" href="{{ pathto('_static/custom.css', 1) }}">
{% endblock %}

{# Replace or extend the footer with custom content #}
{% block footer %}
  {% include "partials/footer.html" %}
{% endblock %}

{% extends "!layout.html" %} または {% extends "basic/layout.html" %} は、プロジェクトの _templates/layout.html を再帰的に読む代わりに、テーマ本来のテンプレートを読み込みます。

上書きしたブロックで {{ super() }} を呼べば、親の内容を残したまま前後に要素を追加できます。

レイアウトのブロック

組み込みの layout.html は Sphinx の慣例に対応するブロックを定義します。

ブロック 用途
doctype 文書型宣言。初期値は <!DOCTYPE html> です。
htmltitle <head> 内の <title> 要素。
linktags ナビゲーションとメタ情報のリンク: favicon、index、search、prev、next。
css スタイルシートのリンクとインライン CSS のルート変数。
scripts 検索インデックスや対話機能の JavaScript タグ。
extrahead フォント、解析ツール、追加メタタグ用の <head> 末尾の挿入位置。
header メインナビゲーションの直前に置くヘッダー。
relbar1 名称、バージョン、検索、テーマ切替を含む上部ナビゲーション。
rootrellink 関連リンクの前にあるナビゲーションの挿入位置。
relbaritems ナビゲーションバーの追加項目。
sidebar1 左のナビゲーションサイドバー。
sidebartoc sidebar1 内の目次ツリー。
breadcrumbs 本文上部のパンくずナビゲーション。
document 本文を囲むコンテナ。
body 現在の文書の HTML 本文({{ body }})。
relbar2 前後の章へ移動する下部ナビゲーション。
footer 著作権、更新日時、ソースへのリンクを含むフッター。
sidebar2 右側の補助欄。ページ内の見出し一覧を表示します。

テンプレートの検索

Guidedog は conf.toml の templates_path を順に検索し、最後に組み込みテンプレートを調べます。名前は各ディレクトリからの相対パスで、.. による外部への移動はできません。

templates_path のファイルとサブディレクトリはすべてビルドの依存入力です。追加、編集、削除を guidedog build と guidedog serve が検出し、サイトを再描画します。

ページ変数

Sphinx に変数名がある場合は同じ名前を使うため、Sphinx テーマの一部を移行できます。

変数 値
body HTML 形式の文書。
title 文書のタイトル。
pagename, docname 文書名。例は usage/install。文書でないページでは docname は空、pagename は Sphinx 同様に genindex、py-modindex、search、テンプレート生成ページの名前となる。
toc 目次ツリーから作る HTML のナビゲーション。
outline 文書内の節を HTML で示します。節がなければ空です。
prev, next 読む順で前後にあるページです。url(link も可)と title を持ち、端では存在しません。
project, version, release, copyright, language 同名の設定値。
html_title, docstitle html_title。既定値は「<project> <release> documentation」です。
html_short_title, shorttitle html_short_title.
root_doc, master_doc ルート文書の名前。
pathto_root ページからサイトのルートへのパスです。例は ../。
root_url, search_url, genindex_url ルートページ、検索ページ、総合索引へのリンク。
css_files, js_files url を持つファイルのリストです。Guidedog のファイルの後に html_css_files と html_js_files を並べます。
logo_url, favicon_url _static 内の html_logo と html_favicon です。未設定なら空です。
accent テーマの色 html_theme_options.accent。
sourcelink_url ソース表示が有効なら _sources 内の文書ソース、それ以外は空です。
last_updated html_last_updated_fmt があれば、その書式のビルド日付です。なければ空です。
show_copyright, show_sphinx, show_guidedog, has_source, show_source html_show_* と html_copy_source の設定。
builder, file_suffix html などのビルダー名とページの拡張子。
html_context の各キー 型を保った値を、Sphinx が Python 値を渡すように渡す。false は {% if %} で偽、数値は数値、配列はリスト、テーブルは conf.toml のキー順を保つ辞書となる。guidedog migrate は conf.py の html_context のリテラルを引き継ぐ。計算値は未定義となり、テンプレートは偽と扱う。

pathto は Sphinx のテンプレート関数。pathto("usage/install") は文書ページ、pathto("_static/logo.svg", 1) はサイト配下のファイルの URL を現在のページからの相対で返す。singlehtml では Sphinx 同様、文書は一ページの節となる。前者はそのページでは #document-usage-install、索引や検索では index.html#document-usage-install。genindex やテンプレートページなど文書以外の名前は、どのビルダーでもサイト直下のページを指す。

テンプレートから作るページ

html_additional_pages は Sphinx 同様、テンプレートだけでページを作る。キーはページ名、値は templates_path 内のテンプレート。

リスト 5 conf.toml
root_doc = "contents"

[html_additional_pages]
index = "indexcontent.html"
download = "download.html"

通常は layout.html を継承してブロックを埋め、他のページと見た目を揃える。

リスト 6 _templates/indexcontent.html
{% extends "layout.html" %}
{% block htmltitle %}<title>{{ shorttitle }}</title>{% endblock %}
{% block body %}
  <h1>{{ docstitle|e }}</h1>
  <p><a href="{{ pathto("tutorial/index") }}">Tutorial</a></p>
{% endblock %}

文書でないページの変数が渡る。pagename はページ名(index)、title と body は空。pathto、toc、toctree()、html_context は通常通り使える。html、dirhtml、singlehtml は全てサイト直下に <name>.html(html_file_suffix)として毎回書く。テンプレート、または templates_path のどのファイルの変更も全ページを再構築する。

ページの配置と Sphinx との差分は次のとおりです。

  • 同名の文書ページを置き換える。Sphinx で最後に書くのと同じだ。index = "landing.html" は index.html をランディングページにし、目次は引き続き index.rst から作る。singlehtml では単一ページを残し、テンプレートページを警告付きで省く。
  • dirhtml は genindex.html や search.html と並ぶ download.html に書く。Sphinx の download/index.html とは異なる。pathto("download") はそのファイルを返す。
  • 名前はサイト直下のファイル名に限る。リンクがルート基準なので "sub/page" は警告(build.additional_page)で拒否する。genindex など既存ファイル名も拒否する。Sphinx では一方を上書きする場合だ。
  • guidedog migrate は conf.py の html_additional_pages を移します。

エラー

テンプレートの誤りはビルドを止め、ファイル、行番号、該当行、修正案を示します。

TEMPLATE ERROR                                                  template.error

  _templates/base.html:1

No filter named 'defualt'.

Did you mean the filter 'default'?

未定義の変数は Jinja と同様に何も表示しません。

暴走するテンプレートもクラッシュせずエラーで停止する。構文(括弧、タグ、演算子・フィルター・elif の連鎖)が100段、マクロ・インクルード・再帰ループが200段を超える場合、または再帰が512 KiB以上のスタックを要する場合だ。自身を含むリストは Python 同様 [...] と表示する。

PDF テンプレート

PDF は Typst で組版する。_templates/book.typ は book 関数を定義する通常の Typst ファイル。Guidedog は次の形でソースを書く。

#import "/_templates/book.typ": book
#show: book.with(title: ..., author: ..., version: ..., date: ...,
  lang: ..., paper: ..., numbering: ..., logo: ...)
// the chapters, one per document of the root toctree

本の見た目を決める要素はすべてそのファイルにあります。フォント、用紙と余白、見出し、扉、柱、目次です。

パラメータ

パラメータ 値
title pdf_documents の本の title、なければ project。
author 本の author、なければ設定の author。
version release.
date |today| は today の設定値、なければ today_fmt 形式のビルド日付です。
lang language.
paper "a4"、または pdf_paper_size が letter なら "us-letter"。
numbering toctree に numbered があれば true。
logo pdf_logo のパス。未設定なら省きます。
copyright 奥付用の copyright です。この引数を受け取るテンプレートにだけ渡します。
body 各章の内容。

テンプレートは既定値付きの引数を追加できる。quickstart のものには accent、フォント serif・sans・mono、文字の size、page-ref がある。最後を n => [p. #n] などの関数にすると、他のページへの参照にページ番号が付く。

Typst テンプレートの分割

Typst も一つのファイルにまとめる必要はありません。スタイル、マクロ、表紙を _templates/ の .typ ファイルに分け、#import と #include で組み合わせられます。

リスト 7 _templates/book.typ
#import "cover.typ": title-page
#import "typography.typ": apply-styles

#let book(
  title: "",
  author: "",
  version: "",
  date: "",
  lang: "en",
  paper: "a4",
  numbering: false,
  logo: none,
  body,
) = {
  apply-styles()
  title-page(title: title, author: author, version: version, logo: logo)
  body
}

テンプレートで使えるもの

Typst パッケージ

#import "@preview/cetz:0.4.2" などのパッケージは初回にダウンロードして使える。pdf_packages = "offline" ならディスク上のものだけでビルドする。

フォント

typst と同様にシステムフォントを使える。pdf_font_paths でフォルダーを追加する。pdf_fonts = "embedded" なら Typst 内蔵だけを使い、バイト単位で再現可能な本を作れる。

プリアンブル

pdf_preamble は #show: book の後に挿入する Typst ファイルです。独自テンプレートを作らずに、少数の set・show 規則を追加できます。

文書内の Typst

文書は reStructuredText と Markdown で、Typst ファイルは文書ではない。書籍に Typst 記法を入れるには raw ブロックを使う。Web ページでは省かれる。

.. raw:: typst

   #align(center)[#text(size: 14pt)[Only in the book]]

.. only:: pdf も通常の内容を本だけに限定します。

Typst のエラーは、テンプレートでも生成ソースでもファイルと行を示す。各 PDF のソースは _build/pdf/sources/<pdf-filename>.typ。reference-en.pdf なら sources/reference-en.pdf.typ。一冊のビルドでは従来の _build/pdf/book-<language>.typ も確認用に残す。失敗時は公開せず、ソースをエラーに示す _build/.doctrees/failed の場所に残す。複数冊の失敗ソースは別々に保つ。

新しいテンプレートの作成

quickstart が書いた、各部分の使い方を示すテンプレートから始めます。

  1. 既定の CSS が前提とする layout.html のマークアップを保つか、_static/guidedog.css も置き換えてください。
  2. 繰り返す部分を別ファイルにして include するか、base.html を作って layout.html から extends します。
  3. 本では book の規則を変えるか、同じ引数を持つ新しい book 関数を書きます。

編集時は guidedog serve で確認します。保存してブラウザを更新すると、変更された入力を再ビルドしてからページを返します。