結果として出来たもののデモはこちらです。この記事自体の Markdown を、JavaScript で描写しています
⇒ http://hkusu.github.io/angularjs-markdown-demo/dist
(改行がうまくいっていない気がしますが、細かいことは気にしない..)
今回の方針
- Markdown は GitHub 形式とします
- コードハイライトに対応します
- 絵文字に対応します
- AngularJS でやります
- AngularJS でなくても marked や Highlight.js を使えばできると思います
- 動作確認として Qiita の新着投稿を表示します
-
Qiita API v1 を利用します
-
v2
を利用ない理由としては、v2
だとクロスオリジン制約にひっかかる為
-
-
Qiita API v1 を利用します
前提環境
手元の環境は次のとおりです。
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
今回はなんでもいいので適当にオプションを選択する。
雛形ができたら $ gulp serve
で動作確認。
② angular-marked と Highlight.js の導入
angular-marked と Highlight.js を導入します。
ちなみに Highlight.js は下記が本家?ぽいのですが上手く動かなかった。
https://github.com/isagalaev/highlight.js
導入手順は基本的に、上記の GitHub の README に記載されているままです。
$ bower install angular-marked --save
$ bower install highlightjs --save
$ gulp wiredep
とするか、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
を丸ごと追記)
'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
を修正します。
〜
<!-- 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'
を追記)
'use strict';
angular.module('angularjsMarkdownDemo', ['ngSanitize', 'ui.router', 'hc.marked', 'emoji'])
.config(function ($stateProvider, $urlRouterProvider) {
〜
以上で絵文字を表示する準備までOK。
Markdown を表示してみる
Qiita API v1 を利用して、適当な記事を取得します。記事の内容は、レスポンスされた JSON の raw_body
に入ってます。
'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 で表示します。
<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
を利用して値が存在したら表示、としています。)
また画像が大きい場合に横にはみ出したり、絵文字の縦位置が中央でなかったりするので、次のように調整しました。
img {
max-width: 100%;
height: auto;
}
i.emoji {
vertical-align: middle;
}
デプロイ用にbuildする場合は $ gulp build
とすると dist
ディレクトリにデプロイ用のファイルが展開されるのですが、絵文字用の画像(emoji.png
)は bower_components/angular-emoji-filter/dist/emoji.ping
を dist/style/emoji.png
へ手動でコピーしました。(もしくは Gulp のタスクを修正すれば良いかと思います。)
デモはこちらです。
⇒ http://hkusu.github.io/angularjs-markdown-demo/dist
おわりに
ソースコードはこちらに置いておきます。
⇒ https://github.com/hkusu/angularjs-markdown-demo