ローカル画像生成サーバ作ってMarkdown記事執筆を加速する

注: gif大量で重いです。

きっかけはこれ。

* [もう保守されない画面遷移図は嫌なので、UI Flow図を簡単にマークダウンぽく書くエディタ作った - Qiita](http://qiita.com/hirokidaichi/items/ff54a968bdd7bcc50d42)

便利そうだけど、そこらへんのMarkdownエディタでプレビュー見れないのが難点。
好きなMarkdownエディタで使えたらいいのになー。

と思って試したらできた！しかも無限の可能性を感じたのでレッツ紹介！

# 書き方

好きなMarkdownエディタ環境でこう書くだけです。
リアルタイムプレビュー機能付きのオンラインエディタ推奨。

```text:markdown
![uiflow](http://127.0.0.1:8888/uiflow/
[最初に]
ユーザーが見るものを書きます。
~~
ユーザーがする行動を書きます。
[次に]
ユーザーが見るもの
~~
ユーザーがすること１
==> その結果１
ユーザーがすること２
==> その結果２
[その結果１]
結果
[その結果２]
結果
)
```

すると、画像タグとして解釈されてこんな画像になります。見れますか？

![uiflow](http://127.0.0.1:8888/uiflow/
[最初に]
ユーザーが見るものを書きます。
~~
ユーザーがする行動を書きます。
[次に]
ユーザーが見るもの
~~
ユーザーがすること１
==> その結果１
ユーザーがすること２
==> その結果２
[その結果１]
結果
[その結果２]
結果
)

↑これ

えっリンク切れてる？私にはこう見えてます。

![uiflow.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/a973b6d1-f38c-d1e1-efb7-bb4ec24b40f3.gif)

はい。
つまり、Markdownの画像タグが案外いろんな表現使えるようなので、
ローカルサーバひっぱたいてその場で画像作ろうぜ！というわけです。

# さっくり試す

これ殴り書いて、

```js:index.js
'use strict';
const http = require('http');
const fs = require('fs');
const uiflow = require('uiflow');
const viz = require("viz.js");

http.createServer(function(req, res) {
  const urls = req.url.split('/');
  if (urls.length < 3) {
    res.writeHead(404);
    res.end();
    return;
  }
  const generator = urls[1];
  const code = decodeURI(urls.slice(2).join('/')).trim();
  if (generator === 'uiflow') {
    // ハイフン代用のチルダを元に戻す
    const uiflowCode = code.replace(/^~+$/mg, '--');
    const svg = viz(uiflow.compile(uiflowCode));
    res.writeHead(200, {
      'Content-Type': 'image/svg+xml',
      'Content-disposition': 'attachment; filename=uiflow.png'
    });
    res.write(svg);
    res.end();
  } else {
    res.writeHead(404);
    res.end();
  }
}).listen(process.env.PORT || 8888, '127.0.0.1');
```

サーバを起動するだけ！

```
$ npm install viz uiflow
$ PORT=8888 node index.js
```

起動できたら、さっきの画像が表示されるか見てみましょう。
もし見れたのならおめでとう、あなたはもう既に、
好きなMarkdownエディタでuiflow記法が使える世界に在るのです！

※uiflowでエラー出るならこっちで。

```
$ npm install uiflow@git+https://github.com/tkrkt/uiflow.git#fix-argument-in-compile
```

# 特徴

利点

* 好きなMarkdownエディタで使える！
* 執筆中ちょっと画像欲しい時にささっと作れる！
* 変更がリアルタイムでプレビューされる！
* ジェネレータ次第で可能性無限大！

欠点

* 公開する場合一度画像を保存し直す必要がある
* Markdownの制限によって一部の記法が使えない（カッコと空行使えないのが痛い）
* 自分で脆弱性作ってるようなもんなので悪意のあるサイトがさらに凶悪になる
* [GitHub](https://help.github.com/articles/why-do-my-images-have-strange-urls/)など画像URL書き換えるとこでは使えない(一部では使える？)

思ったより制限あるが...　まあ問題ない！

# 応用例

アイデア次第でいろいろ使えるのでは...？

軽く計算したいとき

![eval.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/69c0d0a0-0bb5-fbc8-67ae-3fa54e1637c3.gif)

グラフ書きたいとき

![plot.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/fd59d9ff-02c7-5564-26cd-eb4ddd14a38b.gif)

フォント紹介したいとき

![text.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/6eca9f44-9033-154d-d0ba-9712b5b419d4.gif)

ウェブのスナップショット撮りたいとき

![webshot.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/7026b6b8-f5ae-6398-0db0-0347198b8a88.gif)

画像生成したいとき

![elen.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/33e32291-e455-4804-6eaf-1352a1fdac3a.gif)

ゲームしたいとき

![dq.gif](https://qiita-image-store.s3.amazonaws.com/0/60243/d99a6cbf-3dc4-14d5-53a8-75a01e922fe6.gif)

クッキーやらリファラやらgifアニメやら使えば可能性無限大ですね！

# ガッツリ試す

完成度低いですが、気が向いたときにちまちまと書いてます。

* [tkrkt/imagency: Dynamic image generator for markdown writing](https://github.com/tkrkt/imagency)

初めてnpm publishもしました。

* [tkrkt/text2png: text-to-png generator for Node.js](https://github.com/tkrkt/text2png)

案の定npmignoreをミスって.ideaフォルダをpublishしましたよ。
~~早速unpublish~~ 素直にupdateして事なきを得ました。
（package.jsonのfilesプロパティ使うと良いらしいですね。）

そのうちまともなプラグインシステム作ったり、コマンド実行できたり、
直近に生成した画像のフォルダから簡単に添付できるGUIツール作れたらいいな。

# 終わり

というわけでいかがだったでしょうか。
一人でテンション上がっていろいろ考えてたけど需要あるのかしら。
もう既に似たようなのあったら教えてください。