Why can't I combine the "no DIV necessary" shortcut with self-terminating tags?

10 views
Skip to first unread message

Geoffrey Plitt

unread,
Jul 2, 2011, 7:59:51 AM7/2/11
to shpaml
I'd like to do the following Shpaml:

> #no_div_and_self_terminating1
> #no_div_and_self_terminating2

to generate the following HTML:

<div id='no_div_and_self_terminating1' />
<div id='no_div_and_self_terminating2' />

but it doesn't work. I have to choose between either the pipe with
nearly-empty content:

#no_div_and_self_terminating1 | &nbsp;

or adding the DIV:

div#no_div_and_self_terminating1

or something else. But yeah- has anybody noticed this, and am I doing
anything wrong?

-G

Steve Howell

unread,
Jul 2, 2011, 12:23:22 PM7/2/11
to shp...@googlegroups.com
You're not doing anything wrong. I guess your use case is to create an empty
DIV that JS later fills in?

I'm surprised I never implemented the "PASS" keyword after the pipe, which would
allow you to do a one-liner that doesn't force you to add &nbsp.

This is valid syntax, but less than ideal:

#ajax1
PASS
#ajax2
PASS

You can probably patch this regex in your local version of shpaml:
@syntax('(.*?) \| (.*)') def TEXT_ENCLOSING_TAG(m): tag, text = m.groups()
return enclose_tag(tag, text)

I think you want to insert "(?:PASS$)" into the syntax,
@syntax('(.*?) \| (?:PASS$)?(.*)')
>>> re.match('(.*?) \| (?:PASS$)?(.*)', "div | PASS").groups() ('div', '') >>>
>>>re.match('(.*?) \| (?:PASS$)?(.*)', "div | desired content").groups() ('div',
>>>'desired content')

Steve Howell

unread,
Jul 2, 2011, 12:44:38 PM7/2/11
to shp...@googlegroups.com
One problem with allowing this syntax:

span | PASS

...is that you would no longer be able to produce this html with a one-liner

<span>PASS</pass>

It's probably rare that you'd need that, so the patch is probably worthwhile for
you, but it would be potentially problematic for other users.

The other syntax that you tried, which was to assume that div shortcuts apply
after "> ", might not be as problematic.

This is the method that manipulates lines with text to the right of the angle
bracket:
@syntax('> (.*)') def SELF_CLOSING_TAG(m): tag = m.group(1).strip()
return '<%s />' % apply_jquery(tag)[0]
You probably add these two lines before the "return" statement:
if DIV_SHORTCUT.match(tag): tag = 'div' + tag
I haven't tested it, though. I also haven't thought through all the
implications, but it seems innocuous enough.

Geoffrey Plitt

unread,
Jul 3, 2011, 6:46:47 AM7/3/11
to shpaml
Thanks for the quick and awesome response, Steve!

The fixed worked like a charm, and made me realize another question I
had - have you guys talked about a syntax similar to self-closed tags,
but for empty tags? Perhaps:
>> #emptyDiv
or
> #emptyDiv >
or
#emptyDiv ||

And it would evaluate to:
<div id='emptyDiv'></div>

Curious if anyone else has mentioned this.

-G
> > allow you to do a one-liner  that doesn't force you to add  .

Ashmoi

unread,
Jul 3, 2011, 7:36:53 AM7/3/11
to shp...@googlegroups.com
I've been looking for something like that.

Intuitively the following should work:

> #outer > #inner

should translate to

<div id="outer"><div id="inner" /></div>

And

#outer > #inner |

should translate to

<div id="outer"><div id="inner"></div></div>

IIRC, both aren't handled as expected (some or all of it is treated as a
literal rather than as SHPAML).

Adding this behaviour would therefore create no problems with backwards
compatibility without adding new symbols.


Cheers,

Ashmoi

Steve Howell

unread,
Jul 3, 2011, 11:18:54 AM7/3/11
to shpaml
Nobody has mentioned the "||" syntax for line methods, or at least I
don't recall it coming up.

It seems reasonable to me. The patch there is probably to create a
new LINE_METHODS.

You'd add a function similar to this with a regex that reflects the
new syntax you propose:

@syntax('(.*?) \| (.*)')
def TEXT_ENCLOSING_TAG(m):
tag, text = m.groups()
return enclose_tag(tag, text)

Something like:

@syntax('(.*?) \|\|$')
def NON_SELF_CLOSING_TAG(m):
tag = m.groups()[0]
return enclose_tag(tag, '')

Then add it in here:

LINE_METHODS = [
RAW_HTML,
TEXT,
OUTER_CLOSING_TAG,
TEXT_ENCLOSING_TAG,
SELF_CLOSING_TAG,
NON_SELF_CLOSING_TAG
RAW_TEXT,
]

Then the rest would be handled by the general parsing mechanism.

Steve Howell

unread,
Jul 3, 2011, 11:31:15 AM7/3/11
to shpaml
Shpaml does recurse for some scenarios:

#one > #two > #three | 3

<div id="one"><div id="two"><div id="three">3</div></div></div>

What makes it happen for OUTER_CLOSING_TAG is the call to
convert_line:

@syntax('(.*?) > (.*)')
def OUTER_CLOSING_TAG(m):
tag, text = m.groups()
text = convert_line(text)
return enclose_tag(tag, text)

There may be other line methods where a recursive parse makes sense.
You could try some experimentation in your local version.

I'd be a little cautious about it, though, especially if you need to
play nice with a templating language. Also, consider this
translation:

#documentation | shpaml uses a | as part of its syntax
<div id="documentation">shpaml uses a | as part of its syntax</div>

Right now shpaml ignores everything after the first pipe, which means
you don't have to worry about escaping the second pipe. A recursive
syntax would make that more painful, or perhaps even impossible, to
write.

Ashmoi

unread,
Jul 3, 2011, 12:13:29 PM7/3/11
to shp...@googlegroups.com
Ah, true, but in any case this fails for the following scenario:

#one > #two > #three |

The trailing bar, even if followed by whitespace, won't be handled as
expected.

Any reason this shouldn't be handled the same as a bar followed by
actual content?

Steve Howell

unread,
Jul 3, 2011, 12:19:28 PM7/3/11
to shpaml
The problem you mention comes down to this not doing what you want:

#foo |

The recursion aspect is orthogonal.

I am pretty sure that if you applied one of the patches I suggested to
Geoffrey, you would get the desired behavior for the recursive case as
well.

I like the idea of this translation:

#foo ||
<foo></foo>
Reply all
Reply to author
Forward
0 new messages