|
本サイトは移転しました。旧アドレスからのリダイレクトは2025年03月31日(月)まで有効です。
|
🛈 | ✖ |
DoxygenのHTML出力の原稿としてマークダウン形式ファイルを用いる方法を説明する。
ドキュメンテーションツールであるDoxygenは修飾機能が豊富で本来のソースコード解析を目的としなくてもリッチなドキュメントを作成できる。本サイトもDoxygen修飾を付加したプレーンテキストとして原稿を作成し、マークダウン形式(拡張子*.md)ファイルとしてDoxygenに処理させたHTML出力を用いている。しかしDoxygenのマークダウン形式の処理には不具合も多く、安定した運用にはいくつかの注意を必要とする。
本サイトでの"マークダウン形式ファイル"はDoxygenの読み込むファイル形式に限定する。独自拡張したコマンドを持ち、他形式コマンドが混在し、厳密に定義される"マークダウン形式ファイル"から恐らく大きくかけ離れる。
Doxygenはプログラミングのソースコード解析が本来の目的で、Doxygen書式のコメント行に各種コマンドを挿入して出力をコントロールする。マークダウン形式ファイルだけが各種コマンドをコメント行でなくプレーンテキストに置くことができる。
Doxygenの豊富な機能を用いれば一般のHTMLドキュメント生成ツールとしても利用できるが、コメント行に長文作成すれば原稿の見通しを悪夢的に損なう。
こういった場合、分かち書きの英語なら単語間で改行だが日本語は向かない。そこで山月記を一定カラムで改行してみるが、半角スペースで連結され不自然である。
隴西の李徴は博学才穎、天宝の末年、若くして名を虎榜に連ね、ついで江南尉に補 せられたが、性、狷介、自ら恃むところ頗る厚く、賤吏に甘んずるを潔しとしなか った。いくばくもなく官を退いた後は、故山、虢略に帰臥し、人と交を絶って、ひ たすら詩作に耽った。下吏となって長く膝を俗悪な大官の前に屈するよりは、詩家 としての名を死後百年に遺そうとしたのである。
Doxygenは四つの修飾方法(コマンド)を同一ファイルの中で利用できる。マークダウン形式はMARKDOWN_SUPPORTオプションをYES(デフォルト)とする必要がある。マークダウン形式ファイル(拡張子*.md)でもマークダウン以外の形式が使える。
HTMLドキュメント作成において文書の構成要素(ページ、セクション、サブセクションなど)を示すコマンドを構成要素コマンドと定義する。Doxygen形式の構成要素コマンドを示す。
Doxygen形式 | 概略 |
---|---|
\mainpage [(title)] | HTMLトップページ(index.html) |
\page <name> (title) | HTMLページ(*.html) |
\section <name> (title) | セクションレベル1、章 |
\subsection <name> (title) | サブセクションレベル2、節 |
\subsubsection <name> (title) | サブセクションレベル3、項 |
ページ相互は\subpageコマンドで上下関係を付ける。トップページを祖とするツリー構造とするのが自然だが、本サイトのセットアップ、用語などのようにトップページに並列させる事もできる。並列配置されたページはRelated Pageページに表示される。構成要素は\refコマンドで参照できる。
Doxygen形式 | 概略 |
---|---|
\subpage <name> ["(text)"] | ページを参照し上下関係を定義する |
\ref <name> ["(text)"] | ページやセクションを参照する |
\subpageコマンドによるページ間構成と\sectionコマンドなどによるページ内構成を合わせて目次(Table Of Contents)が作成され、GENERATE_TREEVIEWオプションが画面左に表示するツリービューなどに反映される。
マークダウン形式のヘッダは構成要素コマンドとして機能する。
プレースホルダー | 意味 |
---|---|
<sharp> | 単語、空白を含めない |
(round) | 行末あるいは次の制御文字までの文字列、空白を含める |
{curly} | { }を含め実際の文字列として扱う |
[square] | 省略可能なオプション |
等価となるDoxygen形式コマンドと対比する。
Doxygen形式 | マークダウン形式1 | マークダウン形式2 | 備考 |
---|---|---|---|
\mainpage [(title)] | (title) {#mainpage} ======= | # (title) # {#mainpage} | ファイル先頭の場合 \refからはindexで参照 |
\page <name> (title) | (title) [{#<name>}] ======= | # (title) # [{#<name>}] | ファイル先頭の場合 |
\section <name> (title) | (title) [{#<name>}] ======= | # (title) # [{#<name>}] | ファイル先頭以外の場合、レベル1 |
\subsection <name> (title) | (title) [{#<name>}] ------- | ## (title) ## [{#<name>}] | レベル2 |
\subsubsection <name> (title) | - | ### (title) ### [{#<name>}] | レベル3 |
- | - | #### (title) #### [{#<name>}] | レベル4 |
- | - | ##### (title) ##### [{#<name>}] | レベル5、\refで参照できない |
- | - | ###### (title) ###### [{#<name>}] | レベル6、\refで参照できない |
マークダウン形式1の2行目は=または-のみからなる文字列で、その文字数は2個以上任意である。マークダウン形式2の(title)直後の#文字数は0個以上任意である。マークダウン形式2は最大6レベルのサブセクションを作れるが、\refで参照できるのはレベル4までに限定される。\mainpageを除きDoxygen形式で<name>は必須だがマークダウン形式では省略できる。マークダウン形式は\page(および\mainpage)と\sectionが同一構文で混乱するものの、開発者は"Note that the subsequent sections have to be at the same level as the title in order for them to be rendered as sections within the page (you can call this a bug)"と居直る。
\subpageに対応するマークダウン形式は存在しないが、\refへの対応は存在する。Doxygen形式には外部ウェブページを参照するコマンドが無く、HTLM形式アンカー要素かマークダウン形式を用いる。
Doxygen形式 | HTML形式 | マークダウン形式 | 備考 |
---|---|---|---|
\subpage <name> ["(text)"] | - | - | - |
\ref <name> ["(text)"] | - | [(text)](\ref <name>) | マークダウン形式の[ ]はプレースホルダーの記号ではなくて実際の文字 |
- | <a href="<web-address>">(text)</a> | [(text)](<web-address>) | HTML型式< >は<web-address>を除きタグを表す実際の文字 マークダウン形式の[ ]は実際の文字 |
マークダウン形式ファイルの先頭に\page(または\mainpage)あるいは対応するマークダウン形式コマンドが無い場合、あるいは先頭のマークダウン形式コマンドが<name>を省略する場合、マニュアルはタイトル((text))とラベル(<name>)をファイル名から作成するとしている。マニュアルに記載は無いがラベルはmd_<page-base-name>の形式で、<page-base-name>はDoxygen実行ディレクトリからファイルまでの相対パスを構成するディレクトリ名と、拡張子を除いたファイル名をアンダースコアで連結する。相対パスが親ディレクトリを含む場合に<page-base-name>がどうなるかは全く不明にある。マニュアルはまた\refコマンドにマークダウン形式ファイル名を直接参照できるとするが、相対パスの影響を受け理解に苦しむ挙動を示す。
以下にマークダウン形式ファイルを実行ディレクトリから異なる相対位置(上位、同じ、下位)として、トップページから\subpageで参照した場合の挙動をまとめる。ファイルが置かれるディレクトリは全てINPUTオプションに指定して、ファイル名にディレクトリは含まない。
ディレクトリ | 参照方法 | \subpageの参照先 | ツリービュー(トップとの関係) | Related Page |
---|---|---|---|---|
上位 | 先頭コマンド<name> | HTML表示 | 子ノードで参照先はHTML表示 | 表示されない |
md_<page-base-name> | <page-base-name>が不明 | |||
ファイル名 | ソースコード表示 | 兄弟ノードで参照先はHTML表示 | 参照先はHTML表示 | |
同じ | 先頭コマンド<name> | HTML表示 | 子ノードで参照先はHTML表示 | 表示されない |
md_<page-base-name> | HTML表示 | 子ノードで参照先はHTML表示 | 表示されない | |
ファイル名 | HTML表示 | 兄弟ノードで参照先はHTML表示 | 参照先はHTML表示 | |
下位 | 先頭コマンド<name> | HTML表示 | 子ノードで参照先はHTML表示 | 表示されない |
md_<page-base-name> | HTML表示 | 子ノードで参照先はHTML表示 | 表示されない | |
ファイル名 | ソースコード表示 | 兄弟ノードで参照先はHTML表示 | 参照先はHTML表示 |
\subpageによる参照なのでトップページの子ノードでRelated Pageに表示されないはずだが、整合性は乏しく過去のバージョンでは異なるケースもある。結論として、ラベルを先頭コマンド<name>で明示するのが最も確実で安定している。
Doxygenが1.8.15にバージョンアップした際にマークダウン形式1はバグを抱えたため現時点では利用を避ける。
Doxygen形式は<name>を必須とする。<name>は全ドキュメント(全原稿)ユニークなID文字列で、ファイル数が多くなるとその管理は負担となる。サイト作成者だけかもしれないが<name>を忘れて(title)のみを与えるミスが多く、その場合(title)として与えたつもりの文字列の最初の空白文字までが<name>と解釈され、以降が(title)となる。(title)が空文字列なら<name>が代わりにラベル表示されるのため、このミスは発見しづらい。他と重複する<name>を持つ構成要素は目次に登録されずツリービューなどに表示されない。一方、マークダウン形式は<name>を省略できる。<name>を持たない構成要素はTOC_INCLUDE_HEADINGSオプション値のレベルまで目次に登録されツリービューなどに表示される。TOC_INCLUDE_HEADINGS値デフォルトをマニュアルは5とするがDoxygen(バージョン1.8.15)生成テンプレートファイルでは0なのでDoxyfileで明示的に設定する。なお<name>を持つ構成要素はTOC_INCLUDE_HEADINGS値と無関係に目次に登録される。
TOC_INCLUDE_HEADINGS値を1以上として、二つのファイルでそれぞれが同じタイトルを持つセクションを定義してみる。Doxygen形式はあえて<name>を忘れるミスを犯す。
Doxygen形式は二つのセクションでID文字列が衝突し、ツリービューなどに片方しか表示されない。マークダウン形式は両方とも表示される。マークダウン形式(現状では形式2に限定される)の方が<name>の自由度が高くDoxygen形式より優れると結論付けられよう。
DoxyfileのSEARCHENGINEオプション(デフォルトはYES)でHTML出力に検索ボックスを追加できる。これはソースコード解析ならクラス名、ファイル名、関数名を検索できて有益であるが、ソースコード以外ではページラベルしか検索できない上に日本語による検索に不具合がある。ソースコード解析を含まない一般的なドキュメントならこのオプションをNOとした方が安心できる。
DoxygenによるHTML出力の原稿となるマークダウン形式ファイルを作成する場合の指針を示す。
一つのファイルで一つのHTMLページを作成するとしたが、ファイル途中にDoxygen形式の\pageコマンドを挿入すれば一つのファイルで二つ以上のHTMLページを作成できる。しかし構成要素コマンドをマークダウン形式2に統一する観点から好ましくなく、また一つのファイル一つのページを原則としたほうが管理がたやすい。Doxygenの以前のバージョンで一ファイルから複数ページを作成させていたところサイズ拡大と共に不可解なエラーの発生を経験したこともあり、避けるに越したことはない。
Doxygenは4種類のコマンド形式を同時解釈するためかそれぞれの形式で期待する動作とならない場合があり、特にマークダウン形式にはバグと呼びたい不具合が多い。各形式が干渉し、例えばある形式の制御文字に一致する文字のエスケープ要否がケースバイケースで異なる。トライアンドエラーは避け得ないものとして覚悟する。
本サイトトップページの原稿をサンプルとして示す。