Ruby on Rails 3.1.1 で jsMathを使う

結論。Asset Pipelineを生かした使い方がわからなかった。

私は自分が開発しているWebアプリケーションでRuby on Rails 2.3.8 で jsMathを使うに書いたとおり、jsMathというLaTeXの数式コマンドが使えるjavascriptライブラリーを使っている。Rails 3.1からjavascriptはAssetPipelineというもの経由で使えるようになったのだけど、うまくjsMathを対応させられなかった。

jsMathの設置

jsMathは配布されているjavascriptのライブラリーなので、vendor/assets/ にjsMath.zipを解凍したものをおく。

% cd vendor/assets
% unzip ~/jsMath-3.6e.zip
% mv jsMath-3.6e jsMath

あるページだけ jsMath を使いたいので、それらのページ用に app/views/layouts に専用テンプレートファイル jsmath.html.erb を用意する。 以下のように javascriptsファイルを読み込む。

  <%= javascript_include_tag "application" %>
  <%= javascript_include_tag "jsmath" %>

基本のjavascriptは app/assets/javascripts/application.js で記述。jsMathを読み込む用のものとして、app/assets/javascripts/jsmath.js を用意し、中身を以下のようにする。

//= require easy/load.js

開発環境ではこれでうまく動く。

本番環境での設定

本番環境ではprecompileが必要。ところが、vendor/assets/jsMath/easy/load.js に他のjavascriptファイルが以下のように直書きされているため、AssetPipelineのprecompileでファイル名を変えたものが読み込めない。

〜省略〜
if (jsMath.Easy.root == "") {
  jsMath.Easy.root = document.getElementsByTagName("script");
  jsMath.Easy.root = jsMath.Easy.root[jsMath.Easy.root.length-1].src
  if (jsMath.Easy.root.match(/\/easy\/[^\/]*$/)) {
    jsMath.Easy.root = jsMath.Easy.root.replace(/\/easy\/[^\/]*$/,"");
  } else {
    jsMath.Easy.root = jsMath.Easy.root.replace(/\/(jsMath\/(easy\/)?)?[^\/]*$/,"/jsMath");
  }
}
jsMath.Easy.root = jsMath.Easy.root.replace(/\/$/,""); // trim trailing "/" if any

document.write('<script src="'+jsMath.Easy.root+'/jsMath-easy-load.js"><'+'/script>');

このため、rake assets:precompile をしただけでは以下のようなエラーがでる。

Started GET "/***/assets/jsMath/plugins/autoload.js" for xxx.xxx.xxx.xxx at Fri Nov 18 20:54:50 +0900 2011

ActionController::RoutingError (No route matches [GET] "/assets/jsMath/jsMath-easy-load.js"):

そこで、rake assets:precompile した後に、vendor/assets/jsMathの中身をpublice/assets/jsMathにコピーする。

% rake assets:precompile
% cp -r vendor/assets/jsMath/* public/assets/jsMath

これで、jsMathが動く。