メモなので適当です。本家にマージされたら本気出す。
Parserについての変更
ASTを作る
旧parserでは構文解析と出力生成を別処理に分けずに、正規表現を駆使して解析しながら出力もやっていました。
次期parserではまず最初にParserがASTを作ります。現状はkpegライブラリを利用してます。ASTができた後で出力文字列を生成します。
主な流れは以下の通り。
テキストを渡す
↓
AST(Nodeクラスのオブジェクト)に変換
↓
ASTレベルの変換処理(ASTを別のASTに変換する)を行う
↓
文字列化(Node#to_docを再帰的に適用)
ASTはReVIEW::NodeクラスのオブジェクトとArrayから成り立っています。
ArrayにはArray#to_doc
とArray#to_raw
が追加されます。これは、各要素にそれぞれのメソッドを再帰的に適用し、結果を文字列として連結するものです。
JS版との互換性は考慮したいのですが、どうなるかは未定です。
(詳しくはあとで書くかも)
Builderについての変更
各Builderとエスケープについて、Builder内のハンドラ(メソッド)には引数として解析済みの文字列が渡される
旧builderではエスケープというか解析されていない文字列が渡されてきているので、Builderのハンドラ内で追加の解析処理を行っていました。要するにParseをもう一回行うような感じです。それはさすがにアレなので、Parseは一回だけ全体を一度に行うことになります。
問題はParseではなく結果の文字列の生成で、これをどのタイミングで行うかになりますが、結果的にはハンドラ内ではその部分文字列、つまりコマンドブロック内の文字列や引数の文字列については変換後の文字列を受け取るようにします。そうしないといろいろ辛いので。
ただし、変換前の文字列が必要になるものもあります。例えば文字列をIDとして使いたいとか、特殊な文字列(TeX風数式)を渡したい、といった場合に、そこにエスケープ済みの文字列が渡されると辛いことになります(特にLaTeX)。そこで以下が導入されます。
ハンドラ内でのcompile_inlineなどは削除
上記に付随して、今までハンドラ内でcompile_inlineを使っていたところは修正が必要です。
ASTを引数とするハンドラを作れるようにする
//foo
に対してdef foo
で定義していたものが、def node_foo
というふうになります。
インライン記法については@<hoge>{}
はdef inline_hoge
だったものが、def node_inline_hoge
になります。
ただし、とりあえずは古いメソッドも使えるようにします。その場合、ブロック記法ならlinesと各引数のparse済み文字列を引数としたメソッド、インライン記法なら文字列1つを渡すメソッドになります。
fooとnode_fooが両方ある場合、node_fooが優先されます。これにより、node_fooで上書きすることもできる、という形です。
インライン記法の処理については、旧APIはparseが微妙なので、カンマ区切り文字列等を渡すものはAST中心にした方がいいかもしれません(1引数のインライン記法であれば旧APIでも問題なさそう)。
ブロックのハンドラとインラインのハンドラは文字列を返す&print/putsは使用不可
旧Builderではハンドラの実装として、putsやprintを使って返すものと、文字列を返すものが混在していましたが、前者は撤廃されます。putsやprintでは出力順序が実行順序に依存してしまうので、これだといろいろ困るのでした。
理由はどうあれ、各ハンドラの仕組みがシンプルになるのはメリットかと。
実装上の注意点
Builder
- compile_inline、escapeは原則削除
- rawの扱いについて、
\n
は改行に、\\
は\
に、\}
と\]
は'}'と']'に(インラインかブロックかで異なる)、それ以外はそのまま
LATEXBuilder
- 旧パーサでは複数行のparagraph内の改行文字が(実は)残っていた一方で、新パーサでは改行を落とすようにする
-
foo\nbar\n
といった文字列が、foobar\n
になる - HTMLBuilderではすでにこの挙動だったので、これに合わせる形になる
-
Test
- raw_resultは使わない
- helperメソッドを使うようにする?