好奇心の足跡

飽きっぽくすぐ他のことをしてしまうので、忘れないため・形にして頭に残すための備忘録。

BloggerでMarkdown書式で投稿、SyntaxHighlight対応

Blog書き始めにあたり表題のことがしたかったのだけど、 他の方の記事を寄せ集めても一筋縄でいかなかったので手順メモ。

やりたいこと

  1. Bloggerを使いたい
  2. Markdown書式で記事を書きたい
  3. codeシンタックスハイライトして表示したい
  4. 記事部分の見出しのサイズ・フォントを調整したい
  5. Mobileからもそれっぽく見せたい
  6. 記事の目次を表示したい

Markdown書式でBloggerの記事を書く

code,pre {
    font-family:consolas; /* code中で使いたいフォント */
}
  • 記事を書く時毎回markdownの場合は、下記を設定しておくと便利です
    • 設定 › 投稿とコメント > 投稿テンプレート
<textarea class="markdown" disabled="disabled">
<!-- この中にmarkdownで記事を書く -->
&lt/textarea&gt;

インラインシンタックスハイライトの設定

htmlの編集

  • テンプレート > HTMLの編集で、先ほどの手順で</head>の直前に入れた下記のソースを削除
<script language='javascript' type='text/javascript'>
 hljs.initHighlightingOnLoad();
</script>
  • 先ほどの手順で</body>の直前に入れたMarkdown用設定の後、</body>の前に下記を追加
<!-- Highlight -->
<script>
  $(document).ready(function() {
   $(&#39;code&#39;).each(function(i, block) { hljs.highlightBlock(block); });
  });
</script>
<!-- Highlight -->

cssの編集

  • Highlight用にどこかに上げた、css(手順そのままにやっていればgithub.css)に下記を上書き&追加
.hljs { /* 共通設定 */
    overflow-x: auto;
    color: #333; /*お好み*/
    background: #ccc; /*お好み*/
}
code.hljs {
    display: inline; /* インラインコード用設定 */
    margin: 3 3px; /*お好み*/
    padding: 3px 3px; /*お好み*/
}
pre code.hljs {
    display: block; /* ブロックコード用設定 */
    margin: 0; /*お好み*/
    padding: 0.5em; /*お好み*/
}

記事部分の見出しのサイズ・フォントを調整

  • 今回使用しているmarked.jsは、markdown書式の見出し記法#を下記のようにhtmlタグに変換している。
# -> <h1>
## -> <h2>
### -> <h3>
...
  • ただし、BloggerのTemplateをそのまま使用すると、h1,h2あたりまでは他の用途にも使われているため スタイルをいじると他の所まで連動して変わってしまう。
  • ということで、Markdownで書いた見出しだけスタイル設定したい!!

html templateの修正

  • テンプレート > HTMLの編集で、Styleの設定をしているあたりに下記を追加
/* Markdown Headings
----------------------------------------------- */
mh1 {
    font: $(widget.title.font);
    color: #333333;
    font-size: 20pt;
    /*中身はすべてお好み*/
}
mh2 {
    font: $(widget.title.font);
    color: #424242;
    font-size: 16pt;
    /*中身はすべてお好み*/
}
mh3 {
    font: $(widget.title.font);
    color: #595959;
    font-size: 12pt;
    /*中身はすべてお好み*/
}

自分が使いそうな分だけ設定しておけば良いのではないでしょうか。自分は4階層くらいかな。

marked.jsの修正

  • Markdown用にどこかにupした、marked.jsの下記の部分を
Renderer.prototype.heading = function(text, level, raw) {
  return '<h'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '">'
    + text
    + '</h'
    + level
    + '>\n';
};

下記のように変更 (変換後のタグ名を<h>から<mh>へ)

Renderer.prototype.heading = function(text, level, raw) {
  return '<mh'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '">'
    + text
    + '</mh'
    + level
    + '>\n';
};

Mobileの見栄え調整

  • Defaultのままだと、markdownで書いた部分が全く見えない状態に。
  • テンプレート > モバイル の下の設定アイコンを押す
  • モバイル テンプレートを選択、でカスタムに設定
  • プレビューしてみて問題なければOK

記事の目次を表示

せっかくMarkdownで書くので、目次もいい感じに出したいですよね!
そして目次クリックで街頭の場所にジャンプしたいですよね!

marked.jsの修正 (アンカー作成用)

  • ;(function() {の下に下記を定義
var anchor = 0;
  • 上記で下記のように修正済みの、marked.jsの下記の部分を
Renderer.prototype.heading = function(text, level, raw) {
  return '<mh'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '">'
    + text
    + '</mh'
    + level
    + '>\n';
};

下記のように変更 (アンカーを、indexが出てきた順に採番して追加)

Renderer.prototype.heading = function(text, level, raw) {
  anchor += 1;
  return '<mh'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '"><a name="'
    + anchor
    + '">'
    + text
    + '</a></mh'
    + level
    + '>\n';
};

ガジェットの追加

  • レイアウト > 記事の目次を表示したい場所のガジェットを追加をクリック
  • HTML/JavaScript追加を選択
  • 出てきた窓のコンテンツに下記を貼付け
<script type="text/javascript">
<!--
indexes = generateIndex();
anchor = 1;
indexes.forEach(function(index, i) {
    title = index.replace(/^(#+\s+)/, "");
    indent = index.match(/^#+\s+/)[0];
    document.write('<div style="margin-left:' + (indent.length-2).toString() + 'em">* <a href="#' + anchor + '">' + title + '</a></div>');
    anchor += 1;
});
function generateIndex() {
    var textarea = document.getElementsByTagName("textarea");
    text = textarea[0].value.toString().replace(/```[\s\S]*?```|`.*`/mg, '');
    indexes = text.match( /^(#+)\s(.+)/mg);
    return indexes;
}
//-->
</script>

個別記事のみ目次を表示するよう設定

  • テンプレート > ウィジェットへ移動 > HTML(1,2,3...1沢山あるときは先ほど追加したと思われるやつ)
  • 下記のようなスクリプト部分に飛ばされると思うので、<!-- これ -->の部分を挿入
<b:widget id='HTML2' locked='false' title='Index' type='HTML'>
  <b:includable id='main'>
    <b:if cond='data:blog.pageType == &quot;item&quot;'><!-- これ -->
      <!-- only display title if it's non-empty -->
      <b:if cond='data:title != &quot;&quot;'>
        <h2 class='title'><data:title/></h2>
      </b:if>
      <div class='widget-content'>
        <data:content/>
      </div>
      <b:include name='quickedit'/>
    </b:if><!-- これ -->
  </b:includable>
</b:widget>