middleman-syntaxでGitHubみたいにきれいにhighlightingする方法

middleman

Middlemanで作ったサイトでは、簡単に自分のサンプルコードにsyntax highlightを適用することが可能です。まるで、GitHub上のコードと同じような見た目にすることも可能です。

middleman-syntaxの導入

詳しくは公式READM(英語)を見て頂きたいですが、つまづいた部分とその対応策も含めて簡単に流れを説明します。

Gemfileの修正とbundle install

以下をGemfileに追加し、bundle installをコマンドラインで実行します。

1
gem "middleman-syntax", "~> 2.0.0"

config.rbの修正

以下を追加します。

1
activate :syntax, line_numbers: true

こちらでこのライブラリを有効化しています。line_numbers: trueはコードの左の行番号を表示する設定です。
ちなみにconfig.rbを修正したらmiddleman serverを再起動しないと反映されないようです。さらにcssの設定も必要になります。

cssの設定

highlighting用のcss

highlighting用のcssがerbで動的に生成されるようにします。
なので、ファイル名は_highlighting.css.erbなどにします。scssを使用している場合は拡張子を.scss.erbにします。中身には以下を書いて下さい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<%= Rouge::Themes::Github.render(:scope => '.highlight') %>

.highlight {
  margin-bottom: 2em;
  background: #fff;
  .gutter {
    width: 50px;
    background: #fafafa;

    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }
  table {
    width: 100%;
    table-layout: fixed;
    td {
      padding: 0;
      border: solid 1px #ddd;
    }
  }
 .lineno{
    color: #999;
    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
  }

  pre {
    padding: 0.5em;
    overflow-x: auto;
    white-space: pre;
    word-wrap: inherit;
  }
}

1行目のGithubの部分は色のバリエーションでThankfulEyesColorfulGithubBase16Base16::SolarizedBase16::MonokaiMonokaiから選べるのですが、今回はGithub風にしたいので、Githubを選んでいます。

このコードは以下の記事を参考に、独自に作ったものです。

BETTER GITHUB-STYLE SYNTAX HIGHLIGHTING WITH ROUGE

ファイル名の頭のアンダースコアの意味

_highlighting.css.erbのようにファイル名の頭にアンダースコアをつけているのは、cssをhtmlソースファイルだと認識されないようにするためです。これがないと、middleman build実行時に以下のようなエラーが発生する可能性があります。

1
2
       error  build/stylesheets/highlighting/index.html
Not found

また、アンダースコアをつけたくない場合、config.rbに以下を追加することでも認識されないようにできます。pathは適当なものに変えてください。こちらのissueを参考にしました。

1
ignore "/stylesheets/highlighting.css.erb"

cssが読み込まれるようにする

このcssをhtmlから直接読み込むようにするには、以下を適当な部分に追加します。

1
<%= stylesheet_link_tag "highlighting" %>

scssでまとめている場合は、all.scssなどに以下を追加します。(上のコードは不要です。)

1
@import "highlighting";

これであとはコードブロックを書けば、本サイトと同じコードブロックのスタイルのものができます。

コードブロックを書く

書き方

詳しくはこちらを見て頂きたいですが、erbとmarkdownで使用する場合は下のような形です。

erbの場合

1
2
3
4
5
<% code("ruby") do %>
def my_cool_method(message)
  puts message
end
<% end %>

Markdownの場合

1
2
3
4
5
~~~ruby
def my_cool_method(message)
  puts message
end
~~~

よりGithubらしく書くには

MiddlemanのデフォルトのMarkdownパーサーはKramdownというライブラリです。こちらのデフォルトのマークダウンの書き方は、上記のように~を使います。

ですが、Githubでは以下のように`を使います。

1
2
3
4
5
``` ruby
def some_method
  puts "Hello"
end
```

middlemanでもconfig.rbで、以下を追加してあげればGithubと同じ書き方ができるようになります。GFMというのはGithub Flavored Markdownの略です。

1
set :markdown, input: "GFM"

表示がおかしい場合の対処法

行の長さが親要素の幅より長い時に横スクロールで表示されない

前述したhighlighting.css通りのものを使っていれば発生しないはずですが、何かの都合で修正したり違うものを使った場合、以下の現象が発生する場合があります。

親要素からはみ出す

(( コードが流すぎてはみ出した画像 ))

行の途中で改行される

(( 行の途中で改行される画像 ))

確認ポイント

上の2つの現象が出る場合、前述したhighlighting.cssの32〜34行目がきちんと設定されているかを確認してください。

1
2
3
overflow-x: auto;
white-space: pre;
word-wrap: inherit;

overflow-xは親要素より幅が大きい場合にどのように表示するかを決めます。white-spaceword-wrapは改行についての設定です。

スマホでの表示がおかしい場合

フォントが大きくなり行番号とずれる

(( コードのフォントが大きくなってしまう画像 ))

確認ポイント

-webkit-text-size-adjustという設定を確認します。スマホでの縦向きと横向きとの文字サイズを自動的に調整する機能です。こちらが悪さをしこの現象がおきています。興味のある方は以下を参照ください。
-webkit-text-size-adjust: none を絶対に設定してはいけない理由

これは私のみたところ以下の条件がそろうと発生しているようです。

  • 行番号を表示している。
  • 親要素の幅より長い行がある。
  • -webkit-text-size-adjust: 100%;を設定していない。

なので、以下がcssで設定されていると正常な大きさになります。

1
2
3
body {
  -webkit-text-size-adjust: 100%;
}

実はこの設定は、通常middleman initを実行した際に生成されるファイルnormalize.cssに含まれています。こちらのcssがきちんと読み込まれるようになっているかをまず確認しましょう。
middleman init時に指定するテンプレートによっては生成されないので、その場合はこのコードをcssのどこかに書きましょう。

スマホは実機で確認したほうが良い

chromeのデバッグモードなど、単にuser agentを偽装するだけのシミュレータだと再現できません。実機での確認をおすすめします。下のページはiPhoneのsafariで表示中にMac側からデバッグできる方法です。

iOS SafariのWebインスペクタをMac Safariで表示してデバッグする

まとめ

いかがでしたでしょうか。middleman-syntaxで簡単にGithubライクなコードブロックが書けます。ただ、公式のREADMEのみを参考に進めても、イレギュラーな事象がいくつか発生してしまうことがあります。そんな時はこの記事を参考にして頂ければと思います。

羊毛や小麦