12周年記念パーティ開催! 2024/5/10(金) 19:00

hologramでカスタムスタイルガイド 第1回 機能概要

第1回目はhologramというRubyで書かれたスタイルガイドジェネレータの基本的な機能を概観します。シンプルでありながら高い拡張性をも持ち合わせ、柔軟にスタイルガイドを作成することができます。

発行

著者 高津戸 壮 テクニカルディレクター
hologramでカスタムスタイルガイド シリーズの記事一覧

はじめに

このシリーズでは、hologram(ホログラム)という、Rubyで書かれたスタイルガイドジェネレータを紹介します。

まず第1回の今回は、hologramがどういったものか、サンプルとともに紹介しましょう。今回はざっくりとこんなふうになるという解説にとどめますので、細かい解説は次回以降に行っていきます。

なお、紹介するサンプルは次のリポジトリからダウンロード、またはクローンできます。併せて参照してください。

hologramサンプルリポジトリ

https://github.com/codegrid/hologram

このシリーズは、次の環境にて動作を確認しています。環境や各ソフトウェアのバージョン違いにより、本シリーズで解説している内容がそのまま動作しない可能性がありますので、その点ご留意ください。

  • OS X 10.9.4
  • Ruby 2.1.0p0
  • Bundler 1.5.3
  • hologram 1.1.0

hologramの特徴

この記事では、スタイルガイドとは何か、スタイルガイドジェネレータとは何かという解説は省きます。CodeGridで過去に、StyleDocco、KSSの2つのスタイルガイドジェネレータについて連載しましたので、そちらも併せて参照していただくと、本シリーズの内容をより深く理解できることと思います。

hologramは、Rubyで書かれたスタイルガイドジェネレータです。.css、.scss、.sass、.less、.styl形式のファイルに書かれたコメントから、自動でスタイルガイドを作ってくれます。スタイルガイドは、静的なHTMLファイルとして出力されます。

筆者は、過去の記事でも何度か取り上げてきたOOCSSのNicole Sullivan氏が、自身のプレゼンテーションの中でhologramを取り上げていたのを見て知りました。そのプレゼンテーションとは、以下です。

このプレゼンテーションの中では、Nicole Sullivan氏が関わった、とあるサイトのCSS再設計について解説されています。その中で、OOCSSのストラクチャとスキンを、スタイルガイド上で表現するのにhologramを使ったということが述べられていました。ちなみに、その中で紹介されていたスタイルガイドは、次のURLより閲覧可能です。

筆者はこのプレゼンテーションを見て興味を持ち、hologramを触ってみたわけですが、そのストラクチャとスキンの表現もさることながら、自分でスタイルガイドの見た目などをカスタマイズできるようになっており、これらが非常に手に馴染む感覚を得ました。

hologramは、若いオープンソースのプロジェクトで、正直なところ、まだドキュメントもそんなに用意されていませんし、気の利いたテンプレートも用意されているとは言えない段階のもののように思えます。サンプルとして提供されているテンプレートも、筆者としては、かなりわかりづらかったです。そのため、スタイルガイドとして出力されるHTMLのテンプレートは、自分でイチから書き直しました。現段階では、いくつかのコマンドを叩くだけで文句の付けようがない素晴らしいスタイルガイドができる……とは言えないでしょう。

しかしながら、hologramは追って解説するRedcarpetというgemや、Rubyの標準モジュールであるERBを使って作られており、とても自由度の高い作りとなっています。Rubyの基礎的な知識を持っている人であれば、かなりいじりやすいソフトウェアです。Rubyの勉強がてら、突っ込んで使ってみるのもよさそうです。

よくわからない箇所はこのシリーズにてカバーしているつもりですので、スタイルガイドに悩んでいる人は、一度、このシリーズを読みながら、hologramを触ってみてはいかがでしょうか。

YAML & Markdown

hologramは、CSSファイルのコメントに書かれたMarkdownをパースし、HTMLにしてくれます。各コメントは、その頭に書かれたYAMLフォーマットのデータを元に、ひとつの文章の塊としてまとめられ、インデックスされたHTMLファイルが作られます。

YAMLとは

YAML(ヤムル)とは、XMLやJSONのような、構造化されたデータを表現するテキストのフォーマットです。JSONと同じような構造を表現できるものと考えて問題ありません。例えば、次のようなYAMLのデータがあるとします。

apple: red
banana: yellow
grape: purple

これはJSONで表すと次のようなデータ構造になります。

{
  "apple": "red",
  "banana": "yellow",
  "grape": "purple"
}

このように、データを手軽に書けるのがYAMLの特徴です。

まずは、hologramによってどういったスタイルシートができるのか、例を見てみましょう。

例えば、次のようなCSSがあったとします。

/*doc
---
title: heading
name: heading
category: block
---

見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。

* この見出しはページに一回しか登場しません
* 箇条書きのリストが作れます

見出しです。こんなふうに解説を書きます。

1. 番号付きリストもかけます
2. 番号付きリストもかけます
3. 番号付きリストもかけます

## 以下は通常のHTMLとして書き出されます

<div class="heading">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>

## 以下はコードハイライトされて書きだされます

```html
<div class="heading">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
```

*/

.heading {
  border: 1px solid #7f8c58;
  padding: 10px;
  color: #fff;
  background: #97a66c;
}
.heading .subText {
  font-size: 12px;
  padding: 0 0 8px;
  margin: 0;
}
.heading .mainText {
  font-size: 16px;
  font-weight: bold;
  margin: 0;
}

hologramはこれを、次のようなHTMLへと変換してくれます。

<h1 id="heading">heading</h1>

<p>見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。見出しです。見出しの解説等をここに書きます。</p>

<ul>
<li>この見出しはページに一回しか登場しません</li>
<li>箇条書きのリストが作れます</li>
</ul>

<p>見出しです。こんなふうに解説を書きます。</p>

<ol>
<li>番号付きリストもかけます</li>
<li>番号付きリストもかけます</li>
<li>番号付きリストもかけます</li>
</ol>

<h2>以下は通常のHTMLとして書き出されます</h2>

<div class="heading">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>

<h2>以下はコードハイライトされて書きだされます</h2>
<div class="codeBlock"><div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;heading&quot;</span><span class="nt">&gt;</span>
  <span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">&quot;subText&quot;</span><span class="nt">&gt;</span>見出しの補足見出しの補足<span class="nt">&lt;/p&gt;</span>
  <span class="nt">&lt;h2</span> <span class="na">class=</span><span class="s">&quot;mainText&quot;</span><span class="nt">&gt;</span>彼は背後にひそかな足音を聞いた。それはあまり良い意味を<span class="nt">&lt;/h2&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</pre></div></div>

これにスタイルを当てると、例えば、次のような表示になります。

コメントの先頭に書いたYAMLのtitleが見出しになり、それ以降の内容はMarkdownとしてパースされ、HTMLになります。

出力されたHTMLと、元となったCSSファイルを見てみましょう。もうひとつ、別のコメントブロックもHTMLに変換されているのが確認できます。

基本的には、このように、CSSファイル内のコメントにMarkdownを書いていくことで、スタイルガイド*を作っていきます。

*注:スタイルガイドのスタイル

ちなみに、このスタイルガイドのCSSは、筆者が書いています。デフォルトでこの見栄えが用意されているわけではありません。

Redcarpetで細かなカスタマイズ

このようにMarkdownでスタイルガイドを書くことのできるhologramなのですが、hologramは、Redcarpetという、GitHubでも使われているRubyのgemを使って作られています。まず、Redcarpetは、シンタックスハイライトを自動できれいにやってくれます。具体的には、細々としたクラス付きのspan要素がコードに散りばめられることとなりますが、このHTMLにスタイルを当てると、例えば次のような表示にすることができます。

そして、とってもすばらしいのが、自分でいろいろとカスタマイズができるという点です。例えば、次のように```で囲まれたfenced code blockに囲まれたHTMLがあるとします。

```block
<div class="heading1">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
```

これを次のように、そのコードそのまま出力したもの(上側)と、コードハイライトしたもの(下側)両方を出力することができます。

Redcarpetは、fenced code blockの出力内容をカスタマイズできるようになっています。hologramを経由し、自分でRedcarpet用の追加ロジックを書くことで、さまざまなカスタマイズが可能です。この場合は、fenced code blockの言語指定がblockであった場合の出力内容を指定しています。

このほかRedcarpetで用意されているAPIは、hologramを経由して一通りいじれるようになっているので、こんなふうにしたいという場合、自分でRubyのコードを書くことにはなりますが、いろいろと融通が利きます。

実際にこの機能を使った出力結果を見てみましょう。出力されたHTMLと、元となったCSSファイルです。

blockが指定されたfenced code blockが、ちゃんと変換されて出力されているのがわかります。

parent機能

hologramには、はじめに軽く述べた通り、OOCSSにおけるストラクチャとスキンの関係であったり、BEMにおけるブロックとモディファイアの関係を表現するための、parentという機能があります。

参考

OOCSSやBEMについては、過去に連載した次の記事を参照してもらえればよいかと思います。

例えば、次のようなCSSがあったとします。

/*doc
---
title: heading1
name: heading1
category: heading
---

見出しのベースです。

```block
<div class="heading1">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
```

*/

.heading1 {
  border: 1px solid #000;
  padding: 10px;
}
.heading1 .subText {
  font-size: 12px;
  padding: 0 0 8px;
  margin: 0;
}
.heading1 .mainText {
  font-size: 16px;
  font-weight: bold;
  margin: 0;
}

この部分のCSSは、HTML上では、次のように表示されることを想定しています。

このとき、この部分のCSSコメントに書いたYAML内のnameheading1であることを覚えておいてください。

そして、この見出しのバリエーションとして、次のような見栄えの見出しを作りたいとします。

このような場合、OOCSSのスキンや、BEMのモディファイアの考え方を用いれば、次のようにし、複数のクラスでこれを実現することとなります。

<div class="heading1 heading1--typeA">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>

<div class="heading1 heading1--typeB">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
.heading1--typeA {
  color: #fff;
  border-color: #7f8c58;
  background: #97a66c;
}

.heading1--typeB {
  color: #fff;
  border-color: #8c6960;
  background: #cd9a8d;
}

そういったとき、次のように、そのコメントのYAMLへparent: heading1を追加します。

/*doc
---
title: heading1--typeA
name: heading1--typeA
category: heading
parent: heading1
---

バリエーション`typeA`です。

```block
<div class="heading1 heading1--typeA">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
```

*/

.heading1--typeA {
  color: #fff;
  border-color: #7f8c58;
  background: #97a66c;
}


/*doc
---
title: heading1--typeB
name: heading1--typeB
category: heading
parent: heading1
---

バリエーション`typeB`です。

```block
<div class="heading1 heading1--typeB">
  <div class="subText">見出しの補足見出しの補足</div>
  <h2 class="mainText">彼は背後にひそかな足音を聞いた。それはあまり良い意味を</h2>
</div>
```

*/

.heading1--typeB {
  color: #fff;
  border-color: #8c6960;
  background: #cd9a8d;
}

すると、これらのコメント群が離れている場合でも、次のようにheading1に、一段階レベルの下がった見出しとともに、後続する形でスタイルガイドが作られます。

この機能を使えば複数のファイルにまたがるコードであっても、構造を考慮し、hologramがうまい具合にひとつのHTMLに出力をまとめてくれます。上記サンプルでは、コメントの順序としては、次のようになります。

  • heading1
  • heading2
  • heading1--typeA
  • heading1--typeB

ここでheading2のコメントの内容が、最後に配置されていることに注目してください。

OOCSSやBEMなどのモジュールを意識したコーディングを行う際、このような機能は有効に機能するでしょう。

今回は、hologramの機能をざっくりと紹介しました。次回はhologramを実際に動かしてみながら、機能の解説をしていきます。