asciidoctor
asciidoc

Asciidoc簡易メモ

More than 1 year has passed since last update.

AsciiDocはMarkdownと比較すると表現力が高く、その表現力不足を補うためにMarkdownをいくつも独自拡張してつかうようなことをしているのであれば、AsciiDocはMarkdownの代替候補として有力な選択肢の一つになるとおもう。

変換にはAsciidoctorを使っているので、以下のメモはAsciidocというよりはAsciidoctorの簡易的な変換のメモになっています。
一部の記法についてはいっさい触れず、完全に省略して書いているので注意してください

Attributes, Comment, Include

Attributesは変数。

:name: hbsnow

私の名前は{name}です。
// 私の名前はhbsnowです。

unsetするときには:!name:もしくは:name!:とします。

//はコメントアウトになり出力されません。

////
ここにコメント
////

////で囲まれている箇所もコメントとして扱われます。これらのコメントは変換後の言語のコメントアウトとして出力するのではなく、コメントアウト扱いになるので何も出力しません。

外部のAsciiDocのファイルをincludeさせることもできます。

include::partial.adoc[]

Link

基本的にはhttp://example.com[サンプルのリンク]のようにURLのあとにサイト名を書くだけです。ただ英語のように分かち書きをする言語ではない日本語が主だとパラグラフの頭に出現する状態以外ではほとんどリンクになりません。

たとえばこのように文中にあるhttp://example.com[文中にあるリンク]はリンクになりません。

なのでこのような文中のリンクにはリンクであることを明示させる必要があります。

このようにするとlink:http://example.com[文中にあるリンク]がリンクになります。

link:での指定は相対パスにも使うことができます。

Inline

意味 変換前 変換後
emphasis _word_ <em>word</em>
strong *word* <strong>word</strong>
monospaced `word` <code>word</code>
superscript ^word^ <sup>word</sup>
subscript ~word~ <sub>word</sub>
marked #word# <mark>word</mark>
styled [userinput]#word# <span class="userinput">word</span>

文章中にあってうまく変換ができないときには記号を二つ重ねて**このように**使う必要があります。

\*強調*のエスケープ
\\**二つ重ねている**ときには二つのエスケープが必要です。

またAttributesを含めたこれらのエスケープには\を使います。記号を二つ重ねたときにはバックスラッシュもまた二つ必要になることに注意が必要です。

Section

Headingは=を使います。

[[id]]
= Document Title

== Section Level 1

=== Section Level 2

ToCのために<hn>にidをつけたいときには[[id]]を直前に記述します。このidは基本的にデフォルトで自動に割り当てられるものなのですが、日本語の場合、日本語部分が完全に削除されるので多くの場合動作しないと考えて問題ないとおもいます。

自動割り当てを使わない場合には:sectid!:でunsetすることで設定を無効にすることができます。

便利なのは:sectanchors::sectlinks:の設定で、これを指定することでSection Titleにアンカーやリンクが作成されます。

:sectanchors:

[[sec1]]
== Section Level 1

このようなAsciiDocは次のように変換されます。

<h2 id="sec1"><a class="anchor" href="#sec1"></a>Section Level 1</h2>

タイトルをホバーしたときに出現するようなリンクが必要なときに便利です。

Image

[[example]]
.画像のタイトル
image::example.jpg[サンプル画像, 300, 200, link=http://example.com/file/0000/]
<div id="example" class="imageblock">
  <div class="content">
    <a class="image" href="http://example.com/file/0000/">
      <img src="example.jpg" alt="サンプル画像" width="300" height="200">
    </a>
  </div>
  <div class="title">Figure 1. 画像のタイトル</div>
</div>

画像にタイトルをつけると自動でナンバリングが出力されます。この出力をしたくない場合には:figure-caption!:と指定する必要があります。

Horizontal

// <div style="page-break-after: always;">
<<<

// <hr>
'''

<<<は改ページです。ウェブページに改ページという概念はないので使いどころはあまりないかもしれませんが、<div style="page-break-after: always;"></div>が印刷用のスタイルとして出力されるので、仮にウェブページへの出力しか考えていないような場合でもまったく無駄な要素というわけではありません。

Block

<div id="baz" class="foo bar">のように独自のマークアップをしたいときには----で内容を囲い、その手前で指定します。

[#baz.foo.bar]
----
block
----

[[baz]]
[role="foo bar"]
----
block
----

一行にまとめられた省略記法を使うのがわかりやすいとおもう。これらのブロックにタイトルをつけたくなったときには.ではじまる行を追加します。

[#baz.foo.bar]
.このブロックのタイトル
----
block
----

ただAsciiDocは汎用的なブロックについてはすでに定義されているので、こういった使い方はあんまりすることはないとおもいます。

Source

[source,js]
.hello.js
----
console.log('Hello, world!');
----

------でも問題ありません。定義されているブロックで使用される記号は基本的に4文字でつかうので統一したほうがわかりやすいかも。AsciiDoc内にAsciiDocの記法を出力させたい記事を書くようなときに、もしかすると使い分けることがあるかもしれない程度だとおもう。

sourceのあとには使用する言語を指定することができます。公式のドキュメントではファイル名をタイトルとして出力させています。

このコードブロック内ではAttributeも当然使えません。使いたいときにはsubsattributesを指定する必要があります。

:version: 1.0.0

[source,js,subs="attributes"]
----
console.log('version {version}');
----

インラインのコードにはMarkdownと同じように`を使います。ただしインラインのコード内はブロックと異なってText Replacementが無効になっていないので、pass:r[]で明示する必要があってかなり面倒。なんでこんな挙動になっているのかはよくわからない。

Quote

[quote, 夏目漱石, こころ]
____
私はその人を常に先生と呼んでいた。だからここでもただ先生と書くだけで本名は打ち明けない。
____
<div class="quoteblock">
  <blockquote>
    <div class="paragraph">
      <p>私はその人を常に先生と呼んでいた。だからここでもただ先生と書くだけで本名は打ち明けない。</p>
    </div>
  </blockquote>
  <div class="attribution">— 夏目漱石<br><cite>こころ</cite></div>
</div>

Admonition

NoteやTipsのようなブロックは事前に用意されています。

  • NOTE
  • TIP
  • IMPORTANT
  • CAUTION
  • WARNING
[CAUTION]
====
警告メッセージはここに。
====
<div class="admonitionblock caution">
  <table>
    <tbody>
      <tr>
        <td class="icon">
          <div class="title">Caution</div>
        </td>
        <td class="content">
          <div class="paragraph">
            <p>警告メッセージはここに。</p>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>

ただ目を覆いたくなるようなHTMLが出力されるので結構きつい。

Passthrough

++++
<react-elem></react-elem>
++++

変換処理をしないブロックには++++を使います。[subs="attributes"]を指定することでAttributeを有効にできます。

インラインの場合には+++で変換処理をしない範囲を括り、特定の変換のみを回避するにはpass:[]をつかいます。

+++<ins>これが一番記述しやすいので使いやすい。</ins>+++

pass:a[{attribute}]の変換を回避する

pass:r[->(c)]のようなテキストの置き換えの変換を回避する

Footnotes

MarkdownでもおなじみのFootnotes。使わない人はほとんど使わないもので、私もその使わない人のうちの一人だったりします。

脚注は日本語の文中にあっても問題ありませんfootnote:[この通り。]。footnoteref:[ref1,私はあまり使いませんが。]

本文が長くなるときには参照させることもできます。footnoteref:[ref1]

List

Unordered List

.リストのタイトル
* リスト1
+
複数のパラグラフになったときには+を使ってつなげます

** リスト1-1
** リスト1-2

* リスト2
* リスト3
<div class="ulist">
  <div class="title">リストのタイトル</div>
  <ul>
    <li>
      <p>リスト1</p>
      <div class="paragraph">
        <p>複数のパラグラフになったときには+を使ってつなげます</p>
      </div>
      <div class="ulist">
        <ul>
          <li>
            <p>リスト1-1</p>
          </li>
          <li>
            <p>リスト1-2</p>
          </li>
        </ul>
      </div>
    </li>
    <li>
      <p>リスト2</p>
    </li>
    <li>
      <p>リスト3</p>
    </li>
  </ul>
</div>

-を使うこともできますが、ネストさせることができないので注意してください。またこの事情から基本的によほどの事情がないのであれば、リストは*で統一するほうがいいんじゃないかとおもう。

Ordered List

.リストのタイトル
. リスト1
.. リスト1-1
.. リスト1-2
. リスト2
<div class="olist arabic">
  <div class="title">リストのタイトル</div>
  <ol class="arabic">
    <li>
      <p>リスト1</p>
      <div class="olist loweralpha">
        <ol class="loweralpha" type="a">
          <li>
            <p>リスト1-1</p>
          </li>
          <li>
            <p>リスト1-2</p>
          </li>
        </ol>
      </div>
    </li>
    <li>
      <p>リスト2</p>
    </li>
  </ol>
</div>

順序付きのリストには.を使います。タイトルの.とちょっと紛らわしいかも。

Labeled List

北海道:: 北海道日本ハムファイターズ
関東::
  埼玉::: 埼玉西武ライオンズ
  千葉::: 千葉ロッテマリーンズ
<div class="dlist">
  <dl>
    <dt class="hdlist1">北海道</dt>
    <dd>
      <p>北海道日本ハムファイターズ</p>
    </dd>
    <dt class="hdlist1">関東</dt>
    <dd>
      <div class="dlist">
        <dl>
          <dt class="hdlist1">埼玉</dt>
          <dd>
            <p>埼玉西武ライオンズ</p>
          </dd>
          <dt class="hdlist1">千葉</dt>
          <dd>
            <p>千葉ロッテマリーンズ</p>
          </dd>
        </dl>
      </div>
    </dd>
  </dl>
</div>

[horizontal]を指定すると横並びになります。テーブルにされますが。

[horizontal]
北海道:: 北海道日本ハムファイターズ
<div class="hdlist">
  <table>
    <tbody>
      <tr>
        <td class="hdlist1">北海道</td>
        <td class="hdlist2">
          <p>北海道日本ハムファイターズ</p>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Table

AsciiDocのテーブル記法はとにかく書きやすくて最高だとおもう。CSVをそのまま使えたりするのもすばらしい。

|===
|1-1|2-1|3-1

|1-2
|2-2
|3-2

|1-3
|2-3
|3-3
|===
<table class="tableblock frame-all grid-all spread">
  <colgroup>
    <col style="width: 33%;">
    <col style="width: 33%;">
    <col style="width: 33%;">
  </colgroup>
  <thead>
    <tr>
      <th class="tableblock halign-left valign-top">1-1</th>
      <th class="tableblock halign-left valign-top">2-1</th>
      <th class="tableblock halign-left valign-top">3-1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">1-2</p>
    </td>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">2-2</p>
    </td>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">3-2</p>
    </td>
    </tr>
    <tr>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">1-3</p>
    </td>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">2-3</p>
    </td>
    <td class="tableblock halign-left valign-top">
      <p class="tableblock">3-3</p>
    </td>
    </tr>
  </tbody>
</table>

<thead>が不要の場合には最初の一行目を含めてすべて複数行で記述すると簡単に実現することができます。複数行にわけたときに最初の一行目をヘッダとして扱うには、[options="header"]を追加する必要があります。<tfoot>も必要であれば[options="header,footer"]になります。

またこのテーブルのように列幅の設定がない場合、列がすべて等幅になることには注意する必要があります。

[cols="3,2*1"]
|===
|1-1|2-1|3-1

|1-2
|2-2
|3-2
|===
<table class="tableblock frame-all grid-all spread">
  <colgroup>
    <col style="width: 60%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
  </colgroup>
  <thead>
    <tr>
      <th class="tableblock halign-left valign-top">1-1</th>
      <th class="tableblock halign-left valign-top">2-1</th>
      <th class="tableblock halign-left valign-top">3-1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">1-2</p>
      </td>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">2-2</p>
      </td>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">3-2</p>
      </td>
    </tr>
  </tbody>
</table>

[cols="3,2*1"][cols="3,1,1"]を省略して書いたもので、すべて省略されているときには[cols="1,1,1"]になります。この数値はセルの横幅の割合を表していて、合計値がいくつになるかを気にすることなく適当な数値に設定するだけでうまいこと調整してくれます。

テーブルの縦列に特殊なスタイルを適用したいときには値を与えます。よくつかうのはahaはAsciiDocの記法を使用できるようになり、hはヘッダとして扱うようになります。

[cols="h,a2*1"]
|===
|1-1|2-1|3-1

|1-2
|`2-2`
|`3-2`
|===
<table class="tableblock frame-all grid-all spread">
  <colgroup>
    <col style="width: 33%;">
    <col style="width: 33%;">
    <col style="width: 33%;">
  </colgroup>
  <thead>
    <tr>
      <th class="tableblock halign-left valign-top">1-1</th>
      <th class="tableblock halign-left valign-top">2-1</th>
      <th class="tableblock halign-left valign-top">3-1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    <th class="tableblock halign-left valign-top">
    <p class="tableblock">1-2</p>
    </th>
    <td class="tableblock halign-left valign-top">
      <div>
        <div class="paragraph">
          <p><code>2-2</code></p>
        </div>
      </div>
    </td>
    <td class="tableblock halign-left valign-top">
      <div>
        <div class="paragraph">
          <p><code>3-2</code></p>
        </div>
      </div>
    </td>
    </tr>
  </tbody>
</table>

またこれは以下のように特定セルだけに個別で指定することができます。このサンプルであれば個別に指定したほうがいいでしょう。AsciiDocである必要もありません。

|===
|1-1|2-1|3-1

|1-2
m|2-2
m|3-2
|===

mはMonospacedで<code>でマークアップされます。ただし、Monospaced内ではReplacementsがきくありえない仕様になっているので注意が必要です。対策としてはaに設定して`を使うか、eBuilt-in entity attributesでごまかすしかなさそうです。

セルの結合方法はHTMLの記述にとてもよく似ています。

|===
3+|1-1

.2+|1-2
|2-2
|3-2

|2-3
|3-3
|===
<table class="tableblock frame-all grid-all spread">
  <colgroup>
    <col style="width: 33%;">
    <col style="width: 33%;">
    <col style="width: 33%;">
  </colgroup>
  <thead>
    <tr>
      <th class="tableblock halign-left valign-top" colspan="3">1-1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="tableblock halign-left valign-top" rowspan="2">
        <p class="tableblock">1-2</p>
      </td>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">2-2</p>
      </td>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">3-2</p>
      </td>
    </tr>
    <tr>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">2-3</p>
      </td>
      <td class="tableblock halign-left valign-top">
        <p class="tableblock">3-3</p>
      </td>
    </tr>
  </tbody>
</table>

数値のあとに+で連結になります。数値の前に.があれば縦方向への連結で、なければ横方向の連結です。

AsciiDocはCSVファイルをそのままテーブルにすることもできます。

[format="csv", options="header"]
|===
1-1,2-1,3-1
1-2,2-2,3-2
1-3,2-3,3-3
|===

その内容をincludeさせることもできます。

[format="csv", options="header"]
|===
include::data.csv[]
|===

参照文献