HikiDocの改造版をgithubで公開しました。HikiやtDiaryでhikidoc.rbを差し替えるだけで機能すると言う点ではかわりませんが、今回は開き直ってオリジナル記法との互換性を捨てているので注意が必要です。
目玉はブロック要素の記述の強化でプラグインを使ったやっつけ仕事とは違い、
といったことがちゃんとできます。
その他の主な変更は以下のとおりです。
詳しくはTextFormattingRules.jaまたはテストを参照してください。 ----[green]
----[green]
以下に[[TextFormattingRules.ja|http://github.com/hs/hikidoc/raw/master/TextFormattingRules.ja]]のコピペを貼っておきます。tDiaryはhikidocに渡す前に"!"1個の見出しだけなんか前処理をしていてうまく変換できないのでその部分だけちょっと誤魔化してます。Hikiの場合は[[こちら|http://www.on-sky.net/~hs/misc/?TextFormattingRules.ja]]
[border center]
記述例 | 出力例 |
---|---|
((( | ((( |
((( | ((( |
((( | ((( |
単に 折り返した行の表示は ブラウザによりこのように整形されます。
))) 単に 折り返した行の表示は ブラウザによりこのように整形されます。 )))
段落内で改行したい場合は、 ←ここにスペースを入れます。
))) 段落内で改行したい場合は、
←ここにスペースを入れます。
)))
空行を入れます。 すると、段落が変わります。
))) 空行を入れます。
すると、段落が変わります。 )))
[border center]
((( | ((( |
((( | ((( |
[bgOrange,"マウスカーソルをあわせるとタイトルが表示されます"] 段落にclass属性を付けてCSSで見栄えを変えられます。
))) [bgOrange,"マウスカーソルをあわせるとタイトルが表示されます"] 段落にclass属性を付けてCSSで見栄えを変えられます。 )))
!![foo,"マウスカーソルをあわせるとタイトルが表示されます"]見出し
)))
)))
[border center]
記述例 | 出力例 |
---|---|
((( | ((( |
!! 見出し2 !!! 見出し3 !!!! 見出し4 !!!!! 見出し5
)))
)))
[border center]
記述例 | 出力例 |
---|---|
((( | ((( |
((( | ((( |
((( | ((( |
((( | ((( |
[[http://www.hikiwiki.org/en/]]
))) http://www.hikiwiki.org/en/ )))
[[Hiki|http://www.hikiwiki.org/en/]]
))) Hiki )))
[[Clover|http://jp.rubyist.net/theme/clover/clover_h1.png]]
))) Clover )))
http://www.hikiwiki.org/en/
))) http://www.hikiwiki.org/en/ )))
という条件が2回以上繰り返される単語はWikiNameになり自動的にリンクがはられます。
[border center]
記述例 | 出力例 | コメント |
((( | ((( | ((( |
WikiName HogeRule1 NOTWIKINAME WikiNAME fooWikiName
)))
WikiName HogeRule1 NOTWIKINAME WikiNAME fooWikiName
)))
WikiNameになる WikiNameになる 全て大文字なのでWikiNameではない NAMEが全て大文字なのでWikiNameではない 先頭に全て小文字の英字fooがあるためWikiNameではない
)))
を参考にInterWikiもサポートしています。サーバの追加は InterWikiNameというページを編集します。
[border center]
記述例 | 出力例 |
((( | ((( |
[[Hiki:逆引きRuby]] [[ruby-list:1]] [[GoogleJ:ruby wiki]]
)))
[[Hiki:逆引きRuby]] [[ruby-list:1]] [[GoogleJ:ruby wiki]]
))) InterWikiはouter aliasと呼ばれる簡単に外部とリンクする機能にも対応しています。outer aliasを利用するにはInterWikiNameへaliasキーワードを付けてサーバを追加します。
本文中ではaliasに設定した単語を2つのカギカッコで囲むとリンクとなります。
[border center]
記述例 | 出力例 |
((( | ((( |
;InterWikiName
;本文
)))
[[Ruby]]
)))
[border center]
記述例 | 表示例 |
---|---|
((( | ((( |
((( | ((( |
*レベル1 **レベル2 ***レベル3 ****レベル4 *****レベル5 ******6個目以降は本文になる * *スペースを入れれば先頭に「*」を記述可能
)))
)))
#レベル1-1 ##レベル2-1 ##レベル2-2 #レベル1-2
)))
)))
[border center]
記述例 | 表示例 |
---|---|
((( | ((( |
;用語;:解説 改行 ---- ;用語だけ ---- :解説だけ
))) ;用語;:解説
改行
;用語だけ
)))
表(テーブル)は「||」で始めます。 セルの項目の頭に「!」をつけることにより見出しセルになります。 行の連結には「^」を列の連結には「>」を、連結したい数だけセルの項目頭につけてください。
[border center]
記述例 | ((( |
---|---|
表示例 | ((( |
||!行見出し\列見出し||!列-A||!列-B||!列-C||!>列-D-E(横連結) ||!行-1||A1||B1||^C1-C2(縦連結)||D1||E1 ||!行-2||A2||B2||^>D2-E2-D3-E3(縦横連結) ||!行-3||>>A3-C3(横3連結)
)))
行見出し\列見出し | 列-A | 列-B | 列-C | 列-D-E(横連結) | |
---|---|---|---|---|---|
行-1 | A1 | B1 | C1-C2(縦連結) | D1 | E1 |
行-2 | A2 | B2 | D2-E2-D3-E3(縦横連結) | ||
行-3 | A3-C3(横3連結) |
)))
行内の任意の場所に記述できる要素です。
波括弧「{」1つと記号の組み合わせで、文字飾りを表示することができます。
[border center]
記号 | 記述例 | 表示例 | タグ | |
---|---|---|---|---|
色付き | ~色: | {{~red:}色付き{~}} | {~red:色付き~} | <font color="指定色"> |
強調 | ' | {{'}強調{} | {'強調'} | <em> |
強調 | 2つの ' | {{}強調{'{!'}!}''} | {強調} | <strong> |
下線 | _ | {{_}下線{_}} | {_下線_} | <u> |
斜体 | / | {{/}斜体{/}} | {/斜体/} | <i> |
取消線 | = | {{=}取消線{=}} | {=取消線=} | <del> |
拡大文字 | + | 拡大{{+}大{+}}大文字 | 拡大{+大+}大文字 | <big> |
縮小文字 | - | 縮小{{-}小{-}}小文字 | 縮小{-小-}小文字 | <small> |
上付き | 2つの^ | 上{{^^}付き{^^}} | 上{^^付き^^} | <sup> |
下付き | 2つの_ | 下{{__}付き{__}} | 下{__付き__} | <sub> |
[border center]
記述例 | 表示例 |
---|---|
{!{'強調の中で{=取消線を指定すると=}'}効果が重なります!} | {'強調の中で{=取消線を指定すると=}'}効果が重なります |
{!1{+2{+3{+4{+5+}4+}3+}2+}1!} | 1{+2{+3{+4{+5+}4+}3+}2+}1 |
{!1{-2{-3{-4{-5-}4-}3-}2-}1!} | 1{-2{-3{-4{-5-}4-}3-}2-}1 |
{!その他の{'文字飾りの{'入れ子'}はできません'}!} | その他の{'文字飾りの{'入れ子'}はできません'} |
文字列を「{{$}」と「{$}}」で囲むとmimeTeXによって整形された数式が表示されます。
[border center]
記述例 | 表示例 |
---|---|
数式を {!{$f(x) = \frac{1}{3}$}!} インライン表示 | 数式を {$f(x) = \frac{1}{3}$}インライン表示 |
その他、以下のインライン要素が記述できます。
[border center]
記号 | 記述例 | 表示例 | 備考 | |
---|---|---|---|---|
引用元 | {@ | {!{@参考文献@}!} | {@参考文献@} | <cite>タグ |
無変換 | {! | {!{!{@!}参考文献{!@}!}!} | {!{@参考文献@}!} | 間の文字列を変換せずに表示 |
名前付き文字列 | {!{"!} | {!{"[foo]テキスト"}!} | {"[foo]テキスト"} | class/title属性付きの<span>タグで囲まれます |
「<<<」という行と「>>>」という行で挟まれた部分はブロック要素になります。
[border center]
((( | ((( |
---|---|
((( | ((( |
記述例 ))) 表示例(class/title属性はソースで確認できます) )))
<<<b[foo] 引用 <<<b["タイトル"] さらに引用 >>> >>>
)))
引用 <<<b["タイトル"] さらに引用
>>> )))
[border center]
((( | ((( |
---|---|
((( | ((( |
記述例 ))) 表示例 )))
<<<c 中央寄せ <<<b 入れ子で引用 <<<l 引用内で左寄せに戻す >>> >>> >>> <<<r 右寄せ >>>
)))
中央寄せ <<<b 入れ子で引用 <<<l 引用内で左寄せに戻す
>>> >>>
右寄せ
)))
[border center]
((( | ((( |
---|---|
((( | ((( |
((( | ((( |
記述例 ))) 表示例 )))
<<<p 整形済みテキスト {'強調'} {=取り消し先=} >>>
)))
整形済みテキスト {'強調'} {=取り消し先=}
)))
<<<pa 整形済みテキスト {'強調'} {=取り消し先=} >>>
)))
整形済みテキスト {'強調'} {=取り消し先=}
)))
[border center]
記述例 | 表示例 |
---|---|
((( | ((( |
<<<m f(x) = \frac{1}{3} >>>
)))
f(x) = \frac{1}{3}
)))
[border center]
((( | ((( |
---|---|
((( | ((( |
記述例 ))) 表示例 )))
<<<a 無変換 {'強調'} {=取り消し先=} >>>
)))
無変換 {'強調'} {=取り消し先=}
)))
[border center]
((( | ((( |
---|---|
((( | ((( |
((( | ((( |
記述例 ))) 表示例 )))
<<<div[foo] <div class="foo">と</div>タグで囲まれます。 >>>
)))
<div class="foo">と</div>タグで囲まれます。
)))
<<<[,"bar"] <div title="bar">と</div>タグで囲まれます。 >>>
)))
<div title="bar">と</div>タグで囲まれます。
)))
箇条書き、用語解説の解説、および表の中に「(((」と書くと、次の行から「)))」という行までのブロックが要素内に表示されます。
箇条書きや解説では「(((」を記述した要素の直後にブロックを続けます。
[border center]
記述例 | 表示例 |
---|---|
((( | ((( |
#((( 要素1 <<<c 中央寄せ >>> ))) #((( 要素2(改行→) パラグラフ <<<b 引用 >>> )))
)))
要素1
中央寄せ
)))
要素2(改行→)
パラグラフ
引用
))) )))
表を記述する場合、まずは表全体の構造を記述し、中にブロックを表示したい要素を「(((」とします。その表の後ろに左上から順にブロックを必要な数だけ繰り返し記述し、各ブロックを「)))」で閉じます。
[border center]
記述例 | 表示例 |
---|---|
((( | ((( |
// まずは表を書きます。 ||(((||1行2列 ||2行1列||((( //表はここまで //続けてブロック要素を順に書きます。 1行1列 <<<r 右寄せ >>> ))) 2行2列 パラグラフ(改行→) 2行目 *リスト1 )))
)))
((( | 1行2列 |
2行1列 | ((( |
1行1列
右寄せ
))) 2行2列
パラグラフ(改行→)
2行目
))) )))
「{」2つと「}」2つで囲むとプラグインを呼び出すことができます。 パラメータを複数行に分けて書くことも可能です。 プラグインのみを単独行に書いた場合はブロックプラグインになり、前後に<p>と</p>が付かなくなります。
[border center]
記述例 |
---|
((( |
((( |
{{recent(3)}}
)))
{{pre(' ... )}}
)))
Rubyの軽量フレームワークSinatraでI18nライブラリを使う方法のメモです。I18nについては別の実装としてR18nライブラリというのもあるようです。
まずはライブラリのデフォルトに従い、最小のコードで最低限の機能を実現することを目標にします。
# gem install i18n # gem install sinatra-i18n # gem install rack-contrib
;i18n
;sinatra-i18n
;rack-contrib
# mkdir i18n-sample # cd i18n-sample
# mkdir -p config/locales
config/locales/の下にen.ymlというファイルを作る。ファイルはYAMLフォーマットでロケールをトップレベルのキーとしたハッシュの形で記述します。
en: message: hello: hello! ja: message: hello: こんにちは!
このサンプルでは、message.hello というラベルに、:en ロケールでは"hello!"、:ja ロケールでは"こんにちは!"という文字列が対応するようになります。
i18n-sampleディレクトリにstart.rbを作る。
require 'rubygems' require 'sinatra' require 'sinatra/i18n' require 'rack/contrib' Sinatra.register Sinatra::I18n use Rack::Locale get '/?' do t('message.hello') end
# ruby start.rb == Sinatra/1.0 has taken the stage on 4567 for development with backup from Mongrel
この状態でブラウザから http://sample-host:4567/ にアクセスすると、ブラウザの言語設定にしたがって"Hello!"または"こんにちは!"と表示されます。
というわけで、非常に簡単にI18n対応できたのですが、次のような問題もあります。
ということで、次のエントリではこの問題に対処します。
SinatraとI18n、Rack::Localeライブラリを組み合わせると簡単にI18n対応することができますが、以下のような問題がありました。
このエントリではこれらの問題の解決を図ります。
libというディレクトリを作り、その下に変更するライブラリをコピーします。
# mkdir -p lib/sinatra # mkdir -p lib/rack/contrib # cp /GEM/LIBRARY/ROOT/sinatra-i18n-0.1.0/lib/sinatra/i18n.rb lib/sinatra/ # cp /GEM/LIBRARY/ROOT/rack-contrib-1.0.1/lib/rack/contrib/locale.rb lib/rack/contrib
このようにディレクトリ階層を再現することにより、元のソースの変更を最小限で済ませることができ、またオリジナルのライブラリで問題が解決した際にはコピーしたファイルを消すだけで元に戻せるようにできます。
コピーしたライブラリファイルを以下のように修正します。 ;lib/sinatra/i18n.rb
Sinatra の :locales 設定に複数のファイルを指定できるようにします。
% diff -U0 i18n.rb.old i18n.rb --- i18n.rb.old 2010-09-26 18:40:05.000000000 +0900 +++ i18n.rb 2010-09-26 18:40:26.000000000 +0900 @@ -18 +18 @@ - ::I18n.backend.load_translations(app.locales) + ::I18n.backend.load_translations(*app.locales)
))) ;lib/rack/contrib/locale.rb
ブラウザのACCEPT_LANGUAGEを優先順に評価し、アプリ側で有効なロケールが見つかったら設定します。見つからなかった場合はI18n.default_localeに設定します。
% diff -u locale.rb.old locale.rb --- locale.rb.old 2010-09-26 18:54:43.000000000 +0900 +++ locale.rb 2010-09-26 19:40:04.000000000 +0900 @@ -12,14 +12,14 @@ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 if lang = env["HTTP_ACCEPT_LANGUAGE"] - lang = lang.split(",").map { |l| + lang.split(",").each { |l| l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/ - l.split(';q=') - }.first - locale = lang.first.split("-").first - else - locale = I18n.default_locale + locale = l.split(';q=').first.split("-").first.to_sym + break if I18n.available_locales.include?(locale) + locale = nil + } end + locale ||= I18n.default_locale locale = env['rack.locale'] = I18n.locale = locale.to_s status, headers, body = @app.call(env)
)))
サンプルコードを次のように修正します。
$LOAD_PATH.unshift './lib' require 'rubygems' require 'sinatra' require 'sinatra/i18n' require 'rack/contrib' set :locales, Dir[ "config/locales/*.yml" ] I18n.default_locale = :ja Sinatra.register Sinatra::I18n use Rack::Locale get '/?' do t('message.hello') end
;1行目
;7行目
;8行目
config/locales/ の下のen.ymlをja.ymlにコピーし、ロケールの設定を分けます。
;en.yml
en: message: hello: hello!
))) ;ja.yml
ja: message: hello: こんにちは!
)))
# ruby start.rb == Sinatra/1.0 has taken the stage on 4567 for development with backup from Mongrel
SinatraでのCSRF対策にはRack::Csrfが使えますが、普通に
use Rack::Csrf, :raise => true
とか書いただけでは、errorハンドラで例外を捕捉・処理できません。production環境ではCSRFチェックに引っかかると403応答+真っ白な画面になるのですが、false negativeの可能性が0ではないので、何らかの処理はしておきたいところです。
というわけで、試行錯誤の結果行き着いたのが以下のようなコード。もっと良い方法があったらコメントください。
require 'rubygems' require 'sinatra' require 'rack/csrf' require 'haml' use Rack::Session::Pool use Rack::Csrf, :raise => true, :skip => ['POST:.*', 'PUT:.*', 'DELETE:.*'] set :run, true set :root, File.dirname(__FILE__) set :show_exceptions, false def check_csrf raise Rack::Csrf::InvalidCsrfToken unless params[Rack::Csrf.csrf_field] == session['csrf.token'] end before do check_csrf if ['POST', 'PUT', 'DELETE'].include?(env['REQUEST_METHOD']) end error Rack::Csrf::InvalidCsrfToken do "CSRF exception!!" end ########## get '/?' do haml ROOT_HAML end get '/form' do haml FORM_HAML end get '/form2' do haml FORM_HAML_WITHOUT_CSRF_TAG end post '/?' do "ok" end ########## ROOT_HAML = <<EOHAML %a{:href => "/form"} form %br %a{:href => "/form2"} form2 EOHAML FORM_HAML = <<EOHAML %h1 フォーム %form{:method => "POST", :action => '/'} = Rack::Csrf.csrf_tag(env) %p %input{:type => "submit"} EOHAML FORM_HAML_WITHOUT_CSRF_TAG = <<EOHAML %h1 フォーム %form{:method => "POST", :action => '/'} %p %input{:type => "submit"} EOHAML
上記ソースをstart.rbなど適当な名前で保存し、
% ruby start.rb
で起動し、http://sample-host:4567/ にアクセスすると、"form","form2"という2つのリンクが表示されます。"form"に進んでボタンを押すと"ok"、"form2"に進んでボタンを押すと"CSRF exception!!"と表示されます。
以下、ソースの要点を解説します。
require 'rack/csrf' : use Rack::Csrf, :raise => true, :skip => ['POST:.*', 'PUT:.*', 'DELETE:.*']
requireでライブラリを読み込み、useで使用を宣言(?)します。この時、:skipにPOST, PUT, DELETEメソッドの任意のページを指定してRack::Csrf.callメソッド内でのチェックを無効にしてしまいます。
set :show_exceptions, false
Sinatraの例外表示処理を無効にします。trueにすればいつものトレース画面が表示されます。
def check_csrf raise Rack::Csrf::InvalidCsrfToken unless params[Rack::Csrf.csrf_field] == session['csrf.token'] end
CSRFチェック用のメソッドです。
before do check_csrf if ['POST', 'PUT', 'DELETE'].include?(env['REQUEST_METHOD']) end
beforeフィルタ内にこのように書くことで、POST, PUT, DELETEメソッドの全てのページでCSRFのチェックを行います。これで普通にRack::Csrfを利用した場合と同じ動作となり、かつ例外が発生したときにerrorハンドラーで処理できるようになります。
もし、特定のページだけCSRFチェックしたい場合は、beforeブロック内のcheck_csrfを削除して、
post '/foo' do check_csrf : end
のように、チェックしたいページでの処理の先頭にcheck_csrfを持ってきます。
error Rack::Csrf::InvalidCsrfToken do "CSRF exception!!" end
例外を捕捉して処理するためのコードです。
Rack::Csrfの場合は:skipオプションがあったので迂回できましたが、あまりエレガントではないですね。
あまりよく分かってないのですが、Rackの方で、
とかの何らかの枠組みが必要な気がします。
- aparadekto [Hey, I can't view your site properly within Opera, I actua..]
- hs [Hmm... I checked with Opera 10.63 and it looks no problem ..]