16
20

More than 5 years have passed since last update.

Railsアプリでのシンタックスハイライト付Markdown対応

Last updated at Posted at 2017-03-03

先日ブログサイトをRailsで自作したときに本文をMarkdownで書けるようにしました。併せてソースコードのシンタックスハイライトも実現したのですが、とても簡単だったので書いておきます。

使ったもの

普通にRedcarpetを使う場合

そもそものRedcarpetの使い方はこのような感じです。

renderer = Redcarpet::Render::HTML.new(options) 

# バッククオート3つで囲むフォーマットに対応
markdown = Redcarpet::Markdown.new(renderer, fenced_code_blocks: true) 

# markdownのテキストをHTMLに変換
html = markdown.render(content) 

Rendererを継承してメソッドをオーバーライドしていくことで好みの設定に拡張していくことができます。

ちなみにRedcarpetのみの状態でfenced_code_blocksを使ってRailsのソースコードを書いてみます。

```ruby
# app/controllers/api/api_controller.rb
class Api::ApiController < ApplicationController
  before_action :doorkeeper_authorize!
  helper_method :current_user

  def current_user
    User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
  end
end
```

HTMLのソースはこのようになります。

<code class="ruby">
# app/controllers/api/api_controller.rb 
class Api::ApiController &lt; ApplicationController
  before_action :doorkeeper_authorize!
  helper_method :current_user

  def current_user
    User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
  end
end
</code>

Rouge gemを使えるようにする

Redcarpetと連携すればRougeを少しのステップで使い始めることができます。

はじめにGemfileにgem 'rouge'を加えてbundleします。RougeのRedcarpet対応のプラグインをincludeしたRendererを用意し、このファイルをRailsのロードパスに置きます。

require 'rouge/plugins/redcarpet'

class HTML < Redcarpet::Render::HTML
  include Rouge::Plugins::Redcarpet
end

最初に紹介したRedcarpetの使い方のコードのうち、Redcarpet::Render::HTMLのところを先程用意したクラスに置き換えることで、ソースコード部分がRougeで処理されるようになります。

renderer = HTML.new(options) 
markdown = Redcarpet::Markdown.new(renderer, fenced_code_blocks: true) 
html = markdown.render(content) 

するとこのようにソースコードの箇所に細かくCSSのクラスが付きます。

<pre class="highlight ruby"><code>
<span class="c1"># app/controllers/api/api_controller.rb </span>
<span class="k">class</span> <span class="nc">Api</span><span class="o">::</span><span class="no">ApiController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
  <span class="n">before_action</span> <span class="ss">:doorkeeper_authorize!</span>
  <span class="n">helper_method</span> <span class="ss">:current_user</span>

  <span class="k">def</span> <span class="nf">current_user</span>
    <span class="no">User</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span><span class="n">doorkeeper_token</span><span class="p">.</span><span class="nf">resource_owner_id</span><span class="p">)</span> <span class="k">if</span> <span class="n">doorkeeper_token</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre>

ですが、このままではハイライトされません。スタイルがないからです。

スタイルをあてる

Rougeではシンタックスハイライト用のCSSを生成できるようになっています。

いくつかのテーマと、ソースコード部分のDOMのトップにつけるクラスを指定できます。僕はSublime TextなどのMonokaiテーマを好んで使っているので↓のような感じですね。

Rouge::Themes::MonokaiSublime.render(scope: '.highlight')

生成されたCSSをファイルに保存してからアプリケーションに読み込んでもいいのですが、どうせプリコンパイルされるので僕はアセットパイプラインに入れてしまっています。

rouge.scss.erb
<%= Rouge::Themes::MonokaiSublime.render(scope: '.highlight') %> 

すると、こんなふうになりました。

一部コメントや括弧の色のスタイルを調整していますが、それなりに見えていい感じじゃないでしょうか。

ちなみに、文中に使っているソースコードは自分の投稿から引用しました。


RailsアプリにiOSクライアントをサッと作る #sgadvent | ぴよログ

16
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
20