FreeStyleWiki

HtmlTemplate

このエントリーをはてなブックマークに追加

[Clojure]

HtmlTemplate

Clojure版のHTML::Template実装を作りたい

  HTML::Templateの仕様

  • 仕様
タグ 概要
TMPL_VAR 単純な文字列補間(string interpolation)
TMPL_LOOP 配列で文字列補間
TMPL_INCLUDE ファイルから読み取った文字列で置換する
TMPL_IF 条件付きの文字列補間
TMPL_ELSE 条件付きの文字列補間
TMPL_UNLESS 条件付きの文字列補間

実装方法検討

  まずHTMLソースをantlrに食わせてAST(Abstract Syntax Tree)を得る

  • antlerのプロジェクト内にいろいろな言語用のパーサジェネレータの元がある
  • Clojureのantlerラッパーもある
    • aphyr/clj-antlr ← これは実行時に文法ファイルを読めるが、単一ファイルしか処理できない

HTML用の文法ファイルを使ってみる

サンプルコード

(ns html-template.core
  (:gen-class)

  (:import [org.antlr.v4.runtime ANTLRInputStream CommonTokenStream]
           [html_template.core HTMLParser HTMLLexer])

  (:require [clojure.java.io :as io]))

(defn stream [input]
  (new ANTLRInputStream input))

(defn html-parser [tokens]
  (new HTMLParser tokens))

(defn html-lexer [stream]
  (new HTMLLexer stream))

(defn tokens [lexer]
  (new CommonTokenStream lexer))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (let [stream (stream "<html>Hello,World</html>")
        lexer (html-lexer stream)
        tok (tokens lexer)
        parser (html-parser tok)
        ctx (.htmlDocument parser)]
    (println (.toStringTree ctx))))

出力

$ lein run
([] ([61] ([73 61] < ([81 73 61] html) > ([89 73 61] ([120 89 73 61] Hello,World)) < / ([92 73 61] html) >)))

とりあえずこれでそれっぽいものは得られた。

  ASTを走査して条件にあったノードを改変する

antlrをそのまま使う?

意外に難しいようだ。まあ一度作った木構造を改変するのだからそれは難しいだろう。

Clojureのライブラリを使う?

その他

探してたらそれっぽいのはいろいろある

  ASTをHTMLに戻す