# TODO: due to HTML/CSS quirks, we may need to add an empty <div
# class="rowclear"> after every <div class="row">
-def _assert_no_column_structure(node, known_nodes, styleinfo, current_level):
- # Check that no NEWROW/NEWCOL commands are found in the *children*
+def _find_child_with_column_structure(node, known_nodes, styleinfo):
for n in node.getiterator():
name = known_nodes.get(n)
commands = styleinfo[name]
if NEWROW in commands or NEWCOL in commands:
- raise BadStructure("Heading '%(heading)s' has a 'New row' or 'New column' command applied to "
- "it, but it is at a section level %(level)s, which is lower than current "
- "column structure, which is defined at level %(curlevel)s." %
- dict(heading=name, level=n.tag, curlevel=current_level))
+def _get_next_section_node(nodelist, known_nodes):
+ name = known_nodes.get(n)
def _add_rows_and_columns(topnode, known_nodes, styleinfo):
# This is the most involved and tricky part. See the comments
# above the 'format_html' function.
+ # NB: known_nodes, and all nodes passed around and manipulated,
+ # are the nodes of the containing divs we have added to the
- children = list(topnode.getchildren())
+ children = list(topnode.getchildren()) # our own copy, which we don't change
# Offset used to cope with the fact that we are pulling sub-nodes
# out of topnode as we go along.
# Rows/columns can only be added within the same level of
# nesting of the HTML document. This means we do not need
# to recurse if we have started adding rows/columns.
- # However, it is helpful to recurse and check that no
- # NEWROW/COL commands were found, and complain to the user
- _assert_no_column_structure(node, known_nodes, styleinfo,
+ # However, if we are actually in a '1 column row', we
+ # allow a nested column structure, but only by imposing
+ # constraints on what follows.
+ child = _find_child_with_column_structure(node, known_nodes, styleinfo)
+ raise BadStructure("Item '%(tag)s: %(name)s' has a 'New row' or 'New column' command applied to "
+ "it, but it is a subsection of '%(ptag)s: %(pname)s' which is already in a column "
+ "and columns cannot be created within columns." %
+ dict(tag=cnode.tag, name=cname, ptag=cur_row_start.tag, pname=name))
+ # Allow it, but next section on this level must
+ # not be NEWCOL (unless it is also NEWROW)
+ nextnodename = _get_next_section_node(children[idx+1:], known_nodes)
+ if nextnodename is not None:
+ nextnode_commands = styleinfo[nextnodename]
+ if NEWCOL in nextnode_commands and (NEWROW not in nextnode_commands):
+ raise BadStructure("Item '%(ptag)s: %(pname)s' has a column structure within in "
+ "but section '%(name)s' has a 'New column' command applied to "
+ "it. This would create a nested column structure, which is "
+ "not allowed." % (dict(name=nextnodename, ptag=cur_row_start.tag, pname=name)))
+ _add_rows_and_columns(node, known_nodes, styleinfo)
_add_rows_and_columns(node, known_nodes, styleinfo)