Question: do I read your compiler right, that any line starting with 'var', 'function' or 'this' is assumed to be javascript? So for instance:
<p>
How will riot.js compile
this line?
</p>
would fail?
[Don't mean to sound negative: I've been playing around with my own minimalist framework, so this is right up my alley. I'm reading the code to get a feel for how we've solved problems the same or differently, including the compile phase. Neat stuff and I'll write more when I have time to go over it in more depth.]
I tried making a simple dynamic page and failed repeatedly by attempting to put seemingly innocuous javascript in { } blocks. A simple case such as { platforms.join(' ') } works fine as where { technologies.map(function(t) {return t}).join('|') } does not. Until this is either fixed or (all limitations and work-arounds) documented, I consider this unusable for any real project.
(function(v) {
try {
v = d.technologies.map(d.function(d.t) {
d.return d.t
} finally {
return !v && v !== 0 ? "" : v
}
}).call(d), ").join('|') }"].join("")
There's two problems: (1) prefixing keywords with 'd.' which may possibly be solved by skipping keywords or with(d){...} and (2) the ").join('|') }" code became data.
The compiler also fails if a multi-line comment doesn't end at the end of a line.
<!-- a comment --> and more text
It outputs an empty compiled file.
My honest opinion is that you should consider rewriting the compiler in a classic tokenize-parse-compile style. Several projects (like mustache.js) have had to go through this evolution. Your current solution -- line-by-line with regexes and state flags -- will only get hairier and hairier.
Well, maybe a line-by-line solution is good enough, I mean, it would only target a subset but the code will be readable. I still think though that any compiler which is intended for real apps should do the classic tokenize-parse-compile steps.
Idea: require a <script> tag around the JS in the template (but just for your parser's benefit, not as a tag you intend to embed literally in the rendered DOM -- you can remove it at parse time as necessary).
This has the nice side benefit that it will make editors happy. (E.g. emacs recognizes <script> tags within HTML and does JS highlighting/indenting on their content.)
Agree, removing the need for any special editor support would be great, even if offered as a compiler option. Makes the detection of JS a non-issue too.
This seems like a great idea, even if it's just optional tags that get ignored. With <script> you suddenly have a valid html fragment that should work with any editor.
I guess as is, a make could include a grep -v </?script> step.
The idea of having integrated components (HTML+JS) is certainly interesting and forward-thinking. However, I hope it doesn't lead you to limit us to the integrated style, by making the Riot compiler a required build step.
Personally, I greatly prefer the direct coding style, i.e., riot.tag(). Not only because of the editor issues mentioned here, but because I can include my own modules in my scripts. I.e., can I use require() inside a Riot-compiled module?
Stuff starts getting very hoop-jumpy once you start creating your own compiler & syntax, and bringing too much "magic" to the table. One of the big appeals of Riot is how UN-magical it is!
Confirmed. Just take the demo app and insert the line 'this is some text.' anywhere in it. It looks like it's particularly bad if you put it into a nested element: the compiler treats everything after the line (including html markup) as javascript.
[Don't mean to sound negative: I've been playing around with my own minimalist framework, so this is right up my alley. I'm reading the code to get a feel for how we've solved problems the same or differently, including the compile phase. Neat stuff and I'll write more when I have time to go over it in more depth.]