# HG changeset patch # User Paul Boddie # Date 1370956998 -7200 # Node ID 9eb0dcdf488c4766ec019446048a85c440f2c04c # Parent bffc66ce38a1dba0aec3657ee416b627e59876d2 Added handling of nested macros and table of contents support to the XHTML parser. diff -r bffc66ce38a1 -r 9eb0dcdf488c wikiparser.py --- a/wikiparser.py Tue Jun 11 14:21:03 2013 +0200 +++ b/wikiparser.py Tue Jun 11 15:23:18 2013 +0200 @@ -418,7 +418,7 @@ macrotypes = { "anchor" : "<>", "color" : "<>", - "toc" : "<>", + "toc" : "<>", } class ConfluenceParser: diff -r bffc66ce38a1 -r 9eb0dcdf488c xmlparser.py --- a/xmlparser.py Tue Jun 11 14:21:03 2013 +0200 +++ b/xmlparser.py Tue Jun 11 15:23:18 2013 +0200 @@ -129,6 +129,7 @@ # Confluence macro MoinMoin syntax "anchor" : "<>", "color" : "<>", + "toc" : "<>", } normalise_regexp_str = r"\s+" @@ -150,8 +151,8 @@ # Macro information. - self.macro = None - self.macro_parameters = {} + self.macros = [] + self.macro_parameters = [] self.held_anchors = [] # Indentation and element nesting states. @@ -205,7 +206,8 @@ # Remember macro information for use within the element. if name == "ac:macro": - self.macro = self.attributes[-1].get("ac:name") + self.macros.append(self.attributes[-1].get("ac:name")) + self.macro_parameters.append({}) def endElement(self, name): @@ -231,8 +233,8 @@ # Discard macro state. if name == "ac:macro": - self.macro = None - self.macro_parameters = {} + self.macros.pop() + self.macro_parameters.pop() def characters(self, content): if not self.is_preformatted(): @@ -323,11 +325,11 @@ # Remember macro information. elif name == "ac:parameter": - self.macro_parameters[self.attributes[-1].get("ac:name")] = text + self.macro_parameters[-1][self.attributes[-1].get("ac:name")] = text text = "" elif name == "ac:default-parameter": - self.macro_parameters[self.attributes[-2].get("ac:name")] = text + self.macro_parameters[-1][self.attributes[-2].get("ac:name")] = text text = "" # Handle single-level tags. @@ -347,9 +349,9 @@ # Macro name information is used to style rich text body regions. - if name != "table" and self.macro and macro_rich_text_styles.has_key(self.macro): - details = macro_rich_text_styles[self.macro] - title = self.macro_parameters.get("title") + if name != "table" and self.macros and macro_rich_text_styles.has_key(self.macros[-1]): + details = macro_rich_text_styles[self.macros[-1]] + title = self.macro_parameters[-1].get("title") if title: details = "%s\n\n%s" % (details, title) @@ -394,16 +396,16 @@ # simpler macros are handled here. elif name == "ac:macro": - conversion = macrotypes.get(self.macro) + conversion = macrotypes.get(self.macros[-1]) if conversion: parameters = {"content" : text} - parameters.update(self.macro_parameters) - argnames = macroargs.get(self.macro) + parameters.update(self.macro_parameters[-1]) + argnames = macroargs.get(self.macros[-1]) if argnames: confargname, moinargname = argnames - parameters["args"] = quote_macro_argument("%s=%s" % (moinargname, self.macro_parameters[confargname])) + parameters["args"] = quote_macro_argument("%s=%s" % (moinargname, self.macro_parameters[-1][confargname])) text = conversion % parameters - if self.macro == "anchor" and self.forbids_macros(): + if self.macros[-1] == "anchor" and self.forbids_macros(): self.held_anchors.append(text) text = ""