スタイルガイドジェネレーター Styledownを使ってみた

# スタイルガイドに欲しい機能

- exampleのpug対応・・・開発はpugを使う事が多いため。
- pugコード出力・・・pugのコードをコピーして展開して欲しいため。
- ガイド生成用のコメントがソースファイル記述ではない・・・sassファイル内に記述したくない。
- ガイド用のラッパーなどがレスポンシブ対応の邪魔をしない・・・widthなど指定していない。もしくはオプションで消すなど可能であること。

---

# Styledown

今回は「Styledown」を使ってみました。
https://github.com/styledown/styledown
http://cdn.rawgit.com/styledown/styledown/v1.0.2/examples/bootstrap/index.html

---

# 環境
* Windows 10
* node 8.91
* npm 5.5.1
* gulp 3.9.1

---

# 構成
```
│  .babelrc
│  .editorconfig
│  .jsbeautifyrc
│  gulpfile.babel.js
│  package.json
│  yarn-error.log
│  yarn.lock
│  
├─htdocs
│
├─sg
│  │  conf.md
│  │  
│  └─md
│          button.md
│          helper.md
│
└─src
```

---

#インストール
`yarn add babel-preset-es2015 babel-register gulp gulp-shell git+https://github.com/Pelckmans/styledown.git`

※styledownはpug出力したかったので、Forkされているのを使用しています。（左記理由のためgulp-styledownは使用していません）
※gulp-shellは任意（gulpから出力したい場合）

---

# Markdown（conf）ファイル

```sg/conf.md
# Styleguide options

### Head

   //link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css')
   //link(rel='stylesheet' href='http://cdn.rawgit.com/styledown/styledown/v1.0.2/examples/bootstrap/_extras.css')
   link(rel='stylesheet' href='https://cdn.rawgit.com/styledown/styledown/v1.0.2/data/styledown.css')
   link(rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css")
   link(rel="stylesheet" href="css/common/base.css")
   style.
      .sg-header {
         background: #fafafa;
         border-bottom: solid 1px #eee;
         padding-top: 2em;
         padding-bottom: 2em;
      }
      .sg-header h1 {
         font-size: 2em;
      }
      @media (min-width: 768px) {
         .sg-text, .sg-text + .sg-example, .sg-text + .sg-code {
            float: none;
            width: auto;
         }
      }
   script(src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous")
   script(src="https://cdn.rawgit.com/styledown/styledown/v1.0.2/data/styledown.js")
   script(src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js")
   script.
      $(function() {
         $(".sg-code").each(function(i, block) {
            hljs.highlightBlock(block);
         });
      });

### Body
   
   .sg-header
      h1 Styleguides
   .sg-content(sg-content)

```

HEADセクションでカスタマイズしています。
「link(rel="stylesheet" href="css/common/base.css")」で自作のcssを読み込んでいます。
他、highlight.min.jsなど入れてますが、このあたりは好みで拡張して下さい。
BODYセクション内の(sg-content)にてMarkdown(ガイド)ファイルの内容が出力されるようです。

---

#Markdown(ガイド)ファイル

```sg/helper.md
## Helper

### ch__align
`.ch__align` - ボックスの位置
	
	@example
	.ch__align_left(style="width:1em;height:1em;background-color:#000;")
	.ch__align_center(style="width:1em;height:1em;background-color:#000;")
	.ch__align_right(style="width:1em;height:1em;background-color:#000;")


### ch__text
`.ch__text` - テキストの太さ、位置、装飾
	
	@example
	p.ch__text_normal 標準テキスト
	p.ch__text_bold 太字テキスト
	p.ch__text_left 左寄せテキスト
	p.ch__text_center 中央寄せテキスト
	p.ch__text_right 右寄せテキスト
	p.ch__text_overline 上線テキスト
	p.ch__text_underline 下線テキスト
	p.ch__text_strike 打ち消し線テキスト
```

```sg/button.md
## Button

### Button
`.button` - ボタン

   @example
   a.cc__btn_default ボタン
   a.cc__btn_dark ボタン
```

---

# YARN

```
yarn run styledown sg/md/helper.md sg/md/button.md sg/conf.md -o htdocs/guide.html
```
yarnコマンドから出力したい場合です。
以下注意が必要です。
1.ソースファイルをglob「sg/md/*.md」指定するとエラーで出力できませんでした。
2.-oオプションでファイル出力していますが、出力されるディレクトリが存在しない場合エラーになります。（上記yarnコマンドの場合htdocsが存在しない場合はエラーになります）

---

# Gulpfile

```gulpfile.babel.js
import shell from "gulp-shell";
gulp.task("styledown", () => {
	let md = ["sg/md/helper.md", "sg/md/button.md"];
	let conf = "sg/conf.md";
	let out = "htdocs/guide.html";
	return gulp.src("").pipe(shell(`yarn run styledown ${md.join(" ")} ${conf} -o ${out}`))
});
```

gulpから出力したい場合です。注意点はYARN同様です。

---

# 出力コード
- markdownのh2は自動でidをつけるようです。（下記コードのid="helper",id="button"）
- markdownのh1はオプションとして認識されるので使えません。
- 出力コードを見る限りガイド用のセクションやサンプルなどはsgをprefixで出力されるようです。（.sg-section,.sg-canvas, .sg-exampleなど）
- レスポンシブ対応する場合は、HEADセクションにmeta(name="viewport" content="width=device-width")の追加で対応できそうです。


```htdocs/guide.html

<!doctype html>
<html class="sg">

<head>
  <meta charset="utf-8">
  <title>Styledown</title>
  <!--link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css')-->
  <!--link(rel='stylesheet' href='http://cdn.rawgit.com/styledown/styledown/v1.0.2/examples/bootstrap/_extras.css')-->
  <link rel="stylesheet" href="https://cdn.rawgit.com/styledown/styledown/v1.0.2/data/styledown.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
  <link rel="stylesheet" href="css/common/base.css">
  <style>
    .sg-header {
      background: #fafafa;
      border-bottom: solid 1px #eee;
      padding-top: 2em;
      padding-bottom: 2em;
    }
    .sg-header h1 {
      font-size: 2em;
    }
    @media (min-width: 768px) {
      .sg-text,
      .sg-text + .sg-example,
      .sg-text + .sg-code {
        float: none;
        width: auto;
      }
    }
  </style>
  <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
  <script src="https://cdn.rawgit.com/styledown/styledown/v1.0.2/data/styledown.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>
    $(function() {
      $(".sg-code").each(function(i, block) {
        hljs.highlightBlock(block);
      });
    });
  </script>
</head>

<body class="sg"><script id="__bs_script__">//<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.18.13'><\/script>".replace("HOST", location.hostname));
//]]></script>

  <div class="sg-header">
    <h1>Styleguides</h1>
  </div>
  <div class="sg-content">
    <section class="sg-section sg-section-helper">
      <h2 id="helper" class="sg">Helper</h2>
      <section class="sg-block sg-section-ch__align">
        <div class="sg-text">
          <h3 id="ch__align" class="sg">ch__align</h3>
          <p class="sg">
            <code class="sg">.ch__align</code>- &#x30DC;&#x30C3;&#x30AF;&#x30B9;&#x306E;&#x4F4D;&#x7F6E;</p>
        </div>
        <div class="sg-example">
          <div class="sg-canvas">
            <div style="width:1em;height:1em;background-color:#000;" class="ch__align_left"></div>
            <div style="width:1em;height:1em;background-color:#000;" class="ch__align_center"></div>
            <div style="width:1em;height:1em;background-color:#000;" class="ch__align_right"></div>
          </div><pre class="sg-code">.ch__align_left(style=&quot;width:1em;height:1em;background-color:#000;&quot;)
.ch__align_center(style=&quot;width:1em;height:1em;background-color:#000;&quot;)
.ch__align_right(style=&quot;width:1em;height:1em;background-color:#000;&quot;)
</pre>
        </div>
      </section>
      <section class="sg-block sg-section-ch__text">
        <div class="sg-text">
          <h3 id="ch__text" class="sg">ch__text</h3>
          <p class="sg">
            <code class="sg">.ch__text</code>- &#x30C6;&#x30AD;&#x30B9;&#x30C8;&#x306E;&#x592A;&#x3055;&#x3001;&#x4F4D;&#x7F6E;&#x3001;&#x88C5;&#x98FE;</p>
        </div>
        <div class="sg-example">
          <div class="sg-canvas">
            <p class="ch__text_normal">&#x6A19;&#x6E96;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_bold">&#x592A;&#x5B57;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_left">&#x5DE6;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_center">&#x4E2D;&#x592E;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_right">&#x53F3;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_overline">&#x4E0A;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_underline">&#x4E0B;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
            <p class="ch__text_strike">&#x6253;&#x3061;&#x6D88;&#x3057;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;</p>
          </div><pre class="sg-code">p.ch__text_normal &#x6A19;&#x6E96;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_bold &#x592A;&#x5B57;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_left &#x5DE6;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_center &#x4E2D;&#x592E;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_right &#x53F3;&#x5BC4;&#x305B;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_overline &#x4E0A;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_underline &#x4E0B;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
p.ch__text_strike &#x6253;&#x3061;&#x6D88;&#x3057;&#x7DDA;&#x30C6;&#x30AD;&#x30B9;&#x30C8;
</pre>
        </div>
      </section>
    </section>

    <section class="sg-section sg-section-button">
      <h2 id="button" class="sg">Button</h2>
      <section class="sg-block sg-section-button">
        <div class="sg-text">
          <h3 id="button" class="sg">Button</h3>
          <p class="sg">
            <code class="sg">.button</code>- &#x30DC;&#x30BF;&#x30F3;</p>
        </div>
        <div class="sg-example">
          <div class="sg-canvas">
            <a class="cc__btn_default">&#x30DC;&#x30BF;&#x30F3;</a>
            <a class="cc__btn_dark">&#x30DC;&#x30BF;&#x30F3;</a>
          </div><pre class="sg-code">a.cc__btn_default &#x30DC;&#x30BF;&#x30F3;
a.cc__btn_dark &#x30DC;&#x30BF;&#x30F3;
</pre>
        </div>
      </section>
    </section>

  </div>
</body>

</html>
```
---

# 出力キャプチャ
ほとんどスタイルを潰しているし、まだ何も作り込んでいないため一見しょぼく見えますが、
注目して欲しいのはコードの部分でpugのコードが出力されています。
![guide.png](https://qiita-image-store.s3.amazonaws.com/0/80664/8c4da149-2f67-50f1-3784-09ff271ffad7.png)

---

# 試してみて
シンプルな分、カスタマイズは容易でした。
ナビゲーションもconf.mdのBODYセクション内に記述してやれば良い気がします。
但し、検索機能はないので大規模になってくると辛いかもと思いました。