道を外れたAsciiDocの使い方 (GitHub, Vue.js, ほか活用事例)

## 概要
こんな使い方もあるよ…という記事です。これまで書いていない内容をピックアップしています。最後に、活用例をつけています。

* GitHub 上で使う
* Vue.js を呼び出す

### GitHub

#### ファイル配置
* README.adoc を各階層のトップページに使う
* include は諦める代わりに `<<hello.adoc#,Hello>>` のリンクで代替する
* `audio::xxx.mp3[options="controls"]` は表示されない
* `video::https://www.youtube.com/...[youtube, title="...", width=640, height=480]` も表示されない

#### 画像、他

* `ifdef::env-github[]` はなるべく使わない

   **Bad**

   ```asciidoc
   ifdef::env-github[]
   :imagesdir: images
   endif::[]
   ```

   **Good**

   ```asciidoc
   ifndef::imagesdir[]
   :imagesdir: images
   endif::[]
   ```

#### 数式の対応状況は悲惨

* ... でも諦めきれないなら、 [**ここ**](https://gist.github.com/a-rodin/fef3f543412d6e1ec5b6cf55bf197d7b) にあるように、画像リンクを埋め込む方法もなくはない。

    ```
    ifndef::env-github[]
    [stem,latexmath]
    ++++
    \begin{aligned}
    -1 &= 1 + t(z -1) \\
    t(z -1) &= -2 \\
    t &= \frac{2}{1-z}
    \end{aligned}
    ++++
    endif::[]
    ifdef::env-github[]
    image::https://render.githubusercontent.com/render/math?math=%5Cdisplaystyle+%5Cbegin%7Baligned%7D%0A-1+%26%3D+1+%2B+t%28z+-1%29+%5C%5C%0At%28z+-1%29+%26%3D+-2+%5C%5C%0At+%26%3D+%5Cfrac%7B2%7D%7B1-z%7D%0A%5Cend%7Baligned%7D[]
    endif::[]
    ```

    ちなみに、こんな感じになる。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/bf82a160-a292-1629-4096-c0f5e6295d7b.png)

### Vue.js も埋め込める

なんと、ドキュメント上をボタンをクリックするとカウンター増える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/2f2445c7-f3c4-49a7-fc91-aa911de9e00e.png)

評価した結果次のことが分かっている。

* Vue関連
  * Vue-Router が使えない
  * SingleFileConponent が使えない
  * ボタン等のアクションは使えるのでコンポーネント単位で埋め込める程度
  * CDN から持ってきてもちゃんと動く (オフラインで使いたいので、今回はCDN 版を使っていない)
* その他
  * 残念ながら GitHub では動かない (スクリプト全般が NG)
  * 動かしてみると分かるが、単純のため Increment のみ実装しているが、増やしたものを減らしてゼロに戻せない点がストレスになる

**コード**

```asciidoc
ifeval::["{backend}" == "html5"]
[pass]
++++
<!-- Vue3 -->
<script src="js/vue.global.js"></script>
++++
endif::[]

ifeval::["{backend}" == "html5"]
[pass]
++++
<div id="vuejs-counter">
  <h1>{{ count }}</h1>
  <button @click="increment">Increment</button>
</div>
<script>
include::js/vuejs_counter.js[]
</script>
++++
endif::[]
```

**js/vuejs_counter.js**

```javascript
const { ref, createApp } = Vue
createApp({
  setup() {
    const count = ref(0)
    const increment = () => { count.value++ }
    return { count, increment }
  }
}).mount('#vuejs-counter')
```

## おまけ - 活用事例

紹介済みのものもいくつかあるけれども、眺めて見られる程度にざっと集めました。

### 語学に活用できる

何気にGitHubでも見れた。`[pass]` でもスクリプトや外部ファイル取り込み以外はいけそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/87dc2681-d544-127b-ae4a-79932f0da853.png)

```asciidoc
好吃吗?:: おいしいですか？

我的手机是这个::
私の電話はこれです

[pass]
++++
<ruby>
  <rb>我</rb><rp>（</rp><rt>wǒ</rt><rp>）</rp>
  <rb>的</rb><rp>（</rp><rt>de</rt><rp>）</rp>
  <rb>手机</rb><rp>（</rp><rt>shǒu jī</rt><rp>）</rp>
  <rb>是</rb><rp>（</rp><rt>shì</rt><rp>）</rp>
  <rb>这个</rb><rp>（</rp><rt>zhè gè</rt><rp>）</rp>
</ruby>
++++
```

語学に活用できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/b79cd5c5-a436-9c3f-68e0-97b9f4ce51ab.png)


### コードサンプルを体系的にまとめる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/3581eb66-d252-7e72-af52-61688abce672.png)

なお、スタイルは色々試した結果 `golo.css` で Rogue は `monokai_sublime` あたりに落ち着いた。


**asciidoc.mk**

```Makefile
STYLESHEET_FILE=golo.css
STYLESHEET_DIR=$(BASE_DIR)/stylesheets
ROUGE_STYLE=monokai_sublime
AD_OPTS_HTML5_CODES=\
--backend=html5 \
-a stylesheet=$(STYLESHEET_FILE) -a stylesdir=$(STYLESHEET_DIR)　\
-r asciidoctor-diagram \
-a source-highlighter=rouge \
-a rouge-style=$(ROUGE_STYLE)
```

**programming/rust/Makefile**

ビルドのルールはパターンルールで共通化している。

```Makefile
BASE_DIR=../..
DIST_DIR=$(BASE_DIR)

OUTPUT_DIR_HTML=$(DIST_DIR)/html/programming/rust
IMAGES_DIR_HTML=images
OUTPUT_DIR_PDF=$(DIST_DIR)/pdf/programming/rust
IMAGES_DIR_PDF=$(OUTPUT_DIR_HTML)/images

include $(BASE_DIR)/asciidoc.mk

AD_OPTS_HTML5_CODES=\
$(AD_OPTS_HTML5_ROUGE)

HTML_LIST=\
$(OUTPUT_DIR_HTML)/examples-algorithms.html \
$(OUTPUT_DIR_HTML)/install.html \
$(OUTPUT_DIR_HTML)/interior-mutability.html \
$(OUTPUT_DIR_HTML)/match-expr.html \
$(OUTPUT_DIR_HTML)/math.html \
$(OUTPUT_DIR_HTML)/smart-pointers.html \
$(OUTPUT_DIR_HTML)/tutorial.html \
$(OUTPUT_DIR_HTML)/unsafe.html \
$(OUTPUT_DIR_HTML)/README.html

.PHONY: adoc
.SUFFIXES: .pdf .html .adoc

adoc: $(HTML_LIST)

$(OUTPUT_DIR_HTML)/%.html: %.adoc header.adoc ../common/header.adoc
	mkdir -p $(OUTPUT_DIR_HTML)
	-@test ! -d images || (test -d images && mkdir -p $(IMAGES_DIR_PDF))
	asciidoctor --trace $(AD_OPTS_HTML5_CODES) -o "$@" "$<"
	-@test ! -d images || (test -d images && cp -u -rp images/* $(IMAGES_DIR_PDF))

clean:
	rm -f $(HTML_LIST)

# EOF
```

### Dotを使う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/21a960b5-f2c7-adae-7e2c-db6c41e38468.png)

### 数式を合わせて使う

図は GeoGebra で作成した SVG画像。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/5b85f0a5-57e6-038a-2a23-21afa45808b0.png)

### Ploy.ly でグラフを表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/cef0bdd5-4c3a-319c-fb85-3d95c754b0e9.png)

JavaScript を入れるだけ

```asciidoc
== Jacobi elliptic functions

ifeval::["{backend}" == "html5"]
**楕円関数: f(_x_) = _x_^3^ -4__x__ - _y_^2^**
[pass]
++++
<div id="jacobi_elliptic_functions_plot_area"><!-- Plotly chart will be drawn inside this DIV --></div>
<script>
include::js/jacobi_elliptic_functions.js[]
</script>
++++
endif::[]
```

```javascript
function window_function(z, epsilon) {
    positive_z = Math.abs(z);
    if (positive_z > epsilon) return epsilon;
    return positive_z;
}

let cd_ary_x = [];
let cd_ary_y = [];
let cd_ary_z = [];

let x_min = -5;
let x_max = 5;
let x_sample_size = 600;
let dx = (x_max - x_min) / x_sample_size;

let y_min = -5;
let y_max = 5;
let y_sample_size = 600;
let dy = (y_max - y_min) / y_sample_size;

let epsilon = 0.1;

for (let x = x_min; x <= x_max; x += dx) {
  for (let y = y_min; y <= y_max; y += dy) {
    cd_ary_x.push(x);
    cd_ary_y.push(y);
    cd_ary_z.push(window_function(x*x*x - 4 * x - y * y, epsilon));
  }
}

var cd_trace = {
  color:'rgb(0,0,0)',
  x: cd_ary_x,
  y: cd_ary_y,
  z: cd_ary_z,
  type: 'contour',
  colorscale: 'Hot',
  z_min: 0,
  z_max: epsilon
};

var cd_layout = {
    hovermode:'closest',
    autosize: false, width: 600, height: 600,
    yaxis: { l: 10, r: 10, b: 10, t: 10, pad: 4 },
    paper_bgcolor: '#efefef'
};
Plotly.newPlot('jacobi_elliptic_functions_plot_area', [cd_trace], cd_layout, {displayModeBar: false});
```

### 参考: フォルダ構成

大規模になってきたので、こんな構成にしている。

```
+ asciidoc.mk
+ Makefile
+ rouge-themes
   + *.rb
+ stylesheets
   + *.css
+ common
   + header.adoc
+ category_1
   + Makefile
   + header.adoc
   + README.adoc
   + common
      + headder.adoc
   + sub_category_1
      + Makefile 
      + header.adoc   ../common/header.adoc を取り込み
      + README.adoc   header.adoc を取り込み
      + foo.adoc      header.adoc を取り込み
      + bar.adoc      header.adoc を取り込み
   + sub_category_2
      + Makefile 
      + header.adoc   ../common/header.adoc を取り込み
      + README.adoc   header.adoc を取り込み
      + aaa.adoc      header.adoc を取り込み
      + bbb.adoc      header.adoc を取り込み
```