Skip to content

Instantly share code, notes, and snippets.

@bga
Created November 1, 2011 23:53
Show Gist options
  • Save bga/1332310 to your computer and use it in GitHub Desktop.
Save bga/1332310 to your computer and use it in GitHub Desktop.
ltml.js
String.prototype._quoteCString = #{
-> @replace(/\\/g, '\\\\').replace(/\"/g, '\\"')
}
fix _ltmlToHtml = #(s) {
fix _skipSpaces = #(p) {
-> p + s.slice(p).match(/^\s*/)[0].length // skip
}
fix _passAttr = #(p) {
switch(s.charAt(p))
{
case '(': // (:attrName value)
fix q = s.indexOf(')', p)
fix sub = s.slice(p + 1, q)
-> {
ret: sub.replace(
/^:(\w+)(\s+)([^)]*)/,
#(all, name, ws, value) {
-> ''.concat(name, '="', value._quoteCString(), '"')
}
),
p: q + 1
}
case ':': // :attrName ?value
var m = /^:(\w+)(\s+)([^():\s]+)?/.exec(s.slice(p))
-> {
ret: ''.concat(m[1],
((m[3] || '').length > 0)
? ''.concat('="', m[3]._quoteCString(), '"')
: ''
),
p: p + m[0].length
}
default:
throw s.slice(p)
}
}
fix _passTag = #(p) {
fix tagNameM = /\((\w+)/.exec(s.slice(p))
fix tagName = tagNameM[1]
p += tagNameM[0].length
var attrs = ''
var cont = ''
var isCont = no
fix _combineTag = #{
-> ''.concat('<', tagName, attrs, '>', cont, '</', tagName, '>')
}
fix _applyRet = #(ret) {
p = ret.p
-> ret.ret
}
fix _prependSpaces = #{
if(!isCont)
{
var m = /(\n[ \t]*?)$/.exec(s.slice(0, p))
if(m)
cont += m[1]
isCont = yes
}
}
while(p < s.length) {
var q = _skipSpaces(p)
if(isCont)
cont += s.slice(p, q)
p = q
switch(yes)
{
case s.charAt(p) == ')': // end of tag
-> {ret: _combineTag(), p: p + 1}
case s.charAt(p) == ':' || s.substr(p, 2) == '(:': // attr
attrs += ' ' + _applyRet(_passAttr(p))
break
case s.substr(p, 2) == '(*': // block comment
var q = s.indexOf('*)', p)
cont += ''.concat('<!--', s.slice(p + 2, q), '-->')
p = q + 2
break
case s.charAt(p) == '(': // nested tag
_prependSpaces()
cont += _applyRet(_passTag(p))
break
default:
_prependSpaces()
fix q = s.slice(p).search(/[()]/) + p
cont += s.slice(p, q)
p = q
//throw s.slice(p)
}
}
}
-> _passTag(0).ret
}
//var w = open()
//w.document.open('text/html')
_log(_ltmlToHtml("""
(table (:style color: red; background: green)
(thead :width 100
(tr
(th (:style color: black) (i name) tt)
(th address) (* comment *)
)
)
(tbody
(tr
(td Mark)
(td Foo)
)
(tr
(td Twen)
(td Bar)
)
)
)
""".trim()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment