reStructuredTextのUndocumentedな仕様

セクションタイトル

  • 4文字以上の連続であること
  • 章番号を出力する際は、間にスペースを入れる「1.1. サブセクション」
  • アンダーライン記号とオーバーライン記号がミスマッチ、またはオーバーライン記号のみの場合はエラーとなり出力されない。
  • idは全角文字部分は無視。重複の場合や空の場合は「id1」「id2」と割り振る。
  • 「2.」の直後に「2.0.1」に相当するタイトルがある場合エラーとなる(2.1を飛ばせないということ)
  • セクションタイトルは暗黙的リンクを生成する。
    • タイトルが重複(暗黙的リンクが重複)していても問題はないが、重複している暗黙的リンクを参照するとエラーになる。

リストブロックの抽出

  • リストブロック中にさらに別のブロックを入れる場合は、ブロックの手前に空行が必要。
  • 要素中に1箇所でも空行やリスト以外のアイテムを含む場合、そのレベルとより上位のリストはすべて<p>ブロックに展開される。
    • ただしアイテムの入れ子のための空行のみは無視する
  • 次のようなリストも有効である。
    -
        aa
    -
    
    - cc
    
    この挙動は、列挙リスト、フィールドリスト、オプションリストも同様。

列挙リストの挙動

  • 次の場合リストの終了を(2)までと見なし、(3)以降を通常文と見なす。
    1. 項目1
    2. 項目2
    3. 項目3
    5. 項目5
    6. 項目6
    
    • リストは次行をチェックする仕様であり、次行が以下のいずれかでなければならない。
      • ブランク行(空行)
      • インデントされた行
      • 全くの同型で順番も合っている列挙型
    • この際、リストブロックの終わり((2)の次行)にブランク行を入れろと警告が出る。
    • (3)の後にブランク行を入れれば正常な挙動になる。
  • 列挙の形式を混ぜることはできない
    1. 項目1
    2) 項目2
    (3) 項目3
    

フィールドリスト

  • フールドリストの最初の行は、そのフィルード中で最小のブロックインデントと同じとみなされる。
    :Authors: - X
        - Y
          - Z
    
        - X
        - Y
          - Z
    
    • この仕様は「オプションリスト」同様である。

オプションリスト

  • ダッシュ1個"-"のときは、続く1文字[A-Za-z0-9] のみをオプションとして解釈。2文字目以降は(スペースがなくても)引数として解釈。
  • ダッシュ2個"-"のときは、[a-zA-Z][a-zA-Z0-9_-]* をオプションとして解釈。引数との間には、スペースまたは=1個が必要。
  • 複数のオプションを区切る場合、", "を書く。" , "や", "はダメ。
  • MS-DOS形式の「/xxx」の"/"は、処理場は"--"の別表記として扱われる。
  • オプションの引数中に","が含まれる場合の解釈がおかしい*1
    -c <x, y>  arg include ","
    
  • オプションリストとして表記がおかしいものは、普通のテキストとして扱われる。

*1 : 仕様では< >内には何を書いても良いので、バグと思われる

ブロックの入れ子

  • インデントを変えることでブロックを入れ子にできる。
  • 以下の場合、入れ子は「aaaa」→「cccc」→「bbbb」となる。
    aaaa
            bbbb
        cccc
    

定義リスト

  • 単独行+インデント行で定義リストになる。開始が複数行ではならない。
    定義リスト
    	定義リストdd内
    
    2行以上の
    普通の文章
    	ここは引用ブロックになる。
    
  • classifierの展開がHTML違反(<dl>直下要素は<dt>/<dd>/<div>のみ)
    <dt>term 4</dt>
    	<span class="classifier-delimiter">:</span>
    	<span class="classifier">classifier one</span>
    	<span class="classifier-delimiter">:</span>
    	<span class="classifier">classifier two</span>
    	<dd>Definition 4.</dd>
    

行ブロック

  • 空行でブロックが終了する。
  • 入れ子は「行ブロック」のみ扱われる。
  • その他ブロック処理は行われない。
  • 空白に続く行は、前行に連結したものとして扱われる。

Doctestブロック

  • リテラルブロック同様、\(バックスラッシュ)をそのまま出力し、シンタックスハイライトに展開する。
  • インデント付Doctestは、インデントなしDoctestと同じである。
    Doctest with indent
    
        >>> print 'a'
        print 'b'
        print 'c'
    
  • Doctestよりも浅いインデントがある場合、浅いインデントを引用ブロックとして処理してから、Doctestブロックを入れ子処理する。
    Doctest with indent
    
        >>> This is doctest string
      This is quiot string
    
  • Doctestと同じインデントで改行を含むブロック構成の場合は、全体を引用ブロックとして処理してから、Doctestブロックを入れ子処理する。
    Doctest with indent
    
        >>> This is doctest string
    
       This is quiot string
    

テーブル

  • グリッドテーブルは2カラム以上の開始記号と、次行の"|"があってテーブルとみなされる。最小のテーブルは以下(ただしエラーになる)。
    +-+-+
    |
    
  • シンプルテーブルは最後のカラムのみはみ出しても良い。
    === === ===
    aaa bbb cccccccccc
    === === ===
    
  • シンプルテーブルは border の長さがすべて一致しないとエラーになる。
  • シンプルテーブルのボーダーは開始行を除くと「"-" と " "」のみの行、「"=" と " "」のみの行はボーダーとして扱われる。
  • シンプルテーブルの終わりは、3つ目の「=」ボーダーか、2つ目のボーダーの次行がブランク行の時である。
  • シンプルテーブルの「===/---」は、通常のカラム構成のマージン部分それぞれが、すべて埋まっているか、すべてスペースでないとエラーになる。

シンプルテーブルの変換例

=  =
adcd
----
-  -
=  =
+  1
+  2
=  =
adcd
   
 
   
1
2

脚注、引用参照(citation)

  • オートナンバー型脚注は、すべての脚注の中で使われていない番号を1から探索し順番に割り振る。
  • オートナンバー型脚注をラベル付で重複定義すると、重複した定義はすべてラベルがないものとして処理される。
  • オートナンバー型脚注の参照は、最初のオーナンバー脚注の宣言から順に参照する。
    • ラベル付オートナンバーへの参照は、ラベルが見つからない時は、ラベルなしオートナンバーとして扱われる。
  • 脚注番号は重複していても、脚注自体は出力される。
  • 無効な脚注(重複した脚注を含む)への参照は、脚注ではなく存在しないリンクへの参照として扱われる。
  • オートナンバー型やオートシンボル型の参照で宣言が足りない時は、存在しないidへのリンクを次の形式で出力する。
    <a href="#id36"><span class="problematic" id="id46"><span id="id24"></span>[#]_</span></a>
    <a href="#id47"><span class="problematic" id="id48"><span id="id29"></span>[*]_</span></a>
    
  • 引用参照エラーの場合は、最後の「_」を取り除いたテキストを出力する。
    [REF_ERR]_ → [REF_ERR]
    
  • 脚注参照や引用参照で、単なるリンク(明示的オーバーライドを含む)を参照するとPythonごと落ちる。

ラベル名 / simple reference names

最初の「#」を除いて以下の形式となる。

半角英数字と全角文字、および語中に含まれるハイフン、アンダースコア、ピリオドで構成された大文字・小文字を区別しない単語。連続した「ハイフン、アンダースコア、ピリオド」は互いに連続してはいけない。

  • 全角文字は、Unicodeクラスの「Letter」および「Number」のみ許可される。
    • 仕様書によると「simple reference names」である必要があり、全角文字が許可されるという記述は存在しない。
  • ラベル内にバックスラッシュ「\」がある場合無効。

Perlの正規表現で表せば以下となる。

$label =~ /^[A-Za-z0-9\p{gc:L}\p{gc:N}]+(?:[\-_\.][A-Za-z0-9\p{gc:L}\p{gc:N}]+)*$/

逆参照リンク

  • 参照されていない脚注や引用には、逆参照リンクが付かない。*2
  • 複数の参照元がある場合、逆参照リンクが参照数だけ付く。
    <em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id3">2</a>)</em>
    
  • 脚注から参照した場合は、脚注からの参照に対しては逆参照が付かない*3

*2 : 1つだけの場合そもそも付かない模様。

*3 : 参照リンクは有効だが、脚注出力時は脚注からの参照は存在しないものとして扱われる

リンク

  • リンクの本体は、そのままaタグに挿入される。
    .. _test: footnote.html#444""
    .. _ftp:  ftp://ftp.jaist.ac.jp
    
  • 「.. _」で始まれば、リンクとしてみなされ処理される。
    .. _malformed_error
    
  • 脚注や引用参照のラベルを指定して直接リンクすることができる。この場合、逆参照は発生しない。
    脚注を直接参照 1_
    
    .. [1] footnote
    
  • リンクラベルを「引用参照(citation)」形式でリンクすることはできない。
  • リンクラベルの宣言は「::」の後にいくつスペースがあっても良いが
  • 「:」の手前に1つのスペースは有効だが、「:」の手前に2つ以上スペースがあると無視される
    • 「malformed hyperlink target」が出力され、リンクブロックが終了したとみなされる。
      ..      _有効なリンク宣言 :
      .. _無効なリンク宣言  :
      .. _`無効なリンク宣言 `:
      
  • リンクラベル中の複数の連続したスペースは1つのスペースに正規化される。
  • リンクラベルの宣言時、ラベル名の最後に空白を含むと無視される(上例)。
  • リンクラベルの宣言は、バッククオート「`」の直前や直後にスペースかあると、区切りとみなされない。
  • リンクラベルの宣言中にバックスラッシュ(\)を含む場合、\によるエスケープを処理した後の名前がラベルとして記録される。*4
    • 「:: _tar\g\ et:」という宣言は「:: _target:」とみなされ処理される。
    • 「:: _tar\get\ :」という宣言は無効である。
  • リンクURLは、バックスラッシュ(\)が評価される。
  • 同じ記述が複数あっても、同じ定義(URL)ならばエラーにならない。
    • 同じURLを示していても次の記述はエラーとなる。
      .. _duplicate: https://adiary.org/
      .. _duplicate:
      .. _adiary: https://adiary.org/
      
  • エイリアス(alias)を複数行に渡って記述することができる。
    .. _alias:
    	`hyperlink
    	 name`_
    
  • 参照先が見つからないエイリアス、循環参照しているエイリアスのリンク宣言は、エラーとして出力される。
    .. _loopX: loopX_
    .. _not_found: ZZZZZZZ_
    

参照時

  • リンクターゲットが見つからない場合は、「`」や最後の「_」が残されたままテキストが出力される(存在しないidでリンクが生成される)。
  • 「``」なしの形式では、バックスラッシュ(\)を含む場合、参照とみなされない(リンク処理されない)。
  • 「``」なしの形式は、simple reference namesのみ許可される。

ラベルの重複

  • リンクのターゲット名と「引用参照(citation)」のラベルが同じである場合、リンクは失敗する(存在しないidでリンクが生成される)。
  • 脚注・引用参照(citation)でリンクを参照した場合。
    • それがURLである場合、実行時エラーとなり、何も出力されない。
    • それが内部リンクである場合、脚注と全く同じ形式のリンクが生成される。

入れ子

  • リンクラベル宣言は、リストアイテム等に入れ子することができる。
    * .. _XXX:
    
      あいうえお
    
    <li><p id="xxx">あいうえお</p>
    </li>
    

無名リンク

  • 参照数と定義数が合わないとき、すべての無名リンクを無効とする。

埋め込みリンク

  • 埋め込みリンクとして認識されない例(通常のリンク参照とみなされる)
    • <>中に<>を含む。
    • ラベルと<の間にスペースがない(スペースは複数あっても良い)。
    • <>内の先頭または最後にスペースがある
    • >`の間にスペースが含む
    • <>の中身が空
      - `AA < http://adiary.org>`_
      - `BB<http://adiary . org>`_
      - `CC <http://adiary.org >`_
      - `DD <http://adiary.org> `_
      - `EE <>`_
      
  • <>内のスペースは除去される。
    • ラベル名省略時は、除去後のテキストが出力される。
      `<http : // adiary . org>`_
      → http://adiary.org
      
  • 埋め込みリンクの参照名が重複していても、リンク自体は出力される。

*4 : footnoteや引用参照の宣言や、リンクの参照では途中に「\」を含むと期待した動作をしない。

置換定義

  • ".. |"で始まる行は置換定義とみなされ処理される。
  • "| |" 内の先頭および最後がスペースのものは形式エラーとなる。
  • "| |" の後ろにスペースがないものはエラーとなる(即改行は良い)。
  • "| |" 内の連続するスペースは、1つのスペースとして処理される(参照時同じ)。
  • エラーとなった置換定義ブロックは丸ごと出力されない。
replace |test test| !

.. |test  test| replace:: success
.. |error1|replace:: dummy
.. |error1|replace:: dummy
.. |error2| replace:: dummy
.. |error3 | replace:: dummy
.. | error4| replace:: dummy
	no output
	
	no output
  no output
  • 重複定義した場合エラーとなるが、置換自体は成功する(最後のものが有効)。

参照時

  • 置換とリンクの両方の参照が同時に行われた場合、置換参照に成功しないとリンクは生成されない。
  • 置換とリンクの両方の参照が同時に行われた場合、リンク参照に成功しないと文字の置換は行われない。
    どちらも無効 |link1|_ |link2|_
    
    .. _link1: https://adiary.org/
    .. |link2| replace:: adiary
    
  • replaceテキスト中で置換参照 "| |" を行うと Sphinx がクラッシュする。
  • replaceテキスト中で以下を行うとエラーとなる。
    • インラインリンク定義 `text <http://example.com>`_
    • 脚注/引用参照 [1]_ [CITE]_

インラインマークアップ

  • 入れ子にはできない。
  • 仕様と異なり、Unicodeカテゴリ「Po (Other Punctuation)」に属する文字でも、以下のものは区切り記号として認識しない(インラインマークアップの前後の文字として使用できない)。
    # % & * @
    
  • タグの開始記号を認識してから、終了記号を認識する。
    • 開始記号を先に認識し、終了記号が見つからない場合、WARNINGを出力する。
    • 脚注参照[XXX]を除く。
  • 2行にまたがるインラインタグが有効。
    This **is
    a** pen.
    
  • 中が空であるマークアップは、マークアップ全体がエラーとなる。
  • 仕様と異なり、認識したマークアップの開始文字がエラーとなった場合、直後の文字は境界条件(マークアップ開始記号の直前の文字に関する制限)を満たしていることになる。
    記述仕様から導かれる出力実際の動作
    ***XX****XX***<em>XX</em>

その他

  • 文字幅を示す「East_Asian_Width」の「A (=Ambiguous)」に属するものは、すべて半角として扱う。

reStructuredText記法

Ver3.30 から reStructuredText (RST/reST) に対応しました。

  • ePub等でも使われる、入力記法です。
  • Markdownよりも幅広い文章表現ができます。
  • adiaryにはSphinx連携機能もあります。

入力方法は以下のRSTドキュメントを参照してください。

互換性情報

「Sphinx v1.4.9」にて互換性確認を行っています。

Ver3.24以前からアップデート時の導入方法

アップデートしたままでは使用できません。adiary.conf.cgiを再生成するか、以下のように設定を変更してください。

<$v.parsers = begin_hash_order>
	markdown      = Markdown
	default       = 標準(改行処理)
	default_p1    = 1行=1段落
	default_p2    = 空行で段落処理
	rst           = reStructuredText
	simple	      = HTML(そのまま)
	simple_br     = HTML(改行処理)
<$end>

HTML化して静的出力

adiaryには記事内容すべてをHTMLとして出力する機能があります。そのままアップロードすれば、静的HTMLによるサイトとして公開できます。

基本的にはコンテンツツリーをそのままサイトとして出力する目的で使用します。

設定方法

以下を adiary.conf.cgi に設定することで機能が有効になります。*1

<$v.static_export = true>

相対パスでテーマ(CSS/JS)やアルバム内のファイルを出力するフォルダを指定することもできます。

<$v.static_theme_dir = 'theme/'>
<$v.static_files_dir = 'files/'>

なお第3者にレンタルしている場合、この機能は使用しないほうがよいでしょう。

*1 : Ver3.30から設定方法が変更になりました。

出力方法

出力したいブログで、「ブログの管理」→「エクスポート」と進み、静的出力を選択します。

static_export.png
  • トップページ(最初に表示される記事)として index をコンテンツキーに持つ記事を作成してください。
  • 出力されるファイルは、コンテンツキーや記事番号に「.html」を付加したものになります。
  • 印刷用リンクやタグ一覧など、HTML化時にリンク切れになるプラグイン(デザインモジュール)があります。
    • 問題の起こるリンクやデザインモジュールなどは削除してください。

記事一覧出力(Ver3.32-)

サイドバーの記事一覧リンクや、月別記事一覧モジュールのリンクにそれぞれ対応しています。この対応で、indexを持たないブログやmixi_export等で取り込んだものを、静的出力することが可能になりました。

スタンドアローン/EXE版

Webサーバが不要のスタンドアローン版とWindows用EXE版がVer3.20以降収録されています。

実行ファイル

  • adiary.httpd.pl
    • Perl用の実行ファイルです。Perl本体およびImage::Magick等のライブラリをインストールしてください。
  • adiary.exe (x64)
    • Perlを内包していますので、Perl本体は不要です。Windows用ZIP版にのみ含まれます。*1

システム更新時にメモリリークが起こりやすいようなので、更新時は再起動を推奨します。

*1 : githubには置いてありません。githubで管理する場合は、adiary.exeのみ抜き出して使用してください。

オプション(引数)

"-h"オプション付で実行するとヘルプが表示されます。以下オプションの説明になります。ヘルプと内容が異なる場合、ヘルプを優先してください。

Usage: ./adiary.httpd.pl [options]
available options are:
  -p port	bind port (default:8888, windows:80)
  -t timeout	connection timeout second (default:3, min:0.001)
  -d daemons	start daemons (default:10, min:1)
  -m max_req	maximum cgi requests per daemon (default:10000, min:100)
  -e mime_file	load mime types file name (default: /etc/mime.types)
  -c fs_code	set file system's code (charset)
  -b bufsize    buffer size [KB] (default:1024 = 1M, min:64)
  -u filename	UNIX domain socket mode
  -f		use fork()
  -i		use threads (ithreads)
  -k1		connection keep-alive enable (default)
  -k0		connection keep-alive disable
  -t0		set ENV SatsukiTimer=0
  -t1		set ENV SatsukiTimer=1
  -s		silent mode
  -sc		silent mode for cgi  access
  -sf		silent mode for file access
  -n		do not open web browser
  -?|-h         view this help
-p
bindするポート番号を指定します。デフォルトは 8888、Windowsでは 80 です。
-t
タイムアウト(秒)を指定します。指定秒数経過するとTCP接続を切断します。長い値を指定すると、keep-alive時の効率がよくなりますが、接続リソースを使い尽くすDoS攻撃に弱くなります。
-d
デーモン数*2を指定します。ここで指定した数だけ同時接続を受け付けます。
-m
1つのデーモンあたりの最大CGI処理回数を指定します。この数を超えるとデーモンが再起動されます。メモリリーク対策用の設定になります。0を指定すると最大数が設定されます。静的ファイルアクセス(CGIアクセス以外)はカウントされません。
-e
FileTypeを記述したmimeファイルを指定します。Linux等ならば /etc/mime.types を自動で読み込みます。内部で必要最低限の設定はされていますので、ほとんどの場合、指定する必要はありません。
-c
ファイルシステムの文字コードを指定します。自動認識に失敗するときに指定してください。
-u
指定したUNIX domain socketを開きます。TCPポートは開かなくなります。
-b
ファイル送信時*3のメモリバッファのサイズを指定します。「1M」や「256K」等の単位を付けて指定することもできます。数字のみ指定した場合は、KB単位となります。
-f
forkモードでデーモンを起動します。Windowsでは動作しません。非Windowsでのデフォルトです。
-i
ithreads(threads)モードでデーモンを起動します。Windowsでのデフォルトです。
-k1
keep-aliveをonにします。デフォルトです。Chrome以外のブラウザでは、keep-aliveをoffのほうが接続効率は良くなります。
-k0
keep-aliveをoffにします。Chrome等では、keep-aliveをoffにすると接続効率が極端に悪くなります。
-t0
環境変数に SatsukiTimer=0 を設定します。タイマー計測が強制オフになります。
-t1
環境変数に SatsukiTimer=1 を設定します。タイマー計測が強制オンになります。
-s
サイレントモードに設定します。接続ログを標準出力しなくなります。
-sc
CGIアクセスのログを出力しなくなります。
-sf
ファイルアクセスのログを出力しなくなります。
-n
起動時に自動でブラウザを開かなくなります(Windowsのみ)。
-h, -?
HELPメッセージを表示します。

*2 : forkプロセス数やスレッド数

*3 : クライアントから見ればファイルダウンロード時

リバースProxyによる運用

adiary.httpd.pl をApache等リバースproxyより適当なWebフォルダに貼り付けることができます(Ver3.40以降)。

# Reverse Proxy
ProxyPass  /adiary/  http://localhost:8888/adiary/

この場合、adiary.httpd.pl に Web working path を指定してあげる必要があります。

./adiary.httpd.pl /adiary/

Apacheで試したところ、直接アクセスした場合の8割程度の性能になるようです。

UNIX domain socketを使用する場合

# Reverse Proxy
ProxyPass  /adiary/  unix:/path/to/adiary/adiary.sock|http://localhost/adiary/
./adiary.httpd.pl -u adiary.sock /adiary/

adiary.exeの生成方法

Strawberry Perlと pp を使って adiary.httpd.pl をコンパイルしたものです。管理が面倒なのでx64専用としていますが、コンパイルしなおせばx86(32bit)でも動作すると思います。

  • 更新が必要な場合は自動検出しエラーを出力します。*4

exeの生成

PAR.pmへのパッチ

sub import {
    my $class = shift;

    PAR::SetupProgname::set_progname();
    PAR::SetupTemp::set_par_temp_env();

    # patch for sitelib by nabe@abk ---------
    if ($ENV{PAR_TEMP} && $^O eq 'MSWin32') {
        my %conf;
        foreach(keys(%Config)) {
            $conf{$_} = $Config{$_};
        }
        *Config::Config = \%conf;   # replace read-only object

        my $base = "$ENV{PAR_TEMP}\\inc";
        $Config::Config{sitelib}    = "$base\\site\\lib";
        $Config::Config{sitelibexp} = "$base\\site\\lib";
    }
    # patch end -----------------------------

Crypt::glibc

WindowsでCrypt/MD5、Crypt/SHA256、Crypt/SHA512を実行するためのライブラリ。

https://adiary.org/download/tools/Crypt-glibc-0.01.tar.gz

*4 : エラーをSTDERRに出力し、入力待ちを行ってからexit(-1)します。

ディレクトリ情報

www上からのアクセス設定(公開/非公開)および、ディレクトリについて。

公開ディレクトリ

pub/
ブログごとの画像データ等、付随データが置かれる。プライベートブログを設置する際はディレクトリ内のファイル一覧を表示させないこと。*1
pub-dist/
adiary本体と共に配布されるデータが置かれる。
theme/
テーマ(CSS)が置かれる。
js/
JavaScriptが置かれる(プラグイン以外)。

公開ディレクトリ以外は非公開に設定しても構いません。

*1 : Apacheで言うところの -Indexes 設定です。

非公開ディレクトリ

以下はWeb上からはアクセス不可に設定してください。*2

__cache/
.confや.htmlのコンパイル結果が置かれる。
data/
ブログの各種設定データ等が置かれる。
plugin/
プラグインデータが置かれる。
skel.local/
サイト独自のスケルトンを設置する場合に使用する。使用する場合は非公開を推奨。

*2 : .htaccessが有効ならばアクセスできないように設定されています。

ディレクトリ構成とパーミッションまとめ(Ver3.15現在)

場所Apacheadiary.cgi補足
__cache/非公開R/Wコンパイルキャッシュ
data/非公開R/Wブログ非公開データ
info/anyR本体付属の非公開データ
js/公開RJavaScript
lib/anyRPerl LIB(adiary本体)
plugin/非公開Rプラグイン
pub/公開R/Wブログ公開データ
pub-dist/公開R本体付属の公開データ
skel/anyRスケルトン
skel.local/非公開Rローカルスケルトン
theme/公開Rテーマファイル(CSS)
any
公開、非公開どちらでも良い