📄 docfixer.py
字号:
parent.normalize() children = parent.childNodes if children[-1].nodeType == TEXT: children[-1].data = string.rstrip(children[-1].data)def fixup_trailing_whitespace(doc, wsmap): queue = [doc] while queue: node = queue[0] del queue[0] if wsmap.has_key(node.get_nodeName()): ws = wsmap[node.get_tagName()] children = node.childNodes children.reverse() if children[0].nodeType == TEXT: data = string.rstrip(children[0].data) + ws children[0].data = data children.reverse() # hack to get the title in place: if node.get_tagName() == "title" \ and node.parentNode.firstChild.get_nodeType() == ELEMENT: node.parentNode.insertBefore(doc.createText("\n "), node.parentNode.firstChild) for child in node.childNodes: if child.nodeType == ELEMENT: queue.append(child)def normalize(doc): for node in doc.childNodes: if node.nodeType == ELEMENT: node.normalize()def cleanup_trailing_parens(doc, element_names): d = {} for gi in element_names: d[gi] = gi rewrite_element = d.has_key queue = [] for node in doc.childNodes: if node.nodeType == ELEMENT: queue.append(node) while queue: node = queue[0] del queue[0] if rewrite_element(node.get_tagName()): children = node.childNodes if len(children) == 1 \ and children[0].nodeType == TEXT: data = children[0].data if data[-2:] == "()": children[0].data = data[:-2] else: for child in node.childNodes: if child.nodeType == ELEMENT: queue.append(child)def contents_match(left, right): left_children = left.childNodes right_children = right.childNodes if len(left_children) != len(right_children): return 0 for l, r in map(None, left_children, right_children): nodeType = l.nodeType if nodeType != r.nodeType: return 0 if nodeType == ELEMENT: if l.get_tagName() != r.get_tagName(): return 0 # should check attributes, but that's not a problem here if not contents_match(l, r): return 0 elif nodeType == TEXT: if l.data != r.data: return 0 else: # not quite right, but good enough return 0 return 1def create_module_info(doc, section): # Heavy. node = extract_first_element(section, "modulesynopsis") if node is None: return node._node.name = "synopsis" lastchild = node.childNodes[-1] if lastchild.nodeType == TEXT \ and lastchild.data[-1:] == ".": lastchild.data = lastchild.data[:-1] modauthor = extract_first_element(section, "moduleauthor") if modauthor: modauthor._node.name = "author" modauthor.appendChild(doc.createTextNode( modauthor.getAttribute("name"))) modauthor.removeAttribute("name") platform = extract_first_element(section, "platform") if section.get_tagName() == "section": modinfo_pos = 2 modinfo = doc.createElement("moduleinfo") moddecl = extract_first_element(section, "declaremodule") name = None if moddecl: modinfo.appendChild(doc.createTextNode("\n ")) name = moddecl.attributes["name"].value namenode = doc.createElement("name") namenode.appendChild(doc.createTextNode(name)) modinfo.appendChild(namenode) type = moddecl.attributes.get("type") if type: type = type.value modinfo.appendChild(doc.createTextNode("\n ")) typenode = doc.createElement("type") typenode.appendChild(doc.createTextNode(type)) modinfo.appendChild(typenode) versionadded = extract_first_element(section, "versionadded") if versionadded: modinfo.setAttribute("added", versionadded.getAttribute("version")) title = get_first_element(section, "title") if title: children = title.childNodes if len(children) >= 2 \ and children[0].get_nodeName() == "module" \ and children[0].childNodes[0].data == name: # this is it; morph the <title> into <short-synopsis> first_data = children[1] if first_data.data[:4] == " ---": first_data.data = string.lstrip(first_data.data[4:]) title._node.name = "short-synopsis" if children[-1].nodeType == TEXT \ and children[-1].data[-1:] == ".": children[-1].data = children[-1].data[:-1] section.removeChild(title) section.removeChild(section.childNodes[0]) title.removeChild(children[0]) modinfo_pos = 0 else: ewrite("module name in title doesn't match" " <declaremodule/>; no <short-synopsis/>\n") else: ewrite("Unexpected condition: <section/> without <title/>\n") modinfo.appendChild(doc.createTextNode("\n ")) modinfo.appendChild(node) if title and not contents_match(title, node): # The short synopsis is actually different, # and needs to be stored: modinfo.appendChild(doc.createTextNode("\n ")) modinfo.appendChild(title) if modauthor: modinfo.appendChild(doc.createTextNode("\n ")) modinfo.appendChild(modauthor) if platform: modinfo.appendChild(doc.createTextNode("\n ")) modinfo.appendChild(platform) modinfo.appendChild(doc.createTextNode("\n ")) section.insertBefore(modinfo, section.childNodes[modinfo_pos]) section.insertBefore(doc.createTextNode("\n "), modinfo) # # The rest of this removes extra newlines from where we cut out # a lot of elements. A lot of code for minimal value, but keeps # keeps the generated *ML from being too funny looking. # section.normalize() children = section.childNodes for i in range(len(children)): node = children[i] if node.get_nodeName() == "moduleinfo": nextnode = children[i+1] if nextnode.nodeType == TEXT: data = nextnode.data if len(string.lstrip(data)) < (len(data) - 4): nextnode.data = "\n\n\n" + string.lstrip(data)def cleanup_synopses(doc, fragment): for node in find_all_elements(fragment, "section"): create_module_info(doc, node)def fixup_table_structures(doc, fragment): for table in find_all_elements(fragment, "table"): fixup_table(doc, table)def fixup_table(doc, table): # create the table head thead = doc.createElement("thead") row = doc.createElement("row") move_elements_by_name(doc, table, row, "entry") thead.appendChild(doc.createTextNode("\n ")) thead.appendChild(row) thead.appendChild(doc.createTextNode("\n ")) # create the table body tbody = doc.createElement("tbody") prev_row = None last_was_hline = 0 children = table.childNodes for child in children: if child.nodeType == ELEMENT: tagName = child.get_tagName() if tagName == "hline" and prev_row is not None: prev_row.setAttribute("rowsep", "1") elif tagName == "row": prev_row = child # save the rows: tbody.appendChild(doc.createTextNode("\n ")) move_elements_by_name(doc, table, tbody, "row", sep="\n ") # and toss the rest: while children: child = children[0] nodeType = child.nodeType if nodeType == TEXT: if string.strip(child.data): raise ConversionError("unexpected free data in table") table.removeChild(child) continue if nodeType == ELEMENT: if child.get_tagName() != "hline": raise ConversionError( "unexpected <%s> in table" % child.get_tagName()) table.removeChild(child) continue raise ConversionError( "unexpected %s node in table" % child.__class__.__name__) # nothing left in the <table>; add the <thead> and <tbody> tgroup = doc.createElement("tgroup") tgroup.appendChild(doc.createTextNode("\n ")) tgroup.appendChild(thead) tgroup.appendChild(doc.createTextNode("\n ")) tgroup.appendChild(tbody) tgroup.appendChild(doc.createTextNode("\n ")) table.appendChild(tgroup) # now make the <entry>s look nice: for row in table.getElementsByTagName("row"): fixup_row(doc, row)def fixup_row(doc, row): entries = [] map(entries.append, row.childNodes[1:]) for entry in entries: row.insertBefore(doc.createTextNode("\n "), entry)# row.appendChild(doc.createTextNode("\n "))def move_elements_by_name(doc, source, dest, name, sep=None): nodes = [] for child in source.childNodes: if child.get_nodeName() == name: nodes.append(child) for node in nodes: source.removeChild(node) dest.appendChild(node) if sep: dest.appendChild(doc.createTextNode(sep))RECURSE_INTO_PARA_CONTAINERS = ( "chapter", "abstract", "enumerate", "section", "subsection", "subsubsection", "paragraph", "subparagraph", "back-matter", "howto", "manual", "item", "itemize", "fulllineitems", "enumeration", "descriptionlist", "definitionlist", "definition", )PARA_LEVEL_ELEMENTS = ( "moduleinfo", "title", "verbatim", "enumerate", "item", "interpreter-session", "back-matter", "interactive-session", "opcodedesc", "classdesc", "datadesc", "funcdesc", "methoddesc", "excdesc", "memberdesc", "membderdescni", "funcdescni", "methoddescni", "excdescni", "tableii", "tableiii", "tableiv", "localmoduletable", "sectionauthor", "seealso", "itemize", # include <para>, so we can just do it again to get subsequent paras: PARA_ELEMENT, )PARA_LEVEL_PRECEEDERS = ( "setindexsubitem", "stindex", "obindex", "COMMENT", "label", "input", "title", "versionadded", "versionchanged", "declaremodule", "modulesynopsis", "moduleauthor", "indexterm", "leader", )def fixup_paras(doc, fragment): for child in fragment.childNodes: if child.get_nodeName() in RECURSE_INTO_PARA_CONTAINERS: fixup_paras_helper(doc, child) descriptions = find_all_elements(fragment, "description") for description in descriptions: fixup_paras_helper(doc, description)def fixup_paras_helper(doc, container, depth=0): # document is already normalized children = container.childNodes start = skip_leading_nodes(children) while len(children) > start: if children[start].get_nodeName() in RECURSE_INTO_PARA_CONTAINERS: # Something to recurse into: fixup_paras_helper(doc, children[start]) else: # Paragraph material: build_para(doc, container, start, len(children)) if DEBUG_PARA_FIXER and depth == 10: sys.exit(1) start = skip_leading_nodes(children, start + 1)def build_para(doc, parent, start, i): children = parent.childNodes after = start + 1 have_last = 0 BREAK_ELEMENTS = PARA_LEVEL_ELEMENTS + RECURSE_INTO_PARA_CONTAINERS # Collect all children until \n\n+ is found in a text node or a # member of BREAK_ELEMENTS is found. for j in range(start, i): after = j + 1 child = children[j] nodeType = child.nodeType if nodeType == ELEMENT: if child.get_tagName() in BREAK_ELEMENTS: after = j break elif nodeType == TEXT: pos = string.find(child.data, "\n\n") if pos == 0: after = j break if pos >= 1: child.splitText(pos) break else: have_last = 1 if (start + 1) > after: raise ConversionError( "build_para() could not identify content to turn into a paragraph") if children[after - 1].nodeType == TEXT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -