padolsey / SIML

Simplified Markup
MIT License
97 stars 5 forks source link

Feature Request: Prototypes #2

Closed wooorm closed 11 years ago

wooorm commented 11 years ago

One of the greatest thing a preprocessor can do, is help better the authors writing experience: Less doing and more results.

This is why I propose adding a “prototype” like feature to SIML, a feature that allows authors to write concise code—writing certain selectors once, instead of multiple times.

Note: I’m not talking about mixins: Mixins are great too, but I’m seeing prototypes as an element, rather than “document fragment”, like feature.

Input

Setting prototypes: /[A-Za-z][A-Za-z0-9_-]* = /

// Setting prototypes.
primary-header = h1.giant

// Setting prototypes with Default values in prototypes.
image = img[alt=""]

Getting prototypes: /\+[A-Za-z][A-Za-z0-9_-]*/

// Getting prototypes.
+primary-header "Hello World!"

// Getting and implicitly using default `alt` attribute.
+image[src="./image.png"]

// Getting and overwriting default `alt` attribute.
+image[alt="a crocodile swimming in a river."][src="./other-image.png"]

Output

<h1 class="giant">Hello World!</h1>
<img alt="" src="./image.png" />
<img alt="a crocodile swimming in a river." src="./other-image.png" />

Final Notes

Sure, this is just a draft—the regexes are just an idea, I haven’t thought about what happens with multiple classes (in the prototype setting, and the prototype getting)—but “mixins” seem like a logical extension of an HTML preprocessor: One which I haven’t seen in HAML, Jade, Slim, and the like.

padolsey commented 11 years ago

I really like this idea!

I think the prototype-getter token will have to be something other than '+' though -- it would introduce too much ambiguity since we're already using it as the CSS sibling combinator.

Thinking about it, the parser could just check, when you specify a selectorTag (e.g. div, header), whether or not a prototype is defined by that name. So we don't necessarily need an explicit operator to recall prototypes. It could be as simple as.

something = div.foo

header > something.bar

Outputting:

<header><div class="foo bar"></div></header>

What are your thoughts?

wooorm commented 11 years ago

Like the idea.

And you're right about the +. Dropping it would also give the author the ability to rewrite a selectorTag: e.g. img = img[alt=""].

However, what about scope? Would the following SIML…

img[src=a]
    img = img[alt=""]
    img[src=b]
img[src=c]

…result in this…

<img src="a" />
    <img src="b" alt="" />
<img src="c" alt="" />

…or this?

<img src="a" />
    <img src="b" alt="" />
<img src="c" />

I'd opt for the latter; but would it be easy to implement in the parser?

padolsey commented 11 years ago

I agree -- the latter makes sense. Fortunately, it's too hard to handle scoping.

padolsey commented 11 years ago

I've begun implementation in the feature-prototype branch. It was surprisingly simple to implement. Feel free to check it out and play with test/resources/live-parser.html

Next step is to write some tests.

wooorm commented 11 years ago

I like it, i like it a lot!

padolsey commented 11 years ago

Ok, it's now in the 0.3.2 release! :)

Ready to play with here: http://padolsey.github.com/SIML/

Here's one of the chunks I've tested it with:

link = a.link.special[href=""][title="placeholder"]
link
link.another
link[href="http://foo.com/blah"].yet.another
link[href="foo"][title="blah"]
wooorm commented 11 years ago

Works great! Also: Nice fix on the img[alt=a][alt=b] thing, I wasn’t sure if it was a bug, or a feature .