Nuxt.js製のWebサービスにmarked+highlightjsでMarkdownで書いた読書メモを表示できるようにしてみた

先日、開発中の[積読用の書籍管理アプリ](https://tsundoku.site)の新機能として、
Markdownで書ける読書メモを追加したので、その時の備忘録。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">✅読書中のメモが残せる読書メモ機能✨<br>読書メモを残せる機能を追加しました‼️<br>マークダウンで書けて、全メモをクリップボードにコピーできちゃいます😊<br><br>はてなブログなどマークダウンが使えるなら、コピペで記事も書くことも😍<br><br>(続く <a href="https://t.co/K3pjr4noVo">pic.twitter.com/K3pjr4noVo</a></p>&mdash; めもらば@公式 (@MemoryLoverz) <a href="https://twitter.com/MemoryLoverz/status/1168227417950806016?ref_src=twsrc%5Etfw">September 1, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 全体の流れ

やりかたとしては、こんな感じ
1. Markdownの文字列を[marked](https://github.com/markedjs/marked)を使ってHTML化
2. `<pre>`の部分は、markedで[highlightjs](https://github.com/highlightjs/highlight.js/)を使うように設定
3. Markdown用のCSSを追加して見た目を調整

### VueのSFCで書くとこんな感じ

```vuejs
<template>
  <div class="marked" v-html="markedHtml"></div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from "nuxt-property-decorator";
import marked from "marked";
import hljs from "highlightjs";

@Component({ components: {} })
export default class NoteItem extends Vue {
  // マークダウンで書かれたテキスト
  @Prop({ required: true }) memo!: string;

  created() {
    // markedでhighlightjsを利用するように設定
    marked.setOptions({
      langPrefix: "",
      highlight: function(code, lang) {
        return hljs.highlightAuto(code, [lang]).value;
      }
    });
  }
  
  private get markedHtml() {
    // markedを実行した結果を返す
    return marked(this.memo);
  }
}
</script>
```

ポイントとしてはこんな感じ。

1. `created()`内でmarkedの設定。ハイライト処理にhighlightjsを使うように。
2. computedの`markedHtml()`内でmarkedを実行
3. `<div v-html="markedHtml">`でHTMLを表示

### マークダウン用のCSSを追加する

上記のままだと、Webサイトに適用しているCSSがそのまま適用されてしまうので、
こんなになってしまい、あまりよい感じではない...

<img width="500" alt="スクリーンショット 2019-09-03 23.08.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/7489db5b-e4cb-ae85-0db5-621a247e1287.png">

なので、`.marked`というクラスは以下の要素にマークダウン用のCSSを設定して調整する。

0から作ると大変なので、[@skkzshさんのQiita記事](https://qiita.com/skkzsh/items/99e30bbbfe69f379b583)に書いてある、
[simonlc/Markdown-CSS](https://github.com/simonlc/Markdown-CSS)や[kottkrig/Markdown-CSS](https://github.com/kottkrig/Markdown-CSS)を参考に設定していく。

できたのがこんな感じ。
あとはサイトのデザインと合わせて、少しずつ調整〜

```scss
// ****************************
// * Marked
// ****************************
.marked {
  p {
    margin: 1em 0;
  }

  img {
    max-width: 100%;
  }

  h1, h2, h3, h4, h5, h6 {
    font-weight: normal;
    line-height: 1em;
  }
  h4, h5, h6 {
    font-weight: bold;
  }
  h1 {
    font-size: 2.5em;
  }
  h2 {
    font-size: 2em;
  }
  h3 {
    font-size: 1.5em;
  }
  h4 {
    font-size: 1.2em;
  }
  h5 {
    font-size: 1em;
  }
  h6 {
    font-size: 0.9em;
  }

  ol {
    margin: 1em 0;
    padding: 0 0 0 2em;
  }

  ul {
    margin: 1em 0;
    padding: 0 0 0 2em;
    list-style: disc;
  }

  dd {
    margin: 0 0 0 2em;
  }

  table {
    margin: 10px 0 15px 0;
    border-collapse: collapse;
  }
  td, th {
    border: 2px solid #ccb8a3;
    padding: 3px 10px;
  }
  th {
    padding: 5px 10px;
  }

  blockquote {
    padding-left: 1em;
    margin: 0;
    color: #666666;
    border-left: 0.3em #f6f0e5 solid;
  }
}
```

このCSSを適用するとこんな感じに!!
いい感じになった(*´ω｀*)

<img width="500" alt="スクリーンショット 2019-09-03 23.14.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8a3f19a2-3524-f864-4504-ff174683c8cf.png">


いろいろ便利なライブラリがあるのでサクッとできてステキ♪

## こんなのつくってます！！

上記の読書メモ機能を追加した、積読用の読書管理アプリ「積読ハウマッチ」！
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="25%"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで♪



# 参考にしたサイト
- [大量のテキストを食っても速い Markdown Editor 作った - mizchi's blog](https://mizchi.hatenablog.com/entry/2018/10/23/221446)
- [React＋marked＋highlight.jsでマークダウンエディタをつくる - Qiita](https://qiita.com/bmf_san/items/fe2b4b4591dd17ee7103)
- [コードのハイライト表示 JS ライブラリ ３種 - Qiita](https://qiita.com/tadnakam/items/1323d03743fc0101aa50)
- [JavaScript - Markdownパーサーのshowdown.js、markdown-js、markedを簡単比較 - ぼっち勉強会](http://kannokanno.hatenablog.com/entry/2013/06/19/132042)
- [Markdownでスタイルシート - Qiita](https://qiita.com/skkzsh/items/99e30bbbfe69f379b583)