AngularJSでMarkdownを表示する (CoffeeSctipt編)


やりたいこと:

練習でAngularJSのアプリケーションを作っています。Yeomanでサンプルを作ると、"about" というページができるので、ここにはMarkdownで書いた記録を載せたいな...と思ったのがキッカケ。

なお、今回はCoffeeScriptを使っているため、CoffeeScriptの勉強用に置き換えてみるというのが目標です。
基本的に、下記の記事に全面的にお世話になりました...。

利用するための設定など

  • Yeomanを使ってひな形作成
  • 言語はCoffeeScriptベースで作成

参考にさせていただき、ひな形のbower.jsonにangular-marked, marked, highlightjsを追加。

bower.json
{
  "name": "myApp",
  "version": "0.0.0",
  "dependencies": {
    "angular": "^1.3.0",
    "bootstrap-sass-official": "^3.2.0",
    "angular-animate": "^1.3.0",
    "angular-cookies": "^1.3.0",
    "angular-resource": "^1.3.0",
    "angular-route": "^1.3.0",
    "angular-sanitize": "^1.3.0",
    "angular-touch": "^1.3.0",
    "angular-marked": "0.0.12",
    "marked": "~0.3.x",
    "highlightjs": "~8.4.0"
  },
  "devDependencies": {
    "angular-mocks": "^1.3.0"
  },
  "appPath": "app",
  "moduleName": "myApp"
}
  • bower install実施。
  • bower_components/ 以下に必要なものが配置されます。

アプリケーションの設定

JavaScriptもCoffeeScriptも慣れていないため、有り難いサンプルをCoffeeScriptに変換するところで一苦労...。

ここを頼りに変換しました^^;

coffeescript
'use strict'

angular
  .module 'myApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',   # routing利用
    'ngSanitize',
    'ngTouch',
    'hc.marked' # ここがMarkdown用
]
  .config ($routeProvider) ->
    # angular-route 用のルーティング設定
    $routeProvider
      .when '/',
        templateUrl: 'views/main.html'
        controller: 'MainCtrl'
      .when '/about',
        templateUrl: 'views/about.html'
        controller: 'AboutCtrl'
      .when '/contact',
        templateUrl: 'views/contact.html'
        controller: 'ContactCtrl'
      .otherwise
        # その他のところは、リンクがあってもデフォルト(main)に飛ばされる。
        redirectTo: '/'

  .config [
    # ここがMarkDown用の設定
    'markedProvider'
    (markedProvider) ->
      markedProvider.setOptions
        gfm: true
        tables: true
        highlight: (code) ->
          hljs.highlightAuto(code).value
      return
  ]

Markdown用コンポーネント指定

  • 実際はgruntを使っていますので、grunt buildでindex.htmlにも以下が挿入されます。
  • 手差しでもいいんだと思いますが...。
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->

<!-- 中略 -->    
<script src="bower_components/marked/lib/marked.js"></script>
<script src="bower_components/angular-marked/angular-marked.js"></script>
<script src="bower_components/highlightjs/highlight.pack.js"></script>
<!-- endbower -->

about.html の部分をMarkdownで書いてみる

<p>This is the about view.</p>
<!-- Yeomanのひな形はここまで -->

<!-- 以下、markedディレクティブで囲んだ部分をMarkdownで記述してみる -->
<marked>
  ### Markdown directive

  *It works!*

  *This* **is** [markdown](https://daringfireball.net/projects/markdown/) in the view.
</marked>

<!-- README.md というファイルもインクルードしてみる -->
<section marked ng-include="'README.md'"></section>

なお、Yeomanのひな形で作られているディレクトリはこの構成。
about.htmlからincludeの指定をしていますが、ng-includeで指定したファイルは、パスを指定しないとindex.htmlと同じ階層のものを読みにいくので、一応注意。

% tree
.
├── 404.html
├── README.md <- ここだと ng-include="'README.md'
├── favicon.ico
├── images
│   └── yeoman.png
├── index.html
├── robots.txt
├── scripts
│   ├── app.coffee
│   └── controllers
│       ├── about.coffee
│       ├── contact.coffee
│       └── main.coffee
├── styles
│   └── main.scss
└── views
    ├── WorkMemo.md <- ここだと ng-include="'views/README.md'
    ├── about.html
    ├── contact.html
    └── main.html

5 directories, 15 files

結果

gruntでLiveReloadしているので、すぐ確認...。
ひとまずうまく行きました。

やってみての気づき

  • 簡単な日記なら、日記部分のみMarkdownで書いて行くのがいいのかな?と思いました。(既にこういうのありそうですが...)
  • ng-includeの場合は、****.md (マークダウンのファイル側)を変更しても、gruntでは変更を認識してくれなかったので、Gruntfile.jsを調整しました...。
livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '.tmp/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= yeoman.app %>/{,*/}*.md' # ここ追加。
        ]
      }

上記の設定調整後、includeした *.md なファイルを更新しても、ライブリロードでコンパイルし直してくれるようになりました。まあ、このあたりも程度問題ってことで...。

Running "watch" task
Waiting...
>> File "Gruntfile.js" changed.
>> File "app/README.md" changed.
Completed in 0.000s at Mon Apr 20 2015 08:26:36 GMT+0900 (JST) - Waiting...

参考情報