LoginSignup
24
19

More than 5 years have passed since last update.

markedでqiitaライクにファイル名を表示する

Last updated at Posted at 2016-02-25

Qiitaでコードハイライトにファイル名を加える場合、言語の後に:filenameと入力することで、これが表示できます。

```js:index.js
import hoge from 'hoge';
`` `
index.js
import hoge from 'hoge';

markedHighlight.jsでこれを実現する場合、markedのオプションを少し変更する必要があります。

環境設定

今回は確認をブラウザ上で行いますので、下記index.htmlを用意します。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Filename</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.js"></script>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/monokai_sublime.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>
</head>
<body>

<script>
var md = "```js:index.js\nimport hoge from 'hoge';\n```";
var highlight = function(code, lang, callback){
  // hljs.highlightの第一引数にはlangを渡すのが適切だが、`js:index.js`という言語は存在しないため、暫定的にハードコーディングで済ます
  return hljs.highlight('js',code).value;
}
var renderer = new marked.Renderer;
var html = marked(md,{
  highlight: highlight,
  renderer: renderer,
});

document.body.innerHTML = html;
</script>

</body>
</html>

ブラウザ上でmd内のマークダウン文字列が、整形されて表示されることを確認します。

DEMO

スクリーンショット 2016-02-25 14.21.46.gif

renderer.codeのオーバーライド

marked - Overriding renderer methodsで説明されているように、markedのオプション引数rendererのプロパティを定義し直すことで、マークダウン文字列のコンパイル内容を変更することができます。

marked-v0.3.5のもともとのコードブロックの処理は、下記のとおりです。

v0.3.5/lib/marked.js#L764-L785
Renderer.prototype.code = function(code, lang, escaped) {
  if (this.options.highlight) {
    var out = this.options.highlight(code, lang);
    if (out != null && out !== code) {
      escaped = true;
      code = out;
    }
  }

  if (!lang) {
    return '<pre><code>'
      + (escaped ? code : escape(code, true))
      + '\n</code></pre>';
  }

  return '<pre><code class="'
    + this.options.langPrefix
    + escape(lang, true)
    + '">'
    + (escaped ? code : escape(code, true))
    + '\n</code></pre>\n';
};

さきほどのindex.htmlは、既にrendererインスタンスをオプション引数に渡しているので、renderer.codeプロパティを定義し直すことで、ファイル名を表示することができます。

DEMO

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.js"></script>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/monokai_sublime.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>

  <style>
    pre{
      background-color: #F7F7F6;
    }
    pre .filename{
      display: inline-block;
      padding: 0 .25em;
      background: rgba(0,0,0,0.07);
    }
    pre .filename+ *{
      display: block;
    }
  </style>
</head>
<body>

<script>
var md = "```js:index.js:fuga\nimport hoge from 'hoge';\n```";
var highlight = function(code, lang, callback){
  return hljs.highlight(lang,code).value;
}
var renderer = new marked.Renderer;
renderer.code = function(code, fileInfo, escaped) {
  var delimiter = ':';
  var info = fileInfo.split(delimiter);
  var lang = info.shift();
  var fileName = info.join(delimiter); // 2つ目以降のdelimiterはファイル名として扱う
  var fileTag = '';
  if (fileName) {
    fileTag = '<code class="filename">'+fileName+'</code>'
  }

  if (this.options.highlight) {
    var out = this.options.highlight(code, lang);
    if (out != null && out !== code) {
      escaped = true;
      code = out;
    }
  }

  if (!lang) {
    return '<pre>'+fileTag+'<code>'
      + (escaped ? code : escape(code, true))
      + '\n</code></pre>';
  }

  return '<pre>'+fileTag+'<code class="'
    + this.options.langPrefix
    + escape(lang, true)
    + '">'
    + (escaped ? code : escape(code, true))
    + '\n</code></pre>\n';
};
var html = marked(md,{
  highlight: highlight,
  renderer: renderer,
});

document.body.innerHTML = html;
</script>

</body>
</html>

以上です。

24
19
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
24
19