2007年 10月 21日

Io で ERB みたいなの

EIo := Object clone do (
	string := ""
	compiledString := ""

	setString := method(string,
		self string = string asMutable
		self compiledString = self compileString(self string)
		self
	)

	doInObject := method(obj,
		# 汚さないように clone
		obj clone do (
			h := method(v,
				v asString asMutable replaceSeq("&", "&") ¥
				                     replaceSeq("<", "&lt;") ¥
				                     replaceSeq(">", "&gt;")
			)
		) doString(self compiledString)
	)

	compileString := method(string,
		ret := "_eio_string := ¥"¥" asMutable¥n" asMutable
		n   := 0
		p   := 0
		while (n = string findSeq("<%", p),
			s   := string slice(p, n) replaceSeq("¥"", "¥¥¥"")
			n = n + 2
			c   := string findSeq("%>", n)
			mes := string slice(n, c)
			ret appendSeq("_eio_string appendSeq(¥"#{s}¥")¥n" interpolate)
			if (mes beginsWithSeq("="),
				if (mes beginsWithSeq("=="),
					ret appendSeq("_eio_string appendSeq(#{mes slice(2)})¥n" interpolate)
				,
					ret appendSeq("_eio_string appendSeq(h(#{mes slice(1)}))¥n" interpolate)
				)
			,
				ret appendSeq("#{mes}¥n" interpolate)
			)


			p = c + 2
		)
		s   := string slice(p) replaceSeq("¥"", "¥¥¥"")
		ret appendSeq("_eio_string appendSeq(¥"#{s}¥")¥n_eio_string" interpolate)
		ret
	)
)

# data := File openForReading("test.eio") contents
data := """
<p><%=hoge%></p>
<ol>
<% list("aaa", "bbbb", "ccccc", "ddddddd") foreach(i, v, %>
	<li><%=i+1%>. <%=v%></li>
<% ) %>
</ol>
"""

eio := EIo clone setString(data)
# eio compiledString print

context := Object clone do (
	hoge := "hogeog&e<>"
)
eio doInObject(context) print

出力

<p>hogeog&amp;e&lt;&gt;</p>
<ol>

        <li>1. aaa</li>

        <li>2. bbbb</li>

        <li>3. ccccc</li>

        <li>4. ddddddd</li>

</ol>

ヒアドキュメント書けた。トリプルクオートだった。ので修正