コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
ファイル: transforms.py プロジェクト: Pelonza/LaTeXtoLaTeX
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
コード例 #4
0
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
コード例 #5
0
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
コード例 #6
0
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