マークダウンエディターを5分で作る【Marked.js & highlight.js】

現在Laravelでマークダウンエディターを使用したブログを開発中ですが、非同期マークダウンエディターの作り方が想像より簡単だったので、シェア。

結論としては`Marked.js`を使用します。

##完成品

<b>5分Ver</b>

![スクリーンショット 2019-12-07 13.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/ac554ee6-ecfa-04e1-6936-975f2478ac53.png)

<b>10分ver（highlight.js導入）</b>

![スクリーンショット 2019-12-07 15.03.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/bb3f88ef-6179-bc3b-30db-076cd936ff61.png)

##サンプル

https://silly-albattani-c41e1e.netlify.com/

*pcのみ対応しています。*

##雛形

まずはMarked.jsを読み込みます。

CDNの場合、

```html
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>

```

npm使用の場合は

```
npm i marked
```

で、その後

```js

import marked from 'marked';
```

になります。

今回は他にもbootstrap4やjQueryを読み込んでます。
jQueryは必須です。

```html
<div class="row">
		<div class="col-5 m-1">
<!-- ここに入力-->
			<textarea name="article" id="markdown_editor_textarea" cols="30" rows="30" class="form-control"></textarea>
		</div>
		<div class="col-6 m-1 border">
<!-- ここに出力される -->
			<div id="markdown_preview"></div>
		</div>
	</div>
```

```js
// マークダウンをプレビュー画面に表示する
$(function () {

  $('#markdown_editor_textarea').keyup(function () {
    var html = marked($(this).val());
    $('#markdown_preview').html(html);
  });
});
```

textareaのidの`markdown_editor_textarea`のマークダウンを検知し、markdown_previewにhtmlとして返し、表示させています。

全てはmarked関数がよしなにやってくれているんですね。

これだけで完成です。

![スクリーンショット 2019-12-07 13.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/058baa8b-99ce-fd5b-6e42-414a548be1d6.png)


##オシャンにする

ただ地味なので、highlight.jsとcssを当てて行きます。

```css
h1 {
  background: #dfefff;
  box-shadow: 0px 0px 0px 5px #dfefff;
  border: dashed 1px #96c2fe;
  padding: 0.2em 0.5em;
  color: #454545;
  margin-bottom: 20px;
}

h2 {
  background: linear-gradient(transparent 70%, #a7d6ff 70%);
  margin-bottom: 20px;
}

h3 {
  color: #010079;
  text-shadow: 0 0 5px white;
  padding: 0.3em 0.5em;
  background: -webkit-repeating-linear-gradient(-45deg, #cce7ff, #cce7ff 3px, #e9f4ff 3px, #e9f4ff 7px);
  background: repeating-linear-gradient(-45deg, #cce7ff, #cce7ff 3px, #e9f4ff 3px, #e9f4ff 7px);
  margin-bottom: 20px;
}

pre {
  padding: 20px;
}
```

見出しにcssをつけただけなので、ここは対して重要じゃないです。

次にコードハイライターのhighlight.jsを導入します。

##highlight.jsの導入

今回はCDNで読み込みました。

```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/solarized-dark.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.16.2/build/highlight.min.js"></script>
```

読み込むcssは[highlight.jsの公式demo](https://highlightjs.org/static/demo/)から選んでください。

今回holarized-dark。

npmの場合は

```
npm install highlight
```

```js
import hljs from 'highlight.js';
```


読み込み後、

```js
// マークダウンをプレビュー画面に表示する
$(function () {
  marked.setOptions({
    // code要素にdefaultで付くlangage-を削除
    langPrefix: '',
    // highlightjsを使用したハイライト処理を追加
    highlight: function (code, lang) {
      return hljs.highlightAuto(code, [lang]).value
    }
  });
  $('#markdown_editor_textarea').keyup(function () {
    var html = marked($(this).val());
    $('#markdown_preview').html(html);
  });
});
```

marked.setOptionsで読み込み時に処理を行わせます。

これでコードがハイライトされるようになりました。

![スクリーンショット 2019-12-07 15.19.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/f1d20803-00ab-305d-d8ce-d6b613c6a9e4.png)

##実物公開

スマホ未対応です。

色々いじってみてください。

https://silly-albattani-c41e1e.netlify.com/