def test_it_compiles_pystrip(): assert c('<div py:strip=""><p>foo</p></div>') == [ im.TextNode(pos=P(1, 18), content='<p>foo</p>'), ] assert c('<div py:strip="x"><p>foo</p></div>') == [ im.IfNode(pos=P(1, 1), test='not (x)', children=[im.TextNode(pos=P(1, 1), content='<div>')]), im.TextNode(pos=P(1, 19), content='<p>foo</p>'), im.IfNode(pos=P(1, 29), test='not (x)', children=[im.TextNode(pos=P(1, 29), content='</div>')]), ]
def test_it_compiles_tag_with_outer_directive_attrs(): assert c('<div py:if="foo">bar</div>') == [ im.IfNode(pos=P(1, 13), test='foo', children=[ im.TextNode(pos=P(1, 1), content='<div>bar</div>'), ]), ]
def test_it_processes_strip_whitespace_and_keeps_line_numbering(): assert c(u'<p py:whitespace="strip"> ' u'<py:if test="True"> hello! </py:if></p>') == [ im.TextNode(pos=P(1, 1), content='<p>'), im.IfNode( pos=P(1, 27), test='True', children=[im.TextNode(pos=P(1, 47), content='hello!')]), im.TextNode(pos=P(1, 62), content='</p>') ] assert c(u'<html><py:whitespace value="strip"> ' u'<p><py:if test="True"> hello! </py:if></p>' u'</py:whitespace></html>') == [ im.TextNode(pos=P(1, 1), content='<html><p>'), im.IfNode( pos=P(1, 40), test='True', children=[im.TextNode(pos=P(1, 60), content='hello!')]), im.TextNode(pos=P(1, 75), content='</p></html>') ]
def test_it_compiles_if_else(): assert c('<py:if test="foo">xxx</py:if>' ' ' '<py:else>zzz</py:else>') == [ im.IfNode( pos=P(1, 1), test='foo', children=[im.TextNode(pos=P(1, 19), content='xxx')], else_=im.ElseNode( children=[im.TextNode(pos=P(1, 41), content='zzz')])) ]
def compile_if(stmt, *args): n = im.IfNode(test=stmt.raw_args, pos=stmt.pos) children = stmt.children if children: last = children[-1] if isinstance(last, Statement) and last.name == 'else': children = children[:-1] n.else_ = im.ElseNode( pos=last.pos, children=[_compile_node(c) for c in last.children]) n.children = [_compile_node(c) for c in children] return n
def test_it_compiles_conditional_attr_interpolation(): assert c('<input selected="$foo"/>') == [ im.TextNode(pos=P(1, 1), content='<input '), im.WithNode(pos=P(1, 8), vars=[('__piglet_tmp', 'foo')], children=[ im.IfNode(pos=P(1, 8), test='__piglet_tmp is not None', children=[ im.TextNode(pos=P(1, 8), content='selected="'), im.InterpolateNode(pos=P(1, 18), value='__piglet_tmp'), im.TextNode(pos=P(1, 22), content='"') ]) ]), im.TextNode(pos=P(1, 23), content='/>') ]
def _compile_close_tag(node, tagname_expr=None, strip_condition=None): if not node.close_tag or (isinstance(node, Fragment) and not tagname_expr): return im.TextNode('', pos=node.close_tag_pos) if tagname_expr: closetag = im.ContainerNode(children=[ im.TextNode.factory('</', pos=node.close_tag_pos), im.InterpolateNode(value=tagname_expr, pos=node.close_tag_pos), im.TextNode.factory('>', pos=node.close_tag_pos), ]) else: closetag = im.TextNode(node.close_tag, pos=node.close_tag_pos) if strip_condition: if strip_condition in {'True', '1'}: return im.NullNode(children=[closetag]) else: return im.IfNode(test='not ({})'.format(strip_condition), children=[closetag], pos=node.close_tag_pos) return closetag
def _compile_attr(a, container): """ Compile a single parse.Attribute """ intro_text = im.TextNode.factory( '{0.name}{0.space1}={0.space2}{0.quote}'.format(a), pos=a.pos) outro_text = im.TextNode.factory('{0.quote}{0.space3}'.format(a), pos=a.value_pos.advance(a.value)) items = interpolate.parse_interpolations(a.value) if a.name in HTML_EMPTY_ATTRS and \ len(items) == 1 and \ isinstance(items[0], interpolate.Interpolation): interp = items[0] container.append( im.WithNode(vars=[('__piglet_tmp', interp.value)], pos=a.pos, children=[ im.IfNode(test='__piglet_tmp is not None', pos=a.pos, children=[ intro_text, im.InterpolateNode( value='__piglet_tmp', pos=a.value_pos), outro_text ]) ])) else: container.append(intro_text) pos = a.value_pos for i in items: if isinstance(i, (str, ustr)): container.append(im.TextNode.factory(i, pos)) pos = pos.advance(i) else: container.append( im.InterpolateNode(value=unescape(i.value), pos=pos)) pos = pos.advance(i.source) outro_text.pos = pos container.append(outro_text)
def test_it_strips_space_between_py_directives(): assert c('<py:if test="0"></py:if> <py:if test="1"></py:if>') == [ im.IfNode(pos=P(1, 1), children=[], test='0'), im.IfNode(pos=P(1, 26), children=[], test='1') ]
def _compile_open_tag(node, tagname_expr=None, extra_attrs=None, strip_condition=None): """ Compile the open tag attributes. This needs special casing when interpolations are present, eg in the case: <option selected="1 if item == 'foo' else None"> The selected attribute should be entirely omitted if the expression evaluates to None. :param node: the parse.Element node to compile :param tagname_expr: a python expression to replace the tag name :param extra_attrs: A list of python source expressions, each returning a list of attributes :param strip_condition: a python boolean expression to decide whether to output the open tag at all """ if isinstance(node, Fragment) and not tagname_expr: return im.ContainerNode(pos=node.pos) container = wn = im.ContainerNode(pos=node.pos) if strip_condition: if strip_condition in {'True', '1'}: container.append(im.NullNode(pos=node.pos)) else: container.append( im.IfNode(test='not ({})'.format(strip_condition), children=[], pos=node.pos)) wn = container.tip() wn.append(im.TextNode.factory('<', pos=node.pos)) if tagname_expr: wn.append(im.InterpolateNode(value=tagname_expr, pos=node.end_pos)) else: wn.append(im.TextNode.factory(node.qname, pos=node.pos)) wn.append(im.TextNode.factory(node.space, pos=node.pos)) if extra_attrs: wn.append(im.InlineCodeNode(pysrc='__piglet_attrs = {}', pos=node.pos)) for item in extra_attrs: wn.append( im.InlineCodeNode( pysrc='__piglet_attrs.update({})'.format(item), pos=node.pos)) for a in node.attrs.values(): if node.attrs and extra_attrs: wn.append( im.IfNode(test="'{}' not in __piglet_attrs".format(a.name), pos=a.pos)) _compile_attr(a, wn.tip()) else: _compile_attr(a, wn) if extra_attrs: for_ = im.ForNode(each=('__piglet_attr_k, __piglet_attr_v ' 'in __piglet_attrs.items()'), pos=node.end_pos, children=[]) if_ = im.IfNode(test='__piglet_attr_v is not None', pos=node.end_pos, children=[ im.TextNode(' ', pos=node.end_pos), im.InterpolateNode(value='__piglet_attr_k', pos=node.end_pos), im.TextNode('="', pos=node.end_pos), im.InterpolateNode(value='__piglet_attr_v', pos=node.end_pos), im.TextNode('"', pos=node.end_pos) ]) for_.children.append(if_) wn.append(for_) wn.append(im.TextNode(content=node.end, pos=node.end_pos)) return container