但し書き
純粋なMarkdownのリンクの記法にはtarget="_blank"
を付けるようなものはない。なので<a href="http://google.com" target="_blank">google</a>
と書かないといけない。外部サービスでそういうことをしようと思ったら、そのサービスで対応してればその方法を使い、なければ諦めてこうしてhtmlをベタ書きするしかない。
そして自分のサイトでこれをやるには、一般的には変換後のDOMを書き換えたり、リンクのクリックイベントに引っ掛けるのが主流である。しかしMarkdownのパーサーにmarked.jsを使っているなら、少しだけ気分よくtarget="_blank"
を付与することができる
やりたいこと
- hrefが
/
スラッシュから始まるなら内部リンクとする - そうでなければ
target="_blank"
を付与して、外部リンクを示すアイコンを付ける - リンクのテキストが
http://hoge.com
みたいに完全なURLならアイコンは付けない
これを変換のついでに行うようにしてみる。
コード
marked = require 'marked'
renderer = new marked.Renderer()
renderer.link = (href, title, text)->
external = not /^\//.test href
usePrefix = external and not /^http/.test text
target = if external then ' target="_blank"' else ''
prefix = if usePrefix then "<i class=\"fa fa-fw fa-external-link\"></i> " else ''
title = if title then " title=\"#{title}\"" else ''
href= " href=\"#{href}\""
"<a#{href}#{target}#{title}>#{prefix}#{text}</a>"
marked.setOptions
renderer: renderer
このコードはサーバーでもブラウザでも使える。ちなみにこのサイトではブラウザ側で変換している。これを初期化時にやっておけば、あとは普通に変換すれば良い。
表示例
* 内部リンク ... [トップ](/)
* 外部リンク ... [外部リンク](http://google.com)
* 明示的な外部リンク ... http://google.com
が、
<ul>
<li>内部リンク ... <a href="/">トップ</a></li>
<li>外部リンク ... <a href="http://google.com" target="_blank"><i class="fa fa-fw fa-external-link"></i> 外部リンク</a></li>
<li>明示的な外部リンク ... <a href="http://google.com" target="_blank">http://google.com</a></li>
</ul>
こうなって、
こうなる。
おまけ
highlight.jsを使ってコードスニペットのハイライトをする。
marked = require 'marked'
hljs = require 'highlight.js'
marked.setOptions
highlight: (code, lang, callback)->
if lang
try
hljs.highlight(lang, code).value
catch
code
else
code
try catch
してるのは、```lang
みたいにバッククオートのあとに指定した言語がhighlight.js
で対応してなかった時に、例外を起こして変換に失敗するので、その対処である。highlight.js
のdocには「言語は自動で識別するよ」的ことをなことが書いてあるが、それは嘘である。ほとんど期待した言語でハイライトしてくれないので、ちゃんと頭で言語を指定するべきである。