def mbx_strict(text): """ Remove white space that confuses xslt. """ # need a big comment explaining the general ideas, pluse one for each case thetext = text thetext = postprocess.tag_before_after("mrow|intertext", "\n", "", "", "\n", thetext) # do p and li separately, and in this order, because of p in li thetext = postprocess.tag_before_after("p", "x", "", "", "\n", thetext) thetext = postprocess.tag_before_after("li", "x", "", "", "\n", thetext) # no white space arounf me, md, etc thetext = postprocess.tag_before_after("md|mdn", "", "x", "x", "", thetext) thetext = postprocess.tag_before_after("me|men", "", "", "", "", thetext) return thetext
def mbx_strict(text): """ Remove white space that confuses xslt. """ # need a big comment explaining the general ideas, pluse one for each case thetext = text thetext = postprocess.tag_before_after("mrow|intertext", "\n", "", "", "\n", thetext) # do p and li separately, and in this order, because of p in li thetext = postprocess.tag_before_after("p", "x", "", "", "\n", thetext) thetext = postprocess.tag_before_after("li", "x", "", "", "\n", thetext) # no white space arounf me, md, etc thetext = postprocess.tag_before_after("md|mdn", "", "x", "x", "", thetext) thetext = postprocess.tag_before_after("me|men", "", "", "", "", thetext) return thetext
def mbx_pp(text): """ Pretty-print MBX source. """ thetext = text # # first a hack to handle 2-level lists. # thetext = re.sub(r"<li>\s*<p>", "<lip>", thetext) # thetext = re.sub(r"</p>\s*</li>", "</lip>", thetext) # sort-of a hack to handle tags that can occur withing themselves (like li and p) # (does not handle the case of opening tag with parameters) for lip_tag in ["li", "p"]: component.lipcounter[lip_tag] = 0 this_tag_start = "<" + lip_tag + ">" this_tag_end = "</" + lip_tag + ">" the_search_string = this_tag_start + "(.*?)" + this_tag_end component.something_changed = True while component.something_changed: component.something_changed = False thetext = re.sub(the_search_string, lambda match: liprename(match, lip_tag), thetext, 0, re.DOTALL) # print "found", component.lipcounter, "li/p pairs" for n in range(component.lipcounter[lip_tag]): if lip_tag == "li": thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "", "", "\n\n", thetext) else: thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after(lip_tag, "\n\n", "\n", "\n", "\n\n", thetext) # first remove extraneous spaces and put in appropriate carriage returns # thetext = postprocess.tag_before_after("p", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after( "row|tabular|image|latex-image-code|asymptote", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("me|men|md|mdn", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("exercises|exercisegroup|exercise", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after( "webwork|setup|set|pg-code|pg-macros", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("mrow|intertext", "\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dt", "\n\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dd", "\n", "", "", "\n\n", thetext) thetext = postprocess.tag_before_after("sage", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("input", "\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("output", "\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("fn", "", "", "", "", thetext) # thetext = postprocess.tag_before_after("li", "\n\n", "", "", "\n\n", thetext) thetext = postprocess.tag_before_after("ul|ol|dl", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after( "theorem|proposition|lemma|conjecture|corollary", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("algorithm", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("objectives", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after( "definition|axiom|example|insight|exploration|activity|remark|warning|proof", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("problem", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("figure|table", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("paragraphs|sidebyside|aside", "\n\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after( "introduction|statement|solution|answer|hint|objectives|task", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("subsection", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("chapter|section", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("title|cell|caption", "\n", "", "", "\n", thetext) # now shove everything else to the left # need to be more clever, because sometimes the author spacing should be preserved ########### thetext = re.sub("\n +", "\n", thetext) for lip_tag in ["li", "p"]: for n in range(component.lipcounter[lip_tag]): thetext = postprocess.add_space_within(lip_tag + str(n), thetext) # thetext = postprocess.add_space_within(lip_tag + str(n), thetext) # twice, because we will separate into li and p thetext = postprocess.add_space_within("chapter", thetext) thetext = postprocess.add_space_within("section", thetext) thetext = postprocess.add_space_within("subsection", thetext) thetext = postprocess.add_space_within("introduction", thetext) thetext = postprocess.add_space_within("objectives", thetext) thetext = postprocess.add_space_within("figure", thetext) thetext = postprocess.add_space_within("image", thetext) thetext = postprocess.add_space_within("sage", thetext) thetext = postprocess.add_space_within("asymptote", thetext) thetext = postprocess.add_space_within("sidebyside", thetext) thetext = postprocess.add_space_within("aside", thetext) thetext = postprocess.add_space_within("latex-image-code", thetext) for tag in [ "theorem", "definition", "axiom", "proposition", "lemma", "conjecture", "corollary" ]: thetext = postprocess.add_space_within(tag, thetext) for tag in [ "example", "insight", "exploration", "activity", "remark", "warning", "algorithm", "objectives" ]: thetext = postprocess.add_space_within(tag, thetext) thetext = postprocess.add_space_within("task", thetext) thetext = postprocess.add_space_within( "statement|solution|answer|hint|proof", thetext) # thetext = postprocess.add_space_within("p", thetext) thetext = postprocess.add_space_within("paragraphs", thetext) thetext = postprocess.add_space_within("ul", thetext) thetext = postprocess.add_space_within("ol", thetext) thetext = postprocess.add_space_within("dl", thetext) # thetext = postprocess.add_space_within("li", thetext) thetext = postprocess.add_space_within("me|men|md|mdn", thetext) thetext = postprocess.add_space_within("exercises", thetext) thetext = postprocess.add_space_within("exercisegroup", thetext) thetext = postprocess.add_space_within("exercise", thetext) thetext = postprocess.add_space_within("problem", thetext) thetext = postprocess.add_space_within("webwork", thetext) thetext = postprocess.add_space_within("setup", thetext) # thetext = postprocess.add_space_within("var", thetext) thetext = postprocess.add_space_within("set", thetext) thetext = postprocess.add_space_within("pg-code", thetext) thetext = postprocess.add_space_within("pg-macros", thetext) thetext = postprocess.add_space_within("table", thetext) thetext = postprocess.add_space_within("tabular", thetext) thetext = postprocess.add_space_within("row", thetext) thetext = postprocess.add_space_within("pre", thetext) # now put back the li and p for lip_tag in ["li", "p"]: for n in range(component.lipcounter[lip_tag]): # thetext = re.sub(r"(\n *)<" + lip_tag + str(n) + ">",r"\1<" + lip_tag + ">", thetext) # thetext = re.sub(r"(\n *)</" + lip_tag + str(n) + ">",r"\1</" + lip_tag + ">", thetext) thetext = re.sub(r"<" + lip_tag + str(n) + ">", "<" + lip_tag + ">", thetext) thetext = re.sub(r"</" + lip_tag + str(n) + ">", "</" + lip_tag + ">", thetext) # # for some reason there can be extra </lip>. Not sure why. # thetext = re.sub(r"(\n *)</lip>",r"\1 </p>\1</li>", thetext) # special case of p inside li thetext = re.sub(r"(<li>\n)\n( *<p>)", r"\1\2", thetext) thetext = re.sub(r"(</p>\n)\n( *</li>)", r"\1\2", thetext) return thetext
def mbx_pp(text): """ Pretty-print MBX source. """ thetext = text # first remove extraneous spaces and put in appropriate carriage returns thetext = postprocess.tag_before_after("p", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after( "row|tabular|image|latex-image-code|asymptote", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("me|men|md|mdn", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("exercises|exercisegroup|exercise", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("webwork|setup|set|pg-code", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("mrow|intertext", "\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dt", "\n\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dd", "\n", "", "", "\n\n", thetext) thetext = postprocess.tag_before_after("li", "\n\n", "", "", "\n\n", thetext) thetext = postprocess.tag_before_after("ul|ol|dl", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after( "theorem|proposition|lemma|conjecture|corollary", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("algorithm", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("objectives", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after( "definition|axiom|example|insight|exploration|activity|remark|proof", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("problem", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("figure|table", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("paragraphs|sidebyside|aside", "\n\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after( "introduction|statement|solution|answer|hint|objectives", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("subsection", "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after("chapter|section", "\n", "\n", "\n", "\n", thetext) thetext = postprocess.tag_before_after("title|cell|caption", "\n", "", "", "\n", thetext) # # first remove all the spaces at the beginning of a line # thetext = re.sub("\n +", "\n", thetext) # then put it back thetext = postprocess.add_space_within("chapter", thetext) thetext = postprocess.add_space_within("section", thetext) thetext = postprocess.add_space_within("subsection", thetext) thetext = postprocess.add_space_within("introduction", thetext) thetext = postprocess.add_space_within("objectives", thetext) thetext = postprocess.add_space_within("figure", thetext) thetext = postprocess.add_space_within("image", thetext) thetext = postprocess.add_space_within("asymptote", thetext) thetext = postprocess.add_space_within("sidebyside", thetext) thetext = postprocess.add_space_within("aside", thetext) thetext = postprocess.add_space_within("latex-image-code", thetext) thetext = postprocess.add_space_within( "definition|axiom|theorem|example|insight|exploration|activity", thetext) thetext = postprocess.add_space_within("algorithm|objectives", thetext) thetext = postprocess.add_space_within( "proposition|lemma|remark|conjecture|corollary", thetext) thetext = postprocess.add_space_within( "statement|solution|answer|hint|proof", thetext) thetext = postprocess.add_space_within("p", thetext) thetext = postprocess.add_space_within("paragraphs", thetext) thetext = postprocess.add_space_within("ul", thetext) thetext = postprocess.add_space_within("ol", thetext) thetext = postprocess.add_space_within("dl", thetext) thetext = postprocess.add_space_within("li", thetext) thetext = postprocess.add_space_within("me|men|md|mdn", thetext) thetext = postprocess.add_space_within("exercises", thetext) thetext = postprocess.add_space_within("exercisegroup", thetext) thetext = postprocess.add_space_within("exercise", thetext) thetext = postprocess.add_space_within("problem", thetext) thetext = postprocess.add_space_within("webwork", thetext) thetext = postprocess.add_space_within("setup", thetext) # thetext = postprocess.add_space_within("var", thetext) thetext = postprocess.add_space_within("set", thetext) thetext = postprocess.add_space_within("pg-code", thetext) thetext = postprocess.add_space_within("table", thetext) thetext = postprocess.add_space_within("tabular", thetext) thetext = postprocess.add_space_within("row", thetext) thetext = postprocess.add_space_within("pre", thetext) return thetext
def mbx_pp(text): """ Pretty-print MBX source. """ thetext = text # first hide comments thetext = re.sub("--> +\n", "-->\n",thetext) thetext = re.sub("--> +", "-->UVUSpACeVUV",thetext) thetext = re.sub(r"(\s*(<!--)(.*?)(-->))", lambda match: utilities.sha1hide(match, "comment"), thetext, 0, re.DOTALL) # some tags can have punctuation after them for tag in component.punctuatable_tags: thetext = re.sub(r"(</" + tag + ">)" + r"(\S)", r"\1UVUnooooSpACeVUV\2", thetext) thetext = re.sub(r"(</" + tag + ">)" + r" ", r"\1UVUSpACeVUV", thetext) # then hide verbatim content for tag in component.verbatim_tags: thetext = re.sub(r"(\s*(<" + tag + "(>| [^/>]*>))(.*?)(</" + tag + ">))", lambda match: utilities.sha1hide(match, tag), thetext, 0, re.DOTALL) # empty tags that should be on their own line for tag in component.document_pieces_empty: thetext = re.sub(r"\s*(<" + tag + r"[^>]*/>)", "\n" + r"\1", thetext) # sort-of a hack to handle tags that can occur within themselves (like li and p) for lip_tag in component.nestable_tags: component.lipcounter[lip_tag] = 0 thetext = utilities.tag_to_numbered_tag(lip_tag, thetext) print "found", component.lipcounter for n in range(component.lipcounter[lip_tag]): if lip_tag == "li": # note: now the same as the else case! thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "\n", "\n", "\n\n", thetext) else: thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after(lip_tag, "\n\n", "\n", "\n", "\n\n", thetext) # delete all leading spaces! thetext = re.sub(r"\n +", "\n", thetext) # first remove extraneous spaces and put in appropriate carriage returns thetext = postprocess.tag_before_after("dt", "\n\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dd", "\n", "", "", "\n\n", thetext) component.document_global_structure.reverse() component.document_sectioning.reverse() for tag in component.math_display: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.document_components: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.list_like: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.document_environments: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_sectioning: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_global_structure: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_pieces: thetext = postprocess.tag_before_after(tag, "\n", "", "", "\n", thetext) for tag in component.footnote_like: thetext = postprocess.tag_before_after(tag, "", "\n", "\n", "", thetext) # thetext = re.sub(r"(\s)UVUSpACeVUV", r"\1", thetext) # thetext = re.sub(r"UVUSpACeVUV(\s)", r"\1", thetext) # thetext = re.sub(r"UVUSpACeVUV", " ", thetext) # thetext = re.sub(r"\s*UVUnooooSpACeVUV\s*(.)", r"\1", thetext) # sort-of hack for spacing after punctuation after display math thetext = re.sub(r"(</(md|mdn|me|men)>)\s*(;|:|,)\s*", r"\1\3" + "\n", thetext) thetext = re.sub(r"(</(md|mdn|me|men)>)\s*((\?|!|\.)+)\s*", r"\1\3" + "\n", thetext) # sort-of hack for spacing after footnotes that do not end a sentence thetext = re.sub(r"(</fn>)([a-zA-Z])", r"\1 \2", thetext) # space around pagebreak thetext = re.sub(r"\s*<pagebreak\s*/>\s*", "\n\n<pagebreak/>\n\n", thetext) # sort-of hack for cells containing p paragraphs thetext = re.sub(r"(<cell>)(<p[0-9]*>)", r"\1" + "\n" + r"\2", thetext) thetext = re.sub(r"(</p[0-9]*>)(</cell>)", r"\1" + "\n" + r"\2", thetext) # title and idx should not be immediately next to non-pubctuation for tag in ["title", "idx"]: search_string = "(</" + tag + ">)([a-zA-Z]|<)" thetext = re.sub(search_string, r"\1" + "\n" + r"\2", thetext) for lip_tag in component.nestable_tags: for n in range(component.lipcounter[lip_tag]): thetext = postprocess.add_space_within(lip_tag + str(n), thetext) for tag in component.document_global_structure: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_sectioning: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_environments: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_components: thetext = postprocess.add_space_within(tag, thetext) for tag in component.list_like: thetext = postprocess.add_space_within(tag, thetext) for tag in component.math_display: thetext = postprocess.add_space_within(tag, thetext) # since cd is in document_pieces, it does not get spaces inside. # but a cline inside a cd should get spaces in front of it thetext = re.sub("<cline>", " <cline>", thetext) thetext = postprocess.add_space_within("cell", thetext) # now put back the li and p for lip_tag in component.nestable_tags: for n in range(component.lipcounter[lip_tag]): thetext = re.sub(r"<" + lip_tag + str(n) + r"( |>)", "<" + lip_tag + r"\1", thetext) thetext = re.sub(r"</" + lip_tag + str(n) + ">", "</" + lip_tag + ">", thetext) # special case of p inside li thetext = re.sub(r"(<li>\n)\n( *<p>)", r"\1\2", thetext) thetext = re.sub(r"(</p>\n)\n( *</li>)", r"\1\2", thetext) # no blank line after ul or before /ul thetext = re.sub(r"(<(ul|ol|dl)(>| [^>]+>)\n)\n", r"\1", thetext) thetext = re.sub(r"\n(\n *</(ul|ol|dl)>)", r"\1", thetext) # special case of punctuation after a closing display math tag thetext = re.sub(r"(</(me|men)>)\s*((\?|!|;|:|,|\.)+) *?", r"\1\3", thetext) # and punctuation after /line thetext = re.sub(r"(</line>)\s*((\?|!|;|:|,|\.|\)|</)+) *?", r"\1\2", thetext) # print thetext return thetext
def mbx_pp(text): """ Pretty-print MBX source. """ thetext = text # first hide comments thetext = re.sub("--> +\n", "-->\n",thetext) thetext = re.sub("--> +", "-->UVUSpACeVUV",thetext) thetext = re.sub(r"(\s*(<!--)(.*?)(-->))", lambda match: utilities.sha1hide(match, "comment"), thetext, 0, re.DOTALL) # some tags can have punctuation after them for tag in component.punctuatable_tags: thetext = re.sub(r"(</" + tag + ">)" + r"(\S)", r"\1UVUnooooSpACeVUV\2", thetext) thetext = re.sub(r"(</" + tag + ">)" + r" ", r"\1UVUSpACeVUV", thetext) # then hide verbatim content for tag in component.verbatim_tags: thetext = re.sub(r"(\s*(<" + tag + "(>| [^/>]*>))(.*?)(</" + tag + ">))", lambda match: utilities.sha1hide(match, tag), thetext, 0, re.DOTALL) # empty tags that should be on their own line for tag in component.document_pieces_empty: thetext = re.sub(r"\s*(<" + tag + r"[^>]*/>)", "\n" + r"\1", thetext) # sort-of a hack to handle tags that can occur within themselves (like li and p) for lip_tag in component.nestable_tags: component.lipcounter[lip_tag] = 0 thetext = utilities.tag_to_numbered_tag(lip_tag, thetext) print "found", component.lipcounter for n in range(component.lipcounter[lip_tag]): if lip_tag == "li": # note: now the same as the else case! thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "\n", "\n", "\n\n", thetext) else: thetext = postprocess.tag_before_after(lip_tag + str(n), "\n\n", "\n", "\n", "\n\n", thetext) thetext = postprocess.tag_before_after(lip_tag, "\n\n", "\n", "\n", "\n\n", thetext) # delete all leading spaces! thetext = re.sub(r"\n +", "\n", thetext) # first remove extraneous spaces and put in appropriate carriage returns thetext = postprocess.tag_before_after("dt", "\n\n", "", "", "\n", thetext) thetext = postprocess.tag_before_after("dd", "\n", "", "", "\n\n", thetext) component.document_global_structure.reverse() component.document_sectioning.reverse() for tag in component.math_display: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.document_components: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.list_like: thetext = postprocess.tag_before_after(tag, "\n", "\n", "\n", "\n", thetext) for tag in component.document_environments: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_sectioning: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_global_structure: thetext = postprocess.tag_before_after(tag, "\n\n", "\n", "\n", "\n\n", thetext) for tag in component.document_pieces: thetext = postprocess.tag_before_after(tag, "\n", "", "", "\n", thetext) for tag in component.footnote_like: thetext = postprocess.tag_before_after(tag, "", "\n", "\n", "", thetext) # thetext = re.sub(r"(\s)UVUSpACeVUV", r"\1", thetext) # thetext = re.sub(r"UVUSpACeVUV(\s)", r"\1", thetext) # thetext = re.sub(r"UVUSpACeVUV", " ", thetext) # thetext = re.sub(r"\s*UVUnooooSpACeVUV\s*(.)", r"\1", thetext) # sort-of hack for spacing after punctuation after display math thetext = re.sub(r"(</(md|mdn|me|men)>)\s*(;|:|,)\s*", r"\1\3" + "\n", thetext) thetext = re.sub(r"(</(md|mdn|me|men)>)\s*((\?|!|\.)+)\s*", r"\1\3" + "\n", thetext) # sort-of hack for spacing after footnotes that do not end a sentence thetext = re.sub(r"(</fn>)([a-zA-Z])", r"\1 \2", thetext) # space around pagebreak thetext = re.sub(r"\s*<pagebreak\s*/>\s*", "\n\n<pagebreak />\n\n", thetext) # sort-of hack for cells containing p paragraphs thetext = re.sub(r"(<cell>)(<p[0-9]*>)", r"\1" + "\n" + r"\2", thetext) thetext = re.sub(r"(</p[0-9]*>)(</cell>)", r"\1" + "\n" + r"\2", thetext) for lip_tag in component.nestable_tags: for n in range(component.lipcounter[lip_tag]): thetext = postprocess.add_space_within(lip_tag + str(n), thetext) for tag in component.document_global_structure: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_sectioning: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_environments: thetext = postprocess.add_space_within(tag, thetext) for tag in component.document_components: thetext = postprocess.add_space_within(tag, thetext) for tag in component.list_like: thetext = postprocess.add_space_within(tag, thetext) for tag in component.math_display: thetext = postprocess.add_space_within(tag, thetext) # since cd is in document_pieces, it does not get spaces inside. # but a cline inside a cd should get spaces in front of it thetext = re.sub("<cline>", " <cline>", thetext) thetext = postprocess.add_space_within("cell", thetext) # now put back the li and p for lip_tag in component.nestable_tags: for n in range(component.lipcounter[lip_tag]): thetext = re.sub(r"<" + lip_tag + str(n) + r"( |>)", "<" + lip_tag + r"\1", thetext) thetext = re.sub(r"</" + lip_tag + str(n) + ">", "</" + lip_tag + ">", thetext) # special case of p inside li thetext = re.sub(r"(<li>\n)\n( *<p>)", r"\1\2", thetext) thetext = re.sub(r"(</p>\n)\n( *</li>)", r"\1\2", thetext) # no blank line after ul or before /ul thetext = re.sub(r"(<(ul|ol|dl)(>| [^>]+>)\n)\n", r"\1", thetext) thetext = re.sub(r"\n(\n *</(ul|ol|dl)>)", r"\1", thetext) # special case of punctuation after a closing display math tag thetext = re.sub(r"(</(me|men)>)\s*((\?|!|;|:|,|\.)+) *?", r"\1\3", thetext) # and punctuation after /line thetext = re.sub(r"(</line>)\s*((\?|!|;|:|,|\.|\)|</)+) *?", r"\1\2", thetext) # print thetext return thetext