LoginSignup
17
17

More than 5 years have passed since last update.

JavaScript で Markdown 文書を表示してみた

Last updated at Posted at 2015-01-15

結果として出来たもののデモはこちらです。この記事自体の Markdown を、JavaScript で描写しています :smile:
http://hkusu.github.io/angularjs-markdown-demo/dist
(改行がうまくいっていない気がしますが、細かいことは気にしない..)

今回の方針

  • Markdown は GitHub 形式とします
    • コードハイライトに対応します
    • 絵文字に対応します
  • AngularJS でやります
  • 動作確認として Qiita の新着投稿を表示します
    • Qiita API v1 を利用します
      • v2 を利用ない理由としては、v2 だとクロスオリジン制約にひっかかる為

前提環境

手元の環境は次のとおりです。

OS:Mac OS X 10.9.5
gulp:3.8.10
YEOMAN(yo):1.3.2
generator-gulp-angular:0.7.3

また下記の手順で結果的にインストールされたもののバージョンは次のとおり。

AngularJS:1.3.9
anguar-marked:0.0.12
maked:0.3.2
highlightjs:8.4.0
angular-emoji-filter:0.0.2

手順

① AngularJS プロジェクトの雛形を生成

適当なディレクトリを作成してジェネレータを起動します。

$ mkir angularjs-markdown-demo
$ cd angularjs-markdown-demo
$ yo gulp-angular

今回はなんでもいいので適当にオプションを選択する。

スクリーンショット 2015-01-15 15.19.34.png

雛形ができたら $ gulp serve で動作確認。

スクリーンショット 2015-01-15 15.24.35.png

② angular-marked と Highlight.js の導入

angular-markedHighlight.js を導入します。

ちなみに Highlight.js は下記が本家?ぽいのですが上手く動かなかった。
https://github.com/isagalaev/highlight.js

導入手順は基本的に、上記の GitHub の README に記載されているままです。

$ bower install angular-marked --save
$ bower install highlightjs --save

$ gulp wiredep とするか、index.html を修正します。

src/index.html


<!-- build:css({.tmp,src}) styles/vendor.css -->
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
<!-- bower:css -->
+<link rel="stylesheet" href="../bower_components/highlightjs/styles/default.css" />
<!-- endbower -->
<!-- endbuild -->

〜

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="../bower_components/jquery/dist/jquery.js"></script>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="../bower_components/angular-ui-router/release/angular-ui-router.js"></script>
+<script src="../bower_components/angular-marked/angular-marked.js"></script>
+<script src="../bower_components/highlightjs/highlight.pack.js"></script>
<!-- endbower -->
+<script src="../bower_components/marked/lib/marked.js"></script>
<!-- endbuild -->

私の場合は marked.js$ gulp wiredep で追記されなかったので、手で追記した。

AngularJS アプリケーションに組み込みます。
'hc.marked' を追記したのと、2つめの .config を丸ごと追記)

src/app/index.js
'use strict';

angular.module('angularjsMarkdownDemo', ['ngSanitize', 'ui.router', 'hc.marked'])
  .config(function ($stateProvider, $urlRouterProvider) {
    $stateProvider
      .state('home', {
        url: '/',
        templateUrl: 'app/main/main.html',
        controller: 'MainCtrl'
      });

    $urlRouterProvider.otherwise('/');
  })
  .config(['markedProvider', function(markedProvider) {
    markedProvider.setOptions({
      gfm: true,
      tables: true,
      highlight: function (code) {
        return hljs.highlightAuto(code).value;
      }
    });
  }])
;

これで Markdown をコードハイライト付きで表示する準備はOKです。

③ AngularJS Emoji Filter の導入

さらに絵文字(:smale:など)を表示するために、AngularJS Emoji Filter を導入します。

$ bower install angular-emoji-filter --save

$ gulp wiredep するか手動で index.html を修正します。

src/index.html


<!-- build:css({.tmp,src}) styles/vendor.css -->
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
<!-- bower:css -->
<link rel="stylesheet" href="../bower_components/highlightjs/styles/default.css" />
<!-- endbower -->
+<link rel="stylesheet" href="../bower_components/angular-emoji-filter/dist/emoji.min.css" />
<!-- endbuild -->

〜

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="../bower_components/jquery/dist/jquery.js"></script>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="../bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="../bower_components/angular-marked/angular-marked.js"></script>
<script src="../bower_components/highlightjs/highlight.pack.js"></script>
+<script src="../bower_components/angular-emoji-filter/dist/emoji.min.js"></script>
<!-- endbower -->
<script src="../bower_components/marked/lib/marked.js"></script>
<!-- endbuild -->

私の場合は emoji.min.css$ gulp wiredep で追記されなかったので、手で追記した。

AngularJS アプリケーションに組み込みます。('emoji' を追記)

src/app/index.js
'use strict';

angular.module('angularjsMarkdownDemo', ['ngSanitize', 'ui.router', 'hc.marked', 'emoji'])
  .config(function ($stateProvider, $urlRouterProvider) {

以上で絵文字を表示する準備までOK。

Markdown を表示してみる

Qiita API v1 を利用して、適当な記事を取得します。記事の内容は、レスポンスされた JSON の raw_body に入ってます。

src/app/main/main.controller.js
'use strict';

angular.module('angularjsMarkdownDemo')
  .controller('MainCtrl', function ($scope, $http) {

    $scope.raw_body = "";

    $http.get('https://qiita.com/api/v1/items/f77211edf0f4ab7561ca').success(function(item) {
      $scope.raw_body = item.raw_body;
    });

  });

取得した記事の内容を Markdown で表示します。

src/app/main/main.html
<div class="container">
  <ng-if raw_body != "">
    <div marked="raw_body|emoji"></div>
  </ng-if>
</div>

angular-marked の使い方は README に書いてありますが、今回のポイントとしては <div marked="$scopeの変数名|emoji"></div> で動的に値を差し込んでいるところです。
(ただこの使い方だと、値の差し込み前にディレクティブが作動するとエラーになるので、ng-ifを利用して値が存在したら表示、としています。)

また画像が大きい場合に横にはみ出したり、絵文字の縦位置が中央でなかったりするので、次のように調整しました。

src/app/index.css
img {
  max-width: 100%;
  height: auto;
}

i.emoji {
  vertical-align: middle;
}

デプロイ用にbuildする場合は $ gulp build とすると dist ディレクトリにデプロイ用のファイルが展開されるのですが、絵文字用の画像(emoji.png)は bower_components/angular-emoji-filter/dist/emoji.pingdist/style/emoji.png へ手動でコピーしました。(もしくは Gulp のタスクを修正すれば良いかと思います。)

デモはこちらです。
http://hkusu.github.io/angularjs-markdown-demo/dist

おわりに

ソースコードはこちらに置いておきます。
https://github.com/hkusu/angularjs-markdown-demo

17
17
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
17
17