def parse(self, encoding=None, errors="strict", **kwargs): """ Return the contents of toolbox settings file with a nested structure. :param encoding: encoding used by settings file :type encoding: str :param errors: Error handling scheme for codec. Same as ``decode()`` builtin method. :type errors: str :param kwargs: Keyword arguments passed to ``StandardFormat.fields()`` :type kwargs: dict :rtype: ElementTree._ElementInterface """ builder = TreeBuilder() for mkr, value in self.fields(encoding=encoding, errors=errors, **kwargs): # Check whether the first char of the field marker # indicates a block start (+) or end (-) block = mkr[0] if block in ("+", "-"): mkr = mkr[1:] else: block = None # Build tree on the basis of block char if block == "+": builder.start(mkr, {}) builder.data(value) elif block == "-": builder.end(mkr) else: builder.start(mkr, {}) builder.data(value) builder.end(mkr) return builder.close()
def __init__(self, filename): """ Opens file the parser needs to read from """ self.filename = filename.replace(".jack", "") try: inFile = open(filename, 'r') self.code = inFile.read() inFile.close() except IOError: print "Unable to open input file." exit(-2) # Setup the Element Tree builder = TreeBuilder() builder.start("tokens", {}) builder.data("\n") self.etree = ElementTree(builder.end("tokens")) # Remove Comments self.removeComments() # Strip self.code = str.strip(self.code) # Set up enum of token types self.KEYWORDS = '(class)|(constructor)|(function)|(method)|(field)|(static)|(var)|(int)|(char)|(boolean)|(void)|(true)|(false)|(null)|(this)|(let)|(do)|(if)|(else)|(while)|(return)' self.SYMBOLS = '[(\{)|(\})|(\()|(\))|(\[)|(\])|(\.)|(,)|(;)|(\+)|(\-)|(\*)|(\/)|(&)|(|)|(<)|(>)|(=)|(~)]' # Set up token as blank self.token = 'null' self.tokenType = 'NULL'
def build(self, root=None): if root is None: root = TreeBuilder() root.start("html", {}) root.start("head", {}) if self.title: root.start("title", {}) root.data(self.title) root.end("title") for meta in self._metas: root.start("meta", meta) root.end("meta") for style in self._stylesheets: root.start("link", { "rel": "stylesheet", "href": style, "type": "text/css" }) root.end("link") for script in self._scripts: root.start("script", { "type": "text/javascript", "src": script }) root.data(" ") root.end('script') root.end("head") super(Document, self).build(root=root) root.end("html") root = root.close() return "<!DOCTYPE html>\n%s" % str( tostring(root, method="html").decode('utf-8'))
def compileClass(self): """ Compiles a complete class """ if (self.DEBUG): print "Compiling class" # Add non-terminal break for the class builder = TreeBuilder() builder.start("class", {}) builder.data("\n") self.etree = ElementTree(builder.end("class")) self.head.append(self.etree.getroot()) # Check for class keyword self.validateAndRead("keyword", "class") # Check for identifier self.validateAndRead("identifier") # Check for { symbol self.validateAndRead("symbol", '{') # Check for Class Vars while (self.compileClassVarDec()): """ BLANK ON PURPOSE!!! """ # Check for Subroutines while (self.compileSubroutine()): """ BLANK ON PURPOSE!!! """ # Check for } symbol self.validateAndRead("symbol", '}')
def parse(self, encoding=None, errors='strict', **kwargs): """ Return the contents of toolbox settings file with a nested structure. :param encoding: encoding used by settings file :type encoding: str :param errors: Error handling scheme for codec. Same as ``decode()`` builtin method. :type errors: str :param kwargs: Keyword arguments passed to ``StandardFormat.fields()`` :type kwargs: dict :rtype: ElementTree._ElementInterface """ builder = TreeBuilder() for mkr, value in self.fields(encoding=encoding, errors=errors, **kwargs): # Check whether the first char of the field marker # indicates a block start (+) or end (-) block=mkr[0] if block in ("+", "-"): mkr=mkr[1:] else: block=None # Build tree on the basis of block char if block == "+": builder.start(mkr, {}) builder.data(value) elif block == '-': builder.end(mkr) else: builder.start(mkr, {}) builder.data(value) builder.end(mkr) return builder.close()
def build(self, root=None): if root is None: was_root = True root = TreeBuilder() else: was_root = False root.start(self.tagname(), self.attrs()) for i, child in enumerate(self.children): if isinstance(child, HTMLBuilder): child.build(root=root) else: if i in self._formatted: try: proxy = TreeProxy(root) parser = XMLParser(html=True, target=proxy) parser.feed(child) proxy.cleanup() except Exception as e: print("Bad formatting", e) root.data(str(child)) else: root.data(str(child)) root.end(self.tagname()) if was_root: root = root.close() return str(tostring(root, method="html").decode('utf-8'))
def message(self): builder = TreeBuilder() builder.start(self.resource_type, dict()) self.serialize(builder) builder.end(self.resource_type) msg = tostring(builder.close()) return msg
def emit(output, title_string, structure): "Write an SVG file to output representing structure." global builder builder = TreeBuilder() builder.start("svg", dict(xmlns="http://www.w3.org/2000/svg", width=str(width), height=str(height))) title(title_string) structure.depth(3) for key, depth in [(3, 3), (1, 5), (2, 6), (1, 10), (1, 11), (2, 15), (3, 16), (1, 22), (2, 25), (1, 25), ]: structure.key(key, depth) builder.end("svg") ElementTree(builder.close()).write(output, encoding='utf-8', xml_declaration=True) output.write("\n")
class XmppXmlHandler(object): STREAM_TAG='{http://etherx.jabber.org/streams}stream' def __init__(self): self._stack = 0 self._builder = TreeBuilder() self._results = deque() def data(self, data): self._builder.data(data) def start(self, tag, attrib): if tag == self.STREAM_TAG: return self._builder.start(tag, attrib) self._stack += 1 def end(self, tag): self._stack -= 1 elem = self._builder.end(tag) if self._stack == 0: self._results.append(elem) def get_elem(self): """If a top-level XML element has been completed since the last call to get_elem, return it; else return None.""" try: return self._results.popleft() except IndexError: return None
def emit(output, title_string, structure): "Write an SVG file to output representing structure." global builder builder = TreeBuilder() builder.start( "svg", dict(xmlns="http://www.w3.org/2000/svg", width=str(width), height=str(height))) title(title_string) structure.depth(3) for key, depth in [ (3, 3), (1, 5), (2, 6), (1, 10), (1, 11), (2, 15), (3, 16), (1, 22), (2, 25), (1, 25), ]: structure.key(key, depth) builder.end("svg") ElementTree(builder.close()).write(output, encoding='utf-8', xml_declaration=True) output.write("\n")
def _render_holes(svg: TreeBuilder, layer: Layer) -> None: # Sort the holes left to right then up and down to avoid any pathological # movement of the cutting head. holes = sorted(layer.holes(), key=lambda hole: tuple(hole.position)) for hole in holes: if layer.connected(hole.position): continue transformation = Transformation(offset=hole.position, scale=layer.grid, rotation=R0) x, y = transformation.transform_point((0, 0)) r = transformation.transform_distance(hole.radius) path = PathBuilder() path.move_to(x, y + r) path.arc_to(x + r, y, rx=r, ry=r) path.arc_to(x, y - r, rx=r, ry=r) path.arc_to(x - r, y, rx=r, ry=r) path.arc_to(x, y + r, rx=r, ry=r) path.close_path() # TODO path = path.close() svg.start( "path", { "d": str(path), "stroke": "red", "stroke-width": "0.25", "fill": "none", }) svg.end("path")
def write_xml_file(f, taxes): """ Export an XML file for the given taxonomies to the (open) file handle specified. """ x = TreeBuilder() x.start("taxonomy", {}) def f_pre(term): x.start("category", {"id": str(term.uid)}) x.start("name", {}) x.data(term.name) x.end("name") for clue, positive in term.iter_clues(): attrs = {} if not positive: attrs["negative"] = True x.start("clue", attrs) x.data(clue) x.end("clue") def f_post(term): x.end("category") for term in taxes: term.walk(f_pre, f_post) x.end("taxonomy") xml = ElementTree(x.close()) xml.write(f, xml_declaration=True, encoding="utf-8")
def write_output(*, output_path, content): tree_builder = TreeBuilder() root = tree_builder.start("testsuites", {}) root_failures = 0 for (path, hunks) in content.items(): path_el = tree_builder.start("testsuite", {"name": path}) path_failures = 0 for hunk in hunks: tree_builder.start( "testcase", { "name": f"{path}.path_failures", "classname": path }, ) fail_el = tree_builder.start("failure", {}) fail_el.text = hunk root_failures += 1 path_failures += 1 tree_builder.end("failure") tree_builder.end("testcase") path_el.set("tests", str(path_failures)) path_el.set("failures", str(path_failures)) tree_builder.end("testsuite") root.set("tests", str(root_failures)) root.set("failures", str(root_failures)) tree_builder.end("testsuites") xml_tree = ElementTree(tree_builder.close()) if output_path: with open(output_path, "w+") as out: xml_tree.write(out, encoding="unicode") else: xml_tree.write(sys.stdout, encoding="unicode")
def __init__(self, filename): """ Opens file the parser needs to read from """ self.filename = filename.replace(".jack", "") try: inFile = open(filename, 'r') self.code = inFile.read() inFile.close() except IOError: print "Unable to open input file." exit(-2) # Setup the Element Tree builder = TreeBuilder() builder.start("tokens", {}) builder.data("\n") self.etree = ElementTree(builder.end("tokens")) # Remove Comments self.removeComments() # Strip self.code = str.strip(self.code) # Set up enum of token types self.KEYWORDS = r'(\Aclass\b)|(\Aconstructor\b)|(\Afunction\b)|(\Amethod\b)|(\Afield\b)|(\Astatic\b)|(\Avar\b)|(\Aint\b)|(\Achar\b)|(\Aboolean\b)|(\Avoid\b)|(\Atrue\b)|(\Afalse\b)|(\Anull\b)|(\Athis\b)|(\Alet\b)|(\Ado\b)|(\Aif\b)|(\Aelse\b)|(\Awhile\b)|(\Areturn\b)' self.SYMBOLS = '[(\{)|(\})|(\()|(\))|(\[)|(\])|(\.)|(,)|(;)|(\+)|(\-)|(\*)|(\/)|(&)|(|)|(<)|(>)|(=)|(~)]' # Set up token as blank self.token = 'null' self.tokenType = 'NULL'
def _elem(parent: Element, tag: str, data: Optional[str] = None) -> Element: b = TreeBuilder() b.start(tag, {}) # types: ignore if data: b.data(data) ret = b.end(tag) parent.append(ret) return ret
def addTerminal(self): """ Adds a terminal element to the XML tree """ builder = TreeBuilder() builder.start(self.tag, {}) builder.data(" %s " % (self.data)) temp = builder.end(self.tag) temp.tail = "\n" self.head[-1].append(temp)
def coverageview_store_info(builder: TreeBuilder, data: dict, name='store'): # if 'classname' in data.items(): if data.get('classname'): builder.start(name, {'class': data.get('classname')}) builder.start('name') builder.data(data.get('name', None)) builder.end('name') builder.end(name) pass
def write(builder: TreeBuilder, metadata: dict) -> None: builder.start(name, dict()) # 遍历传入的字典 for k, v in metadata.items(): builder.start("entry", dict(key=k)) if k == "COVERAGE_VIEW": # 需要创建 coverageView coverageview_xml(builder, v) pass
def addNonTerminal(self, name): """ Adds a non-terminal element to the XML tree """ builder = TreeBuilder() builder.start(name, {}) builder.data("\n") temp = builder.end(name) temp.tail = "\n" self.head[-1].append(temp) self.head.append(temp)
def addElement(self, tag): """ Adds the current token to the XML ElementTree """ e = self.etree.getroot() builder = TreeBuilder() builder.start(tag, {}) builder.data(" %s " % (self.token)) temp = builder.end(tag) temp.tail = "\n" e.append(temp) return self.token
def save(self): '''saves action to file''' builder = TreeBuilder() builder.start("action", { "id" : str(self.id), "type" : str(self.type) }) builder.start("name", {}) builder.data(self.name) builder.end("name") self._write_type(builder) builder.end("action") doc = ElementTree(builder.close()) doc.write(self.get_file(self.id))
def info_xml(): builder = TreeBuilder() builder.start('root', dict()) builder.data('ceshi') builder.start('child', dict()) builder.data('child_1_data') builder.end('child') builder.end('root') return builder # msg= tostring(builder.close(),encoding='utf-8',method='xml') # print(msg) pass
def _get_new_album_body(self, title): ''' Формирует XML-элемент для нового альбома. @param title: string @return Element ''' builder = TreeBuilder(Element) builder.start('entry', {'xmlns': ATOM_NS}) builder.start('title', {}) builder.data(title.decode('utf8')) builder.end('title') builder.end('entry') node = builder.close() return tostring(node)
class _XHTMLParser(parser.HTMLParser): # A helper class for parsing XHTML into an xml.etree.ElementTree def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.builder = TreeBuilder(element_factory=Element) def handle_starttag(self, tag, attrs): self.builder.start(tag, dict(attrs),) def handle_endtag(self, tag): self.builder.end(tag) def handle_data(self, data): self.builder.data(data)
def message(self): ''' # TODO:[-] 20-03-13 在ResourceInfo中定义的方法,最终返回的是需要提交的msg * 由于ResourceInfo是需要由子类继承的,所以self就是继承的子类 eg: UnsavedCoverageStore message 为 TreeBuilder 创建的 Element -> str ''' builder = TreeBuilder() # 创建了一个 resource_type(每个子类会声明这个类变量) 的 treebuilder builder.start(self.resource_type, dict()) self.serialize(builder) builder.end(self.resource_type) # b'<coverageStore><enabled>true</enabled><name>nmefc_2016072112_opdr_02</name><url>file:nmefc/waterwind/nmefc_2016072112_opdr.nc</url><type>NetCDF</type><workspace>my_test_2</workspace></coverageStore>' msg = tostring(builder.close()) return msg
def parse(self, list_of_docs): builder = TreeBuilder() builder.start('corpus') for i, doc in enumerate(list_of_docs): attrib = {} attrib['id'] = str(i) attrib['len'] = str(len(doc)) builder.start('tok', attrib) builder.data(doc) builder.end('tok') builder.end('corpus') return builder.close()
def write_xml(f, taxes, _solr=None, rows=0): """ Export an XML file for the given taxonomies to the (open) file handle specified. If a SOLR connection is supplied, then include document elements for each category. """ x = TreeBuilder() x.start("taxonomy", {}) def f_pre(term): x.start("category", { "id": str(term.uid) }) x.start("name", {}) x.data(term.name) x.end("name") for clue, positive in term.iter_clues(): attrs = {} if not positive: attrs["negative"] = 'true' x.start("clue", attrs) x.data(clue) x.end("clue") if _solr is not None: count, docs = get_docs_for_category(_solr, term, rows=rows) x.start("count", {}) x.data(str(count)) x.end("count") for doc_id, title, score in docs: x.start("doc", { "id": doc_id, "score": str(score) }) x.start("name", {}) x.data(title) x.end("name") x.end("doc") def f_post(term): x.end("category") for term in taxes: term.walk(f_pre, f_post) x.end("taxonomy") xml = ElementTree(x.close()) xml.write(f, xml_declaration=True, encoding="utf-8")
def write_xml(f, taxes, _solr=None, rows=0): """ Export an XML file for the given taxonomies to the (open) file handle specified. If a SOLR connection is supplied, then include document elements for each category. """ x = TreeBuilder() x.start("taxonomy", {}) def f_pre(term): x.start("category", {"id": str(term.uid)}) x.start("name", {}) x.data(term.name) x.end("name") for clue, positive in term.iter_clues(): attrs = {} if not positive: attrs["negative"] = "true" x.start("clue", attrs) x.data(clue) x.end("clue") if _solr is not None: count, docs = get_docs_for_category(_solr, term, rows=rows) x.start("count", {}) x.data(str(count)) x.end("count") for doc_id, title, score in docs: x.start("doc", {"id": doc_id, "score": str(score)}) x.start("name", {}) x.data(title) x.end("name") x.end("doc") def f_post(term): x.end("category") for term in taxes: term.walk(f_pre, f_post) x.end("taxonomy") xml = ElementTree(x.close()) xml.write(f, xml_declaration=True, encoding="utf-8")
def start(self, tag, attrs): elem = TreeBuilder.start(self, tag, attrs) for key, value in attrs.items(): if key == _MELD_ID: if value in self.meldids: raise ValueError('Repeated meld id "%s" in source' % value) self.meldids[value] = 1 break return elem
def _render_outline(svg: TreeBuilder, layer: Layer) -> None: w = layer.width * layer.grid h = layer.height * layer.grid path = PathBuilder() path.move_to(0, 0) path.line_to(w, 0) path.line_to(w, h) path.line_to(0, h) path.close_path() path = path.close() svg.start("path", { "d": str(path), "stroke": "red", "stroke-width": "0.25", "fill": "none", }) svg.end("path")
def generate_disk(disk, devicename): """ Creates XML representation of disk for libvirt based on disk_definition disk_definition is something like { 'type': 'network', 'device': 'disk', 'format': 'raw', 'source': { 'protocol': 'sheepdog', 'name': 'Alice', 'hosts': [('127.0.0.1', '7000'),], }, } or { 'type': 'file', 'device': 'disk', 'format': 'qcow2', 'source': { 'file': '/var/lib/libvirt/images/Alice.img', }, }, devicename is string representing devicename (eg. vda, vdb, ...) """ builder = TreeBuilder() builder.start('disk', {'type': disk['type'], 'device': disk['device']}) builder.start('source', sans(disk['source'], 'hosts')) for host in disk['source'].get('hosts', []): builder.start('host', {'name': host[0], 'port': host[1]}) builder.end('host') builder.end('source') builder.start('target', {'dev': devicename, 'bus': 'virtio'}) builder.end('target') builder.start('driver', {'name': 'qemu', 'cache': 'none', 'type': disk['format']}) builder.end('driver') builder.end('disk') return builder.close()
def data2builder(data, tag_name="data", builder=None): """pass in a python data structure and get back a etree TreeBuilder """ if builder == None: builder = TreeBuilder() t = type(data) if t == NoneType: builder.start(tag_name, {}) builder.end(tag_name) elif t in (StringType, UnicodeType, IntType, FloatType, BooleanType, LongType): builder.start(tag_name, {}) builder.data(unicode(data)) builder.end(tag_name) elif t in (ListType, TupleType): for value in data: data2builder(value, tag_name=tag_name, builder=builder) elif t == DictionaryType: builder.start(tag_name, {}) for key, value in data.items(): data2builder(value, tag_name=key, builder=builder) builder.end(tag_name) else: raise Exception("uhoh I can't handle type %s" % t) return builder
def generate_nic(network): builder = TreeBuilder() builder.start('interface', {'type': network['type']}) builder.start('mac', {'address': network['mac']}) builder.end('mac') builder.start('source', network['source']) builder.end('source') builder.start('model', {'type':'virtio'}) builder.end('model') builder.end('interface') return builder.close() # vim:set sw=4 ts=4 et: # -*- coding: utf-8 -*-
def _element_from_list(sexpr, builder: ET.TreeBuilder): assert len(sexpr) tag, *rest = sexpr attributes = {} if len(rest) and isinstance(rest[0], dict): attributes, *rest = rest element = builder.start(tag, attributes) for child in rest: child_element = _element_from_sexpr(child, builder) if child_element is not None: element.append(child_element) builder.end(tag)
class XmppXmlHandler(object): STREAM_TAG = '{http://etherx.jabber.org/streams}stream' def __init__(self): self._stack = 0 self._builder = TreeBuilder() self._builder.start('root', {}) self._results = deque() def data(self, data): self._builder.data(data) def start(self, tag, attrib): if tag == self.STREAM_TAG: return self._builder.start(tag, attrib) self._stack += 1 def end(self, tag): self._stack -= 1 elem = self._builder.end(tag) if self._stack == 0: self._results.append(elem) def get_elem(self): """If a top-level XML element has been completed since the last call to get_elem, return it; else return None.""" try: elem = self._results.popleft() if elem.tag.endswith('failure') or elem.tag.endswith('error'): raise Exception("XMPP Error received - %s" % elem.tag) return elem except IndexError: return None
def covreageview_dimensions_info(builder: TreeBuilder, data: dict, name: str = None): ''' TODO:[-] + 创建 namespace coverage stores -> data -> coverage -> [+] dimensions ''' # 将 dict -> dimensions 数组 if isinstance(data, dict): if name is not None: builder.start(name) for k, v in data.items(): if 'coveragedimension' in k.lower(): # 是一个数组 builder.start('coverageDimension') if isinstance(v, CoverageDimensionMidModel): coverageDimension_info(builder, v) builder.end('coverageDimension') # for item in data.get('dimensions'): if name is not None: builder.end(name) pass
def build(self, root=None): if root is None: root = TreeBuilder() root.start("html", {}) root.start("head", {}) if self.title: root.start("title", {}) root.data(self.title) root.end("title") for meta in self._metas: root.start("meta", meta) root.end("meta") for style in self._stylesheets: root.start("link", {"rel": "stylesheet", "href": style, "type": "text/css"}) root.end("link") for script in self._scripts: root.start("script", {"type": "text/javascript", "src": script}) root.data(" ") root.end('script') root.end("head") super(Document, self).build(root=root) root.end("html") root = root.close() return "<!DOCTYPE html>\n%s" % str(tostring(root, method="html").decode('utf-8'))
def save_xml(data, filename): tb = TreeBuilder() studyguide = tb.start("studyguide", {}) for dataQuestion in data: xmlQuestion = SubElement(studyguide, "question", {}) xmlQuestion.text = dataQuestion[0] for dataAnswer in dataQuestion[1]: if dataAnswer == dataQuestion[1][0]: xmlAnswer = SubElement(xmlQuestion, "answer", {'correct': "true"}) else : xmlAnswer = SubElement(xmlQuestion, "answer", {'correct':"false"}) xmlAnswer.text = dataAnswer #dump(studyguide) ElementTree(studyguide).write("xml/" + filename)
def coverageview_namespace_info(builder: TreeBuilder, info: dict, name: str = None): ''' TODO:[-] + 创建 namespace coverage stores -> data -> coverage -> [+] namespace ''' if isinstance(info, dict): if name is not None: builder.start(name) for k, v in info.items(): if k.lower() == 'name': builder.start(k) builder.data(v) builder.end(k) elif k.lower() == 'atom': builder.start(k) builder.data(v) builder.end(k) if name is not None: builder.end(name)
def getGPX(self, fileName): gpx = TreeBuilder() # GPX tag gpx.start( "gpx", { "version": "1.2", "creator": "NikePlus", "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "xmlns": "http://www.topografix.com/GPX/1/2/", "xsi:schemaLocation": "http://www.topografix.com/GPX/1/2/ http://www.topografix.com/gpx/1/2/gpx.xsd", }, ) # Metadata gpx.start("metadata", {}) # Meta Name gpx.start("name", {}) gpx.data("Run " + self._runId) gpx.end("name") # Bounds minLat = min([point.lat for point in self._trackPointList]) maxLat = max([point.lat for point in self._trackPointList]) minLon = min([point.lon for point in self._trackPointList]) maxLon = max([point.lon for point in self._trackPointList]) extents = {"minLat": str(minLat), "maxLat": str(maxLat), "minLon": str(minLon), "maxLon": str(maxLon)} gpx.start("bounds", extents) gpx.end("bounds") # Metadata close gpx.end("metadata") # Track gpx.start("trk", {}) # Track Name gpx.start("name", {}) gpx.data(str(self._runId)) gpx.end("name") # Track Type gpx.start("type", {}) gpx.data("Run") gpx.end("type") gpx.start("trkseg", {}) for point in self._trackPointList: gpx.start("trkpt", {"lat": str(point.lat), "lon": str(point.lon)}) gpx.start("ele", {}) gpx.data(str(point.altitudeMeters)) gpx.end("ele") gpx.start("time", {}) gpx.data(point.time.strftime("%Y-%m-%dT%H:%M:%SZ")) gpx.end("time") gpx.end("trkpt") gpx.end("trkseg") gpx.end("trk") gpx.end("gpx") gpxFile = ElementTree(gpx.close()) gpxFile.write(open(fileName, "wb"), "utf-8")
def serialize(self): builder = TreeBuilder() builder.start(self.resource_type, dict()) self.encode(builder) builder.end(self.resource_type) return tostring(builder.close())
def scheme_to_etree(scheme, data_format="literal", pickle_fallback=False): """ Return an `xml.etree.ElementTree` representation of the `scheme. """ builder = TreeBuilder(element_factory=Element) builder.start("scheme", {"version": "2.0", "title": scheme.title or "", "description": scheme.description or ""}) ## Nodes node_ids = defaultdict(inf_range().__next__) builder.start("nodes", {}) for node in scheme.nodes: desc = node.description attrs = {"id": str(node_ids[node]), "name": desc.name, "qualified_name": desc.qualified_name, "project_name": desc.project_name or "", "version": desc.version or "", "title": node.title, } if node.position is not None: attrs["position"] = str(node.position) if type(node) is not SchemeNode: attrs["scheme_node_type"] = "%s.%s" % (type(node).__name__, type(node).__module__) builder.start("node", attrs) builder.end("node") builder.end("nodes") ## Links link_ids = defaultdict(inf_range().__next__) builder.start("links", {}) for link in scheme.links: source = link.source_node sink = link.sink_node source_id = node_ids[source] sink_id = node_ids[sink] attrs = {"id": str(link_ids[link]), "source_node_id": str(source_id), "sink_node_id": str(sink_id), "source_channel": link.source_channel.name, "sink_channel": link.sink_channel.name, "enabled": "true" if link.enabled else "false", } builder.start("link", attrs) builder.end("link") builder.end("links") ## Annotations annotation_ids = defaultdict(inf_range().__next__) builder.start("annotations", {}) for annotation in scheme.annotations: annot_id = annotation_ids[annotation] attrs = {"id": str(annot_id)} data = None if isinstance(annotation, SchemeTextAnnotation): tag = "text" attrs.update({"rect": repr(annotation.rect)}) # Save the font attributes font = annotation.font attrs.update({"font-family": font.get("family", None), "font-size": font.get("size", None)}) attrs = [(key, value) for key, value in attrs.items() if value is not None] attrs = dict((key, str(value)) for key, value in attrs) data = annotation.text elif isinstance(annotation, SchemeArrowAnnotation): tag = "arrow" attrs.update({"start": repr(annotation.start_pos), "end": repr(annotation.end_pos)}) # Save the arrow color try: color = annotation.color attrs.update({"fill": color}) except AttributeError: pass data = None else: log.warning("Can't save %r", annotation) continue builder.start(tag, attrs) if data is not None: builder.data(data) builder.end(tag) builder.end("annotations") builder.start("thumbnail", {}) builder.end("thumbnail") # Node properties/settings builder.start("node_properties", {}) for node in scheme.nodes: data = None if node.properties: try: data, format = dumps(node.properties, format=data_format, pickle_fallback=pickle_fallback) except Exception: log.error("Error serializing properties for node %r", node.title, exc_info=True) if data is not None: builder.start("properties", {"node_id": str(node_ids[node]), "format": format}) builder.data(data) builder.end("properties") builder.end("node_properties") builder.end("scheme") root = builder.close() tree = ElementTree(root) return tree
for sample in samples: if sample in samp: return sample return None args = init_parser().parse_args() samples = args.s samples = samples.split(",") timeout = args.t memory = args.m batch = args.b exe = args.exe builder = TreeBuilder() builder.start("Jobs", {}) #sample = samples[0] for sample in samples: my_env = environ my_env["SAMPLE"] = sample my_env["EXE"] = exe my_env["NAME"] = args.name print "Sending sample", sample command = [ "jobsub_submit", "-N", "5", "-M", "--OS=SL6", "--group=dune", "--memory=" + memory, "--timeout=" + timeout, "--resource-provides=usage_model=OPPORTUNISTIC", "-e", "SAMPLE", "-e", "NAME", "-e", "EXE", "file:///dune/app/users/calcuttj/geant/GeantReweight/subs/" + batch
class WordMLTranslator(nodes.NodeVisitor): """ This WordML writer handles most of the features for now, You can get the gist of it rather easily. It's not nearly as complicated as the HTML writer, surprisingly. """ title_styles = ["Heading1", "Heading2", "Heading3"] xml_spaces = ' ' # these are meant to be default lists, one for bullet and one for enumerated. # other list types should be added here later. def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.document = document self.doc = '' self.body = [] # the body of the document self.in_docinfo = None self.in_sidebar = None self.settings = settings = document.settings self.section_level = 0 self.title_level = 0 self.text_properties = {} # the list of properties for a run of test self.text_prefix = [] # text or commands inserted before next text run self.paragraph_properties = {} self.id = 1000 self.in_footnote = 0 self.no_text = 0 # flag to suppress any text output self.literal_text = 0 # flag to output newlines in text self.skip_encode = 0 # flag to skip the encoding of text to xml friendly output self.has_text_output = 0 # flag if any text output since last reset self.figure_count = 0 self.in_figure = 0 self.indentation = 0 # list related variables self.lists = [] self.list_level = -1 self.list_count = 0 self.list_properties = [] self.list_defs = [] self.template_list_defs = [] self.current_listdef = [] self.in_listdef = 0 self.show_list_properties = 0 self.extract_listdefs() self.substitutions = {} # table related variables self.in_table = 0 self.colspecs = [] self.row = 0 self.col = 0 self.spans = {} # for multispan columns and rows self.total_col_width = 0 # xml output variables self.doc_tree = TreeBuilder() self.doc_tree.start('w:document', {}) self.xml_spacing = 0 def gen_id(self): self.id += 1 return self.id def template_start_element(self, name, attr): if name == 'w:rest': self.doc_tree.end('w:document') tree = self.doc_tree.close() doc_string = tostring(tree) p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.body_start_element p.EndElementHandler = self.body_end_element p.CharacterDataHandler = self.body_data p.Parse(doc_string) # for b in self.body: # self.doc += b elif name == 'w:rstlists': for l in self.lists: self.doc += l elif name == 'w:rstlistdefs': for l in self.list_defs: self.doc += l else: self.doc += "<" + name + " " for k, v in attr.iteritems(): self.doc += k + '="' + v + '" ' self.doc += ">" def template_end_element(self, name): if name == 'w:rest' or name == 'w:rstlists' or name == 'w:rstlistdefs': pass else: self.doc += '</' + name + '>' def template_char_data(self, data): self.doc += data # routines for extracting the listdef elements from the template def start_listdef_extract(self, name, attr): if name == 'w:listDef': self.in_listdef = 1 self.current_listdef = [] if name == 'w:lsid': return if self.in_listdef == 1: self.current_listdef.append([name, attr]) def end_listdef_extract(self, name): self.current_listdef.append(["/" + name]) if name == 'w:listDef': self.template_list_defs.append(self.current_listdef) self.in_listdef = 0 if name == 'w:lsid': return def list_def_data(self, data): pass def extract_listdefs(self): p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.start_listdef_extract p.EndElementHandler = self.end_listdef_extract p.CharacterDataHandler = self.list_def_data template = file(self.document.settings.template) p.ParseFile(template) def listdef_to_xml(self, list_number, level, start, nfc): """Modify a listdef to include an alternate numbering scheme and new starting number. Then convert it to XML and return the XML string.""" xml = '' lvl = -1000 for x in self.template_list_defs[list_number]: # change the listDefId to match the new list if x[0] == 'w:listDef': x[1]['w:listDefId'] = str(self.list_count + 1) # get the level if it has changed if x[0] == 'w:lvl': lvl = int(x[1]['w:ilvl']) # skip an existing nfc node if (x[0] == 'w:nfc' or x[0] == '/w:nfc') and level == lvl: continue xml += '<' + x[0] + ' ' if len(x) == 2: for k, v in x[1].iteritems(): if x[0] == 'w:start' and k == 'w:val' and lvl == level: xml += k + '="' + str(start) + '" ' else: xml += k + '="' + v + '" ' xml += '>\n' # add in our nfc node right after the start node if x[0] == '/w:start' and level == lvl: xml += '<w:nfc w:val="' + str(nfc) + '" />\n' return xml def body_start_element(self, name, attr): if name == 'w:document': return element = self.xml_spaces[0:self.xml_spacing] + "<" + name + " " for k, v in attr.iteritems(): element += k + '="' + v + '" ' element = element[:-1] element += ">" if name != 'w:t': element += '\n' self.xml_spacing += 2 self.doc += element def body_end_element(self, name): if name == 'w:document': return self.xml_spacing -= 2 element = '' if name != 'w:t': element += self.xml_spaces[0:self.xml_spacing] element += '</' + name + '>\n' self.doc += element def body_data(self, data): self.doc += data def check_for_span(self, col, row): check_span = '{' + str(col) + ',' + str(row) + '}' if self.spans.has_key(check_span): self.doc_tree.start('w:tc', {}) self.doc_tree.start('w:tcPr', {}) self.doc_tree.start('w:tcW', { 'w': str(self.calc_col_pct(self.col)), 'w:type': 'pct' }) self.doc_tree.start(self.spans[check_span][0], self.spans[check_span][1]) self.doc_tree.end(self.spans[check_span][0]) self.doc_tree.end('w:tcW') self.doc_tree.end('w:tcPr') self.doc_tree.start('w:p', {}) self.doc_tree.end('w:p') self.doc_tree.end('w:tc') self.body.append('<w:tc>\n <w:tcPr>\n <w:tcW w="' + str(self.calc_col_pct(col)) + '" w:type="pct" />\n <' + self.spans[check_span][0] + ' />\n </w:tcPr>\n <w:p />\n</w:tc>\n') return True return False def astext(self): p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.template_start_element p.EndElementHandler = self.template_end_element p.CharacterDataHandler = self.template_char_data template = file(self.document.settings.template) p.ParseFile(template) return self.doc def encode(self, text): """Encode special characters in `text` & return.""" text = text.replace("&", "&") text = text.replace("<", "<") text = text.replace('"', """) text = text.replace(">", ">") if self.literal_text == 1: text = text.replace("\n", "</w:t><w:br /><w:t>") else: text = text.replace("\n", " ") return text def visit_Text(self, node): # if we have turned off text input, then just return if self.no_text: return # skip encode allows us to inject custom wordml as a text node without self.doc_tree.start('w:r', {}) self.body.append("<w:r>") if len(self.text_properties) > 0: self.doc_tree.start('w:rPr', {}) self.body.append("<w:rPr>\n") for v in self.text_properties.values(): if type(v) == type(()): element = '<' + v[0] + ' ' for k, a in v[1].iteritems(): element += k + '="' + a + '" ' element += '/>' self.doc_tree.start(v[0], v[1]) self.doc_tree.end(v[0]) self.body.append(element) else: self.body.append(v) self.doc_tree.end('w:rPr') self.body.append("</w:rPr>\n") self.doc_tree.start('w:t', {}) self.body.append("<w:t>") text = node.astext() encoded = self.encode(text) self.doc_tree.data(encoded) self.body.append(encoded) self.has_text_output = 1 def depart_Text(self, node): # if we have turned off text input, then just return if self.no_text: return self.doc_tree.end('w:t') self.doc_tree.end('w:r') self.body.append("</w:t></w:r>\n") def visit_TextNoEncoding(self, node): if self.no_text: return self.doc_tree.data(node.astext()) self.body.append(node.astext()) def depart_TextNoEncoding(self, node): pass def visit_TextWithStyle(self, node): self.text_properties[node.style[0]] = node.style[1] self.visit_Text(node) def depart_TextWithStyle(self, node): del self.text_properties[node.style[0]] self.depart_Text(node) def visit_abbreviation(self, node): pass def depart_abbreviation(self, node): pass def visit_acronym(self, node): pass def depart_acronym(self, node): pass def visit_address(self, node): pass def depart_address(self, node): pass def visit_admonition(self, node, name=''): pass def depart_admonition(self, node=None): pass def visit_attention(self, node): pass def depart_attention(self, node): pass def visit_attribution(self, node): pass def depart_attribution(self, node): pass def visit_author(self, node): self.paragraph_properties['author'] = ('w:pStyle', { 'w:val': 'AuthorName' }) # self.paragraph_properties[ 'author' ] = '<w:pStyle w:val="AuthorName" />' self.visit_paragraph(node) def depart_author(self, node): del self.paragraph_properties['author'] self.depart_paragraph(node) def visit_authors(self, node): pass def depart_authors(self, node): pass def visit_block_quote(self, node): self.indentation += 720 def depart_block_quote(self, node): self.indentation -= 720 def visit_bullet_list(self, node): self.list_level += 1 self.list_count += 1 self.lists.append('<w:list w:ilfo="' + str(self.list_count) + '">\n <w:ilst w:val="1">\n </w:ilst>\n</w:list>\n') self.list_properties.append('<w:listPr>\n<w:ilvl w:val="' + str(self.list_level) + '" />\n<w:ilfo w:val="' + str(self.list_count) + '" />\n</w:listPr>\n') def depart_bullet_list(self, node): self.list_properties.pop() self.list_level -= 1 def visit_caption(self, node): self.figure_count += 1 self.text_properties['caption'] = ('w:rStyle', {'w:val': 'Caption'}) # self.text_properties[ 'caption' ] = '<w:rStyle w:val="Caption" />' node.children.insert( 0, nodes.Text('Figure ' + str(self.figure_count) + ' ')) def depart_caption(self, node): del self.text_properties['caption'] def visit_caution(self, node): pass def depart_caution(self, node): pass def visit_citation(self, node): if not self.in_footnote: self.no_text += 1 def depart_citation(self, node): if not self.in_footnote: self.no_text -= 1 def visit_citation_reference(self, node): citation = self.document.ids[node['refid']] citation_reference_text = '' if not isinstance(citation, nodes.citation): raise TypeError('not a citation node mapped to id') self.doc_tree.start('w:r', {}) self.doc_tree.start('w:rPr', {}) self.doc_tree.start('w:rStyle', {'w:val': 'CitationReference'}) self.doc_tree.end('w:rStyle') self.doc_tree.end('w:rPr') self.doc_tree.start('w:endnote', {'w:suppressRef': 'on'}) self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference"/>\n</w:rPr>\n<w:endnote w:suppressRef="on">\n' ) self.in_footnote = 1 former_paragraph_properties = self.paragraph_properties.copy() self.paragraph_properties = {} self.paragraph_properties['citation'] = ('w:pStyle', { 'w:val': 'EndnoteText' }) # self.paragraph_properties[ 'citation' ] = '<w:pStyle w:val="EndnoteText"/>' labels = citation.traverse(condition=nodes.label) for n in labels: citation_reference_text += n.astext() citation.children.remove(n) p = citation.traverse(condition=nodes.paragraph) # t_head = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference" />\n</w:rPr>\n<w:t>' ) # t_tail = TextNoEncoding( '</w:t>\n</w:r>\n') # p[0].children.insert( 0, t_tail ) # p[0].children.insert( 0, TextNoEncoding( '[' + citation_reference_text + '] ' )) # p[0].children.insert( 0, nodes.Text( '[' + citation_reference_text + '] ' )) t = TextWithStyle('[' + citation_reference_text + '] ', ('citation', ('w:rStyle', { 'w:val': 'CitationReference' }))) p[0].children.insert(0, t) # p[0].children.insert( 0, t_head ) citation.walkabout(self) p[0].children.remove(t) self.doc_tree.end('w:endnote') self.doc_tree.start('w:t', {}) self.doc_tree.data('[' + citation_reference_text + ']') self.doc_tree.end('w:t') self.doc_tree.end('w:r') self.body.append('</w:endnote>\n') self.body.append('<w:t>') self.body.append('[' + citation_reference_text + ']') self.body.append('</w:t>\n</w:r>\n') del self.paragraph_properties['citation'] self.in_footnote = 0 self.no_text += 1 self.paragraph_properties = former_paragraph_properties def depart_citation_reference(self, node): self.no_text -= 1 pass def visit_classifier(self, node): pass def depart_classifier(self, node): pass def visit_colspec(self, node): self.colspecs.append(node) self.total_col_width += node['colwidth'] def depart_colspec(self, node): pass def visit_comment(self, node): self.no_text += 1 def depart_comment(self, node): self.no_text -= 1 def visit_compound(self, node): pass def depart_compound(self, node): pass def visit_contact(self, node): self.paragraph_properties['contact'] = ('w:pStyle', { 'w:val': 'AuthorContact' }) # self.paragraph_properties[ 'contact' ] = '<w:pStyle w:val="AuthorContact" />' self.visit_paragraph(node) def depart_contact(self, node): del self.paragraph_properties['contact'] self.depart_paragraph(node) def visit_container(self, node): pass def depart_container(self, node): pass def visit_copyright(self, node): self.paragraph_properties['copyright'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) # self.paragraph_properties[ 'copyright' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_copyright(self, node): del self.paragraph_properties['copyright'] self.depart_paragraph(node) def visit_danger(self, node): pass def depart_danger(self, node): pass def visit_date(self, node): self.paragraph_properties['date'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) # self.paragraph_properties[ 'date' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_date(self, node): del self.paragraph_properties['date'] self.depart_paragraph(node) def visit_decoration(self, node): pass def depart_decoration(self, node): pass def visit_definition(self, node): self.indentation += 720 self.paragraph_properties['definition'] = ('w:pStyle', { 'w:val': 'Definition' }) # self.paragraph_properties[ 'definition' ] = '<w:pStyle w:val="Definition" />' def depart_definition(self, node): self.indentation -= 720 del self.paragraph_properties['definition'] def visit_definition_list(self, node): pass def depart_definition_list(self, node): pass def visit_definition_list_item(self, node): pass def depart_definition_list_item(self, node): pass def visit_description(self, node): pass def depart_description(self, node): pass def visit_docinfo(self, node): pass def depart_docinfo(self, node): pass def visit_docinfo_item(self, node, name, meta=1): pass def depart_docinfo_item(self): pass def visit_doctest_block(self, node): pass def depart_doctest_block(self, node): pass def visit_document(self, node): pass def depart_document(self, node): pass def visit_emphasis(self, node): self.text_properties['*'] = ('w:i', {}) # self.text_properties[ '*' ] = '<w:i/>' def depart_emphasis(self, node): del self.text_properties['*'] def calc_col_pct(self, col): width = int(self.colspecs[col]['colwidth'] * 100.0 / self.total_col_width + 0.5) return width def visit_entry(self, node): width = self.calc_col_pct(self.col) self.doc_tree.start('w:tc', {}) self.doc_tree.start('w:tcPr', {}) self.doc_tree.start('w:tcW', {'w': str(width), 'w:type': 'pct'}) self.doc_tree.end('w:tcW') self.body.append('<w:tc>\n <w:tcPr>\n <w:tcW w="' + str(width) + '" w:type="pct" />\n') self.has_text_output = 0 if node.has_key('morecols') and node.has_key('morerows'): raise NotImplementedError( "Table cell " + str(self.col) + "," + str(self.row) + " can't have both merged rows and columns.") if node.has_key('morecols'): self.doc_tree.start('w:hmerge', {'w:val': 'restart'}) self.doc_tree.end('w:hmerge') self.body.append('<w:hmerge w:val="restart" />') for i in range(node['morecols']): span = '{' + str(self.col + i + 1) + ',' + str(self.row) + '}' self.spans[span] = ('w:hmerge', {}) # '<w:hmerge />' if node.has_key('morerows'): self.doc_tree.start('w:vmerge', {'w:val': 'restart'}) self.doc_tree.end('w:vmerge') self.body.append('<w:vmerge w:val="restart" />') for i in range(node['morerows']): span = '{' + str(self.col) + ',' + str(self.row + i + 1) + '}' self.spans[span] = ('w:vmerge', {}) # '<w:vmerge />' self.doc_tree.end('w:tcPr') self.body.append('</w:tcPr>\n') def depart_entry(self, node): if self.has_text_output == 0: self.doc_tree.start('w:p', {}) self.doc_tree.end('w:p') self.body.append(' <w:p />\n') self.doc_tree.end('w:tc') self.body.append('</w:tc>\n') # if there are any cells that are part of a span, then include them here as empty cells. col = self.col + 1 row = self.row while self.check_for_span(col, row): col = col + 1 self.col = col self.row = row def visit_enumerated_list(self, node): # to put any sort of customization in, it's necessary to add an entirely new listDef element. # so, I need to load the listDefs at the beginning of the run, and then customize them as needed. self.list_level += 1 self.list_count += 1 list_props = '<w:listPr>\n<w:ilvl w:val="' + str( self.list_level) + '" />\n<w:ilfo w:val="' + str( self.list_count) + '" />\n' #if the list has an explicit start, then set the text for it start = 1 if node.has_key('start'): start = int(node['start']) nfc = 0 if node['enumtype'] == 'arabic': nfc = 0 elif node['enumtype'] == 'upperalpha': nfc = 3 elif node['enumtype'] == 'loweralpha': nfc = 4 elif node['enumtype'] == 'lowerroman': nfc = 2 elif node['enumtype'] == 'upperroman': nfc = 1 self.list_defs.append( self.listdef_to_xml(0, self.list_level, start, nfc)) self.lists.append('<w:list w:ilfo="' + str(self.list_count) + '">\n <w:ilst w:val="' + str(self.list_count + 1) + '">\n </w:ilst>\n</w:list>\n') list_props += '</w:listPr>\n' self.list_properties.append(list_props) def depart_enumerated_list(self, node): self.show_list_properties -= 1 self.list_properties.pop() self.list_level -= 1 def visit_error(self, node): pass def depart_error(self, node): pass def visit_field(self, node): self.paragraph_properties['field'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) # self.paragraph_properties[ 'field' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_field(self, node): del self.paragraph_properties['field'] self.depart_paragraph(node) def visit_field_body(self, node): pass def depart_field_body(self, node): pass def visit_field_list(self, node): pass def depart_field_list(self, node): pass def visit_field_name(self, node): pass def depart_field_name(self, node): pass def visit_figure(self, node): self.in_figure = 1 def depart_figure(self, node): if self.in_figure: self.doc_tree.end('w:p') self.body.append('</w:p>\n') self.in_figure = 0 def visit_footer(self, node): pass def depart_footer(self, node): pass def visit_footnote(self, node): if not self.in_footnote: self.no_text += 1 def depart_footnote(self, node): if not self.in_footnote: self.no_text -= 1 def visit_footnote_reference(self, node): if not node.has_key('auto'): raise TypeError('footnotes required to be auto numbered') footnote = self.document.ids[node['refid']] if not isinstance(footnote, nodes.footnote): raise TypeError('not a footnote node mapped to id') self.doc_tree.start('w:r', {}) self.doc_tree.start('w:rPr', {}) self.doc_tree.start('w:rStyle', {'w:val': 'EndnoteReference'}) self.doc_tree.end('w:rStyle') self.doc_tree.end('w:rPr') self.doc_tree.start('w:endnote', {}) self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnote>\n' ) # figure out how to get the <w:endnoteRef/> self.in_footnote = 1 former_paragraph_properties = self.paragraph_properties.copy() self.paragraph_properties = {} self.paragraph_properties['footnote'] = ('w:pStyle', { 'w:val': 'EndnoteText' }) # self.paragraph_properties[ 'footnote' ] = '<w:pStyle w:val="EndnoteText"/>' # self.body.append( '<w:p>\n<w:pPr>\n<w:pStyle w:val="EndnoteText"/>\n</w:pPr>\n<w:r>\n<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n' ) # Find the label in the target footnode node and add it here. labels = footnote.traverse(condition=nodes.label) # replace label text with <w:endnoteRef /> for n in labels: footnote.children.remove(n) # n.children.append( nodes.Text('<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n')) p = footnote.traverse(condition=nodes.paragraph) # t = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n') t = XMLRegion(xml=[('w:endnoteRef', {})], styles=[('w:rStyle', { 'w:val': 'EndnoteReference' })]) p[0].children.insert(0, t) footnote.walkabout(self) p[0].children.remove(t) self.doc_tree.end('w:endnote') self.doc_tree.end('w:r') self.body.append('</w:endnote>\n</w:r>\n') del self.paragraph_properties['footnote'] self.in_footnote = 0 self.no_text += 1 self.paragraph_properties = former_paragraph_properties def depart_footnote_reference(self, node): # del self.paragraph_properties[ 'footnote' ] # self.in_footnote = 0 self.no_text -= 1 def visit_generated(self, node): pass def depart_generated(self, node): pass def visit_header(self, node): pass def depart_header(self, node): pass def visit_hint(self, node): pass def depart_hint(self, node): pass def visit_image(self, node): width = 100 height = 100 align = 'center' use_width = 0 use_height = 0 if Image: try: im = Image.open(node['uri']) width = im.size[0] height = im.size[1] use_width = 1 use_height = 1 except (IOError, UnicodeError): pass if node.has_key('width'): width = node['width'] use_width = 1 if node.has_key('height'): height = node['height'] use_height = 1 if node.has_key('align'): align = node['align'] self.doc_tree.start('w:p', {}) self.doc_tree.start('w:pPr', {}) self.doc_tree.start('w:jc', {'w:val': str(align)}) self.doc_tree.end('w:jc') self.doc_tree.end('w:pPr') self.doc_tree.start('w:pict', {}) style = 'position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:' if use_width: style += str(width) + 'px' else: style += 'auto' style += ';height:' if use_height: style += str(height) + 'px' else: style += 'auto' style += ';z-index:1;mso-position-horizontal:center' self.doc_tree.start( 'v:shape', { 'id': str(self.gen_id()), 'style': style, 'coordsize': '', 'o:spt': '100', 'adj': '0,,0', 'path': '', 'stroked': 'f' }) self.doc_tree.start('v:imagedata', {'src': node['uri']}) self.doc_tree.end('v:imagedata') self.doc_tree.start('w10:wrap', {'type': 'square'}) self.doc_tree.end('w10:wrap') self.doc_tree.end('v:shape') self.doc_tree.end('w:pict') self.body.append('<w:p>\n<w:pPr>\n<w:jc w:val="' + str(align) + '" />\n</w:pPr>\n<w:pict>\n<v:shape id="' + str(self.gen_id()) + '" ') self.body.append( 'style="position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:' ) if use_width: self.body.append(str(width) + 'px') else: self.body.append('auto') self.body.append(';height:') if use_height: self.body.append(str(height) + 'px') else: self.body.append('auto') self.body.append( ';z-index:1;mso-position-horizontal:center" coordsize="" o:spt="100" adj="0,,0" path="" stroked="f" >\n' ) self.body.append( '<v:imagedata src="' + node['uri'] + '"/>\n<w10:wrap type="square"/>\n</v:shape>\n</w:pict>\n') def depart_image(self, node): if not self.in_figure: self.doc_tree.end('w:p') self.body.append('</w:p>\n') def visit_important(self, node): pass def depart_important(self, node): pass def visit_inline(self, node): pass def depart_inline(self, node): pass def visit_label(self, node): self.text_properties['label'] = ('w:rStyle', { 'w:val': '"EndnoteReference"' }) # self.text_properties[ 'label' ] = '<w:rStyle w:val="EndnoteReference"/>\n' #if self.in_footnote: # self.no_text += 1 # self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n</w:r>\n' ) pass def depart_label(self, node): del self.text_properties['label'] #if self.in_footnote: # self.no_text -= 1 pass def visit_legend(self, node): pass def depart_legend(self, node): pass def visit_line(self, node): pass def depart_line(self, node): pass def visit_line_block(self, node): pass def depart_line_block(self, node): pass def visit_list_item(self, node): pass def depart_list_item(self, node): pass def visit_literal(self, node): self.text_properties['literal'] = ('w:rStyle', {'w:val': 'Literal'}) # self.text_properties[ 'literal' ] = '<w:rStyle w:val="Literal"/>\n' def depart_literal(self, node): del self.text_properties['literal'] def visit_literal_block(self, node): self.paragraph_properties['literal'] = ('w:pStyle', { 'w:val': 'LiteralBlock' }) #~ self.paragraph_properties[ 'literal' ] = '<w:pStyle w:val="LiteralBlock" />\n' self.visit_paragraph(node) self.literal_text = 1 def depart_literal_block(self, node): del self.paragraph_properties['literal'] self.depart_paragraph(node) self.literal_text = 0 def visit_meta(self, node): pass def depart_meta(self, node): pass def visit_note(self, node): pass def depart_note(self, node): pass def visit_option(self, node): pass def depart_option(self, node): pass def visit_option_argument(self, node): pass def depart_option_argument(self, node): pass def visit_option_group(self, node): pass def depart_option_group(self, node): pass def visit_option_list(self, node): pass def depart_option_list(self, node): pass def visit_option_list_item(self, node): pass def depart_option_list_item(self, node): pass def visit_option_string(self, node): pass def depart_option_string(self, node): pass def visit_organization(self, node): self.paragraph_properties['organization'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) #~ self.paragraph_properties[ 'organization' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_organization(self, node): del self.paragraph_properties['organization'] self.depart_paragraph(node) def visit_paragraph(self, node): self.doc_tree.start('w:p', {}) self.body.append("<w:p>\n") if len(self.paragraph_properties) > 0 or len( self.list_properties) > 0 or (self.indentation > 0 and not self.in_footnote): self.doc_tree.start('w:pPr', {}) self.body.append("<w:pPr>\n") if self.indentation > 0 and not self.in_footnote: self.doc_tree.start( 'w:ind', { 'w:left': str(self.indentation), 'w:right': str(self.indentation) }) self.doc_tree.end('w:ind') self.body.append('<w:ind w:left="' + str(self.indentation) + '" w:right="' + str(self.indentation) + '" />\n') for v in self.paragraph_properties.values(): if type(v) == type(()): element = '<' + v[0] + ' ' for k, a in v[1].iteritems(): element += k + '="' + a + '" ' element += '/>' self.doc_tree.start(v[0], v[1]) self.doc_tree.end(v[0]) self.body.append(element) else: self.body.append(v) if len(self.list_properties) > 0 and isinstance( node.parent, nodes.list_item): if type(self.list_properties[-1]) == type(()): t = self.list_properties[-1] element = '<' + t[0] + ' ' for k, a in t[1].iteritems(): element += k + '="' + a + '" ' element += '/>' self.doc_tree.start(t[0], t[1]) self.doc_tree.end(t[0]) self.body.append(element) else: self.body.append(self.list_properties[-1]) self.doc_tree.end('w:pPr') self.body.append("\n</w:pPr>\n") def depart_paragraph(self, node): self.doc_tree.end('w:p') self.body.append("</w:p>\n") def visit_problematic(self, node): pass def depart_problematic(self, node): pass def visit_raw(self, node): pass def visit_reference(self, node): if node.has_key('refid'): self.doc_tree.start('w:hlink', {'w:bookmark': node['refid']}) self.body.append('<w:hlink w:bookmark="' + node['refid'] + '" >\n') if node.has_key('refuri'): self.doc_tree.start('w:hlink', {'w:dest': node['refuri']}) self.body.append('<w:hlink w:dest="' + node['refuri'] + '" >\n') if not node.has_key('refuri') and not node.has_key('refid'): raise NotImplementedError('Unknown reference type') self.text_properties['ref'] = ('w:rStyle', {'w:val': 'Hyperlink'}) #~ self.text_properties['ref'] = '<w:rStyle w:val="Hyperlink" />\n' def depart_reference(self, node): del self.text_properties['ref'] self.doc_tree.end('w:hlink') self.body.append('</w:hlink>\n') def visit_revision(self, node): pass def depart_revision(self, node): pass def visit_row(self, node): self.doc_tree.start('w:tr', {}) self.body.append('<w:tr>\n') while self.check_for_span(self.col, self.row): self.col += 1 def depart_row(self, node): self.row += 1 self.col = 0 self.doc_tree.end('w:tr') self.body.append('</w:tr>\n') def visit_rubric(self, node): pass def depart_rubric(self, node): pass def visit_section(self, node): self.section_level += 1 if self.section_level > 3: raise NotImplementedError("Only 3 levels of headings supported.") if node.has_key('ids'): for id in node['ids']: refid = self.gen_id() self.doc_tree.start( 'aml:annotation', { 'aml:id': str(refid), 'w:type': 'Word.Bookmark.Start', 'w:name': id }) self.doc_tree.end('aml:annotation') self.doc_tree.start( 'aml:annotation', { 'aml:id': str(refid), 'w:type': 'Word.Bookmark.End', 'w:name': id }) self.doc_tree.end('aml:annotation') self.body.append('<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.Start" w:name="' + id + '" />') self.body.append('<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.End" w:name="' + id + '" />') def depart_section(self, node): self.section_level -= 1 def visit_sidebar(self, node): pass def depart_sidebar(self, node): pass def visit_status(self, node): self.paragraph_properties['status'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) #~ self.paragraph_properties[ 'status' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_status(self, node): del self.paragraph_properties['status'] self.depart_paragraph(node) def visit_strong(self, node): self.text_properties['**'] = ('w:b', {}) #~ self.text_properties[ '**' ] = '<w:b/>' def depart_strong(self, node): del self.text_properties['**'] def visit_subscript(self, node): self.text_properties['subscript'] = ('w:vertAlign', { 'w:val': 'subscript' }) #~ self.text_properties[ 'subscript' ] = '<w:vertAlign w:val="subscript" />' def depart_subscript(self, node): del self.text_properties['subscript'] def visit_substitution_definition(self, node): raise nodes.SkipNode def visit_substitution_reference(self, node): raise NotImplementedError("substitution references not implemented") def visit_subtitle(self, node): self.paragraph_properties['subtitle'] = ('w:pStyle', { 'w:val': self.title_styles[self.section_level + 1] }) #~ self.paragraph_properties[ 'subtitle' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level + 1 ] + '"/>\n' self.visit_paragraph(node) def depart_subtitle(self, node): del self.paragraph_properties['subtitle'] self.depart_paragraph(node) def visit_superscript(self, node): self.text_properties['superscript'] = ('w:vertAlign', { 'w:val': 'superscript' }) #~ self.text_properties[ 'superscript' ] = '<w:vertAlign w:val="superscript" />\n' def depart_superscript(self, node): del self.text_properties['superscript'] def visit_system_message(self, node): pass def depart_system_message(self, node): pass def visit_table(self, node): #include for now the default border around the table with a top vertical alignment self.in_table = 1 self.colspecs = [] self.spans = {} self.total_col_width = 0 self.row = 0 self.col = 0 self.doc_tree.start('w:tbl', {}) self.doc_tree.start('w:tblPr', {}) self.doc_tree.start('w:tblStyle', {'w:val': 'Normal'}) self.doc_tree.end('w:tblStyle') self.doc_tree.start('w:tblW', {'w:w': '5000', 'w:type': 'pct'}) self.doc_tree.end('w:tblW') self.doc_tree.start('w:tblBorders', {}) self.doc_tree.start( 'w:top', { 'w:val': 'single', 'w:sz': '4', 'wx:bdrwidth': '10', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:top') self.doc_tree.start( 'w:left', { 'w:val': 'single', 'w:sz': '4', 'wx:bdrwidth': '10', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:left') self.doc_tree.start( 'w:bottom', { 'w:val': 'single', 'w:sz': '4', 'wx:bdrwidth': '10', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:bottom') self.doc_tree.start( 'w:right', { 'w:val': 'single', 'w:sz': '4', 'wx:bdrwidth': '10', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:right') self.doc_tree.start( 'w:insideH', { 'w:val': 'single', 'w:sz': '6', 'wx:bdrwidth': '15', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:insideH') self.doc_tree.start( 'w:insideV', { 'w:val': 'single', 'w:sz': '6', 'wx:bdrwidth': '15', 'w:space': '0', 'w:color': 'auto' }) self.doc_tree.end('w:insideV') self.doc_tree.end('w:tblBorders') self.doc_tree.start('w:tblLook', {'w:val': '000001e0'}) self.doc_tree.end('w:tblLook') self.doc_tree.end('w:tblPr') self.body.append( '<w:tbl>\n' ' <w:tblPr>\n' ' <w:tblStyle w:val="Normal" />\n' ' <w:tblW w:w="5000" w:type="pct" />\n' ' <w:tblBorders>\n' ' <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:insideH w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n' ' <w:insideV w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n' ' </w:tblBorders>\n' ' <w:tblLook w:val="000001e0" />\n' ' </w:tblPr>\n') def depart_table(self, node): self.doc_tree.end('w:tbl') self.doc_tree.start('w:p', {}) self.doc_tree.end('w:p') self.body.append('</w:tbl>\n') self.body.append('<w:p />') # add a blank line after the table self.in_table = 0 def visit_target(self, node): if node.has_key('refid'): refid = self.gen_id() self.doc_tree.start( 'aml:annotation', { 'aml:id': str(refid), 'w:type': 'Word.Bookmark.Start', 'w:name': node['refid'] }) self.doc_tree.end('aml:annotation') self.doc_tree.start( 'aml:annotation', { 'aml:id': str(refid), 'w:type': 'Word.Bookmark.End', 'w:name': node['refid'] }) self.doc_tree.end('aml:annotation') self.body.append('<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.Start" w:name="' + node['refid'] + '" />\n') self.body.append('<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.End" w:name="' + node['refid'] + '" />\n') def depart_target(self, node): pass def visit_tbody(self, node): pass def depart_tbody(self, node): pass def visit_term(self, node): self.paragraph_properties['term'] = ('w:pStyle', { 'w:val': 'DefinitionTerm' }) #~ self.paragraph_properties[ 'term' ] = '<w:pStyle w:val="DefinitionTerm" />' self.visit_paragraph(node) def depart_term(self, node): del self.paragraph_properties['term'] self.depart_paragraph(node) def visit_tgroup(self, node): pass def depart_tgroup(self, node): pass def visit_thead(self, node): pass def depart_thead(self, node): pass def visit_tip(self, node): pass def depart_tip(self, node): pass def visit_title(self, node, move_ids=1): self.paragraph_properties['title'] = ('w:pStyle', { 'w:val': self.title_styles[self.section_level] }) #~ self.paragraph_properties[ 'title' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level ] + '"/>\n' self.visit_paragraph(node) def depart_title(self, node): del self.paragraph_properties['title'] self.depart_paragraph(node) def visit_title_reference(self, node): pass def depart_title_reference(self, node): pass def visit_topic(self, node): self.paragraph_properties['topic'] = ('w:pStyle', {'w:val': 'Topic'}) #~ self.paragraph_properties[ 'topic' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_topic(self, node): del self.paragraph_properties['topic'] self.depart_paragraph(node) def visit_transition(self, node): pass def depart_transition(self, node): pass def visit_version(self, node): self.paragraph_properties['version'] = ('w:pStyle', { 'w:val': 'BibliographMatter' }) # self.paragraph_properties[ 'version' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_version(self, node): del self.paragraph_properties['version'] self.depart_paragraph(node) def visit_warning(self, node): pass def depart_warning(self, node): pass def visit_XMLRegion(self, node): self.doc_tree.start('w:r', {}) self.doc_tree.start('w:rPr', {}) for style in node['styles']: self.doc_tree.start(style[0], style[1]) self.doc_tree.end(style[0]) self.doc_tree.end('w:rPr') for tag in node['xml']: self.doc_tree.start(tag[0], tag[1]) self.doc_tree.end(tag[0]) def depart_XMLRegion(self, node): self.doc_tree.end('w:r') def unimplemented_visit(self, node): pass
def _record_parse(self, key=None, **kwargs): r""" Returns an element tree structure corresponding to a toolbox data file with all markers at the same level. Thus the following Toolbox database:: \_sh v3.0 400 Rotokas Dictionary \_DateStampHasFourDigitYear \lx kaa \ps V.A \ge gag \gp nek i pas \lx kaa \ps V.B \ge strangle \gp pasim nek after parsing will end up with the same structure (ignoring the extra whitespace) as the following XML fragment after being parsed by ElementTree:: <toolbox_data> <header> <_sh>v3.0 400 Rotokas Dictionary</_sh> <_DateStampHasFourDigitYear/> </header> <record> <lx>kaa</lx> <ps>V.A</ps> <ge>gag</ge> <gp>nek i pas</gp> </record> <record> <lx>kaa</lx> <ps>V.B</ps> <ge>strangle</ge> <gp>pasim nek</gp> </record> </toolbox_data> :param key: Name of key marker at the start of each record. If set to None (the default value) the first marker that doesn't begin with an underscore is assumed to be the key. :type key: str :param kwargs: Keyword arguments passed to ``StandardFormat.fields()`` :type kwargs: dict :rtype: ElementTree._ElementInterface :return: contents of toolbox data divided into header and records """ builder = TreeBuilder() builder.start("toolbox_data", {}) builder.start("header", {}) in_records = False for mkr, value in self.fields(**kwargs): if key is None and not in_records and mkr[0] != "_": key = mkr if mkr == key: if in_records: builder.end("record") else: builder.end("header") in_records = True builder.start("record", {}) builder.start(mkr, {}) builder.data(value) builder.end(mkr) if in_records: builder.end("record") else: builder.end("header") builder.end("toolbox_data") return builder.close()
class WordMLTranslator(nodes.NodeVisitor): """ This WordML writer handles most of the features for now, You can get the gist of it rather easily. It's not nearly as complicated as the HTML writer, surprisingly. """ title_styles = ["Heading1", "Heading2", "Heading3"] xml_spaces = " " # these are meant to be default lists, one for bullet and one for enumerated. # other list types should be added here later. def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.document = document self.doc = "" self.body = [] # the body of the document self.in_docinfo = None self.in_sidebar = None self.settings = settings = document.settings self.section_level = 0 self.title_level = 0 self.text_properties = {} # the list of properties for a run of test self.text_prefix = [] # text or commands inserted before next text run self.paragraph_properties = {} self.id = 1000 self.in_footnote = 0 self.no_text = 0 # flag to suppress any text output self.literal_text = 0 # flag to output newlines in text self.skip_encode = 0 # flag to skip the encoding of text to xml friendly output self.has_text_output = 0 # flag if any text output since last reset self.figure_count = 0 self.in_figure = 0 self.indentation = 0 # list related variables self.lists = [] self.list_level = -1 self.list_count = 0 self.list_properties = [] self.list_defs = [] self.template_list_defs = [] self.current_listdef = [] self.in_listdef = 0 self.show_list_properties = 0 self.extract_listdefs() self.substitutions = {} # table related variables self.in_table = 0 self.colspecs = [] self.row = 0 self.col = 0 self.spans = {} # for multispan columns and rows self.total_col_width = 0 # xml output variables self.doc_tree = TreeBuilder() self.doc_tree.start("w:document", {}) self.xml_spacing = 0 def gen_id(self): self.id += 1 return self.id def template_start_element(self, name, attr): if name == "w:rest": self.doc_tree.end("w:document") tree = self.doc_tree.close() doc_string = tostring(tree) p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.body_start_element p.EndElementHandler = self.body_end_element p.CharacterDataHandler = self.body_data p.Parse(doc_string) # for b in self.body: # self.doc += b elif name == "w:rstlists": for l in self.lists: self.doc += l elif name == "w:rstlistdefs": for l in self.list_defs: self.doc += l else: self.doc += "<" + name + " " for k, v in attr.iteritems(): self.doc += k + '="' + v + '" ' self.doc += ">" def template_end_element(self, name): if name == "w:rest" or name == "w:rstlists" or name == "w:rstlistdefs": pass else: self.doc += "</" + name + ">" def template_char_data(self, data): self.doc += data # routines for extracting the listdef elements from the template def start_listdef_extract(self, name, attr): if name == "w:listDef": self.in_listdef = 1 self.current_listdef = [] if name == "w:lsid": return if self.in_listdef == 1: self.current_listdef.append([name, attr]) def end_listdef_extract(self, name): self.current_listdef.append(["/" + name]) if name == "w:listDef": self.template_list_defs.append(self.current_listdef) self.in_listdef = 0 if name == "w:lsid": return def list_def_data(self, data): pass def extract_listdefs(self): p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.start_listdef_extract p.EndElementHandler = self.end_listdef_extract p.CharacterDataHandler = self.list_def_data template = file(self.document.settings.template) p.ParseFile(template) def listdef_to_xml(self, list_number, level, start, nfc): """Modify a listdef to include an alternate numbering scheme and new starting number. Then convert it to XML and return the XML string.""" xml = "" lvl = -1000 for x in self.template_list_defs[list_number]: # change the listDefId to match the new list if x[0] == "w:listDef": x[1]["w:listDefId"] = str(self.list_count + 1) # get the level if it has changed if x[0] == "w:lvl": lvl = int(x[1]["w:ilvl"]) # skip an existing nfc node if (x[0] == "w:nfc" or x[0] == "/w:nfc") and level == lvl: continue xml += "<" + x[0] + " " if len(x) == 2: for k, v in x[1].iteritems(): if x[0] == "w:start" and k == "w:val" and lvl == level: xml += k + '="' + str(start) + '" ' else: xml += k + '="' + v + '" ' xml += ">\n" # add in our nfc node right after the start node if x[0] == "/w:start" and level == lvl: xml += '<w:nfc w:val="' + str(nfc) + '" />\n' return xml def body_start_element(self, name, attr): if name == "w:document": return element = self.xml_spaces[0 : self.xml_spacing] + "<" + name + " " for k, v in attr.iteritems(): element += k + '="' + v + '" ' element = element[:-1] element += ">" if name != "w:t": element += "\n" self.xml_spacing += 2 self.doc += element def body_end_element(self, name): if name == "w:document": return self.xml_spacing -= 2 element = "" if name != "w:t": element += self.xml_spaces[0 : self.xml_spacing] element += "</" + name + ">\n" self.doc += element def body_data(self, data): self.doc += data def check_for_span(self, col, row): check_span = "{" + str(col) + "," + str(row) + "}" if self.spans.has_key(check_span): self.doc_tree.start("w:tc", {}) self.doc_tree.start("w:tcPr", {}) self.doc_tree.start("w:tcW", {"w": str(self.calc_col_pct(self.col)), "w:type": "pct"}) self.doc_tree.start(self.spans[check_span][0], self.spans[check_span][1]) self.doc_tree.end(self.spans[check_span][0]) self.doc_tree.end("w:tcW") self.doc_tree.end("w:tcPr") self.doc_tree.start("w:p", {}) self.doc_tree.end("w:p") self.doc_tree.end("w:tc") self.body.append( '<w:tc>\n <w:tcPr>\n <w:tcW w="' + str(self.calc_col_pct(col)) + '" w:type="pct" />\n <' + self.spans[check_span][0] + " />\n </w:tcPr>\n <w:p />\n</w:tc>\n" ) return True return False def astext(self): p = xml.parsers.expat.ParserCreate() p.StartElementHandler = self.template_start_element p.EndElementHandler = self.template_end_element p.CharacterDataHandler = self.template_char_data template = file(self.document.settings.template) p.ParseFile(template) return self.doc def encode(self, text): """Encode special characters in `text` & return.""" text = text.replace("&", "&") text = text.replace("<", "<") text = text.replace('"', """) text = text.replace(">", ">") if self.literal_text == 1: text = text.replace("\n", "</w:t><w:br /><w:t>") else: text = text.replace("\n", " ") return text def visit_Text(self, node): # if we have turned off text input, then just return if self.no_text: return # skip encode allows us to inject custom wordml as a text node without self.doc_tree.start("w:r", {}) self.body.append("<w:r>") if len(self.text_properties) > 0: self.doc_tree.start("w:rPr", {}) self.body.append("<w:rPr>\n") for v in self.text_properties.values(): if type(v) == type(()): element = "<" + v[0] + " " for k, a in v[1].iteritems(): element += k + '="' + a + '" ' element += "/>" self.doc_tree.start(v[0], v[1]) self.doc_tree.end(v[0]) self.body.append(element) else: self.body.append(v) self.doc_tree.end("w:rPr") self.body.append("</w:rPr>\n") self.doc_tree.start("w:t", {}) self.body.append("<w:t>") text = node.astext() encoded = self.encode(text) self.doc_tree.data(encoded) self.body.append(encoded) self.has_text_output = 1 def depart_Text(self, node): # if we have turned off text input, then just return if self.no_text: return self.doc_tree.end("w:t") self.doc_tree.end("w:r") self.body.append("</w:t></w:r>\n") def visit_TextNoEncoding(self, node): if self.no_text: return self.doc_tree.data(node.astext()) self.body.append(node.astext()) def depart_TextNoEncoding(self, node): pass def visit_TextWithStyle(self, node): self.text_properties[node.style[0]] = node.style[1] self.visit_Text(node) def depart_TextWithStyle(self, node): del self.text_properties[node.style[0]] self.depart_Text(node) def visit_abbreviation(self, node): pass def depart_abbreviation(self, node): pass def visit_acronym(self, node): pass def depart_acronym(self, node): pass def visit_address(self, node): pass def depart_address(self, node): pass def visit_admonition(self, node, name=""): pass def depart_admonition(self, node=None): pass def visit_attention(self, node): pass def depart_attention(self, node): pass def visit_attribution(self, node): pass def depart_attribution(self, node): pass def visit_author(self, node): self.paragraph_properties["author"] = ("w:pStyle", {"w:val": "AuthorName"}) # self.paragraph_properties[ 'author' ] = '<w:pStyle w:val="AuthorName" />' self.visit_paragraph(node) def depart_author(self, node): del self.paragraph_properties["author"] self.depart_paragraph(node) def visit_authors(self, node): pass def depart_authors(self, node): pass def visit_block_quote(self, node): self.indentation += 720 def depart_block_quote(self, node): self.indentation -= 720 def visit_bullet_list(self, node): self.list_level += 1 self.list_count += 1 self.lists.append( '<w:list w:ilfo="' + str(self.list_count) + '">\n <w:ilst w:val="1">\n </w:ilst>\n</w:list>\n' ) self.list_properties.append( '<w:listPr>\n<w:ilvl w:val="' + str(self.list_level) + '" />\n<w:ilfo w:val="' + str(self.list_count) + '" />\n</w:listPr>\n' ) def depart_bullet_list(self, node): self.list_properties.pop() self.list_level -= 1 def visit_caption(self, node): self.figure_count += 1 self.text_properties["caption"] = ("w:rStyle", {"w:val": "Caption"}) # self.text_properties[ 'caption' ] = '<w:rStyle w:val="Caption" />' node.children.insert(0, nodes.Text("Figure " + str(self.figure_count) + " ")) def depart_caption(self, node): del self.text_properties["caption"] def visit_caution(self, node): pass def depart_caution(self, node): pass def visit_citation(self, node): if not self.in_footnote: self.no_text += 1 def depart_citation(self, node): if not self.in_footnote: self.no_text -= 1 def visit_citation_reference(self, node): citation = self.document.ids[node["refid"]] citation_reference_text = "" if not isinstance(citation, nodes.citation): raise TypeError("not a citation node mapped to id") self.doc_tree.start("w:r", {}) self.doc_tree.start("w:rPr", {}) self.doc_tree.start("w:rStyle", {"w:val": "CitationReference"}) self.doc_tree.end("w:rStyle") self.doc_tree.end("w:rPr") self.doc_tree.start("w:endnote", {"w:suppressRef": "on"}) self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference"/>\n</w:rPr>\n<w:endnote w:suppressRef="on">\n' ) self.in_footnote = 1 former_paragraph_properties = self.paragraph_properties.copy() self.paragraph_properties = {} self.paragraph_properties["citation"] = ("w:pStyle", {"w:val": "EndnoteText"}) # self.paragraph_properties[ 'citation' ] = '<w:pStyle w:val="EndnoteText"/>' labels = citation.traverse(condition=nodes.label) for n in labels: citation_reference_text += n.astext() citation.children.remove(n) p = citation.traverse(condition=nodes.paragraph) # t_head = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference" />\n</w:rPr>\n<w:t>' ) # t_tail = TextNoEncoding( '</w:t>\n</w:r>\n') # p[0].children.insert( 0, t_tail ) # p[0].children.insert( 0, TextNoEncoding( '[' + citation_reference_text + '] ' )) # p[0].children.insert( 0, nodes.Text( '[' + citation_reference_text + '] ' )) t = TextWithStyle( "[" + citation_reference_text + "] ", ("citation", ("w:rStyle", {"w:val": "CitationReference"})) ) p[0].children.insert(0, t) # p[0].children.insert( 0, t_head ) citation.walkabout(self) p[0].children.remove(t) self.doc_tree.end("w:endnote") self.doc_tree.start("w:t", {}) self.doc_tree.data("[" + citation_reference_text + "]") self.doc_tree.end("w:t") self.doc_tree.end("w:r") self.body.append("</w:endnote>\n") self.body.append("<w:t>") self.body.append("[" + citation_reference_text + "]") self.body.append("</w:t>\n</w:r>\n") del self.paragraph_properties["citation"] self.in_footnote = 0 self.no_text += 1 self.paragraph_properties = former_paragraph_properties def depart_citation_reference(self, node): self.no_text -= 1 pass def visit_classifier(self, node): pass def depart_classifier(self, node): pass def visit_colspec(self, node): self.colspecs.append(node) self.total_col_width += node["colwidth"] def depart_colspec(self, node): pass def visit_comment(self, node): self.no_text += 1 def depart_comment(self, node): self.no_text -= 1 def visit_compound(self, node): pass def depart_compound(self, node): pass def visit_contact(self, node): self.paragraph_properties["contact"] = ("w:pStyle", {"w:val": "AuthorContact"}) # self.paragraph_properties[ 'contact' ] = '<w:pStyle w:val="AuthorContact" />' self.visit_paragraph(node) def depart_contact(self, node): del self.paragraph_properties["contact"] self.depart_paragraph(node) def visit_container(self, node): pass def depart_container(self, node): pass def visit_copyright(self, node): self.paragraph_properties["copyright"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # self.paragraph_properties[ 'copyright' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_copyright(self, node): del self.paragraph_properties["copyright"] self.depart_paragraph(node) def visit_danger(self, node): pass def depart_danger(self, node): pass def visit_date(self, node): self.paragraph_properties["date"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # self.paragraph_properties[ 'date' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_date(self, node): del self.paragraph_properties["date"] self.depart_paragraph(node) def visit_decoration(self, node): pass def depart_decoration(self, node): pass def visit_definition(self, node): self.indentation += 720 self.paragraph_properties["definition"] = ("w:pStyle", {"w:val": "Definition"}) # self.paragraph_properties[ 'definition' ] = '<w:pStyle w:val="Definition" />' def depart_definition(self, node): self.indentation -= 720 del self.paragraph_properties["definition"] def visit_definition_list(self, node): pass def depart_definition_list(self, node): pass def visit_definition_list_item(self, node): pass def depart_definition_list_item(self, node): pass def visit_description(self, node): pass def depart_description(self, node): pass def visit_docinfo(self, node): pass def depart_docinfo(self, node): pass def visit_docinfo_item(self, node, name, meta=1): pass def depart_docinfo_item(self): pass def visit_doctest_block(self, node): pass def depart_doctest_block(self, node): pass def visit_document(self, node): pass def depart_document(self, node): pass def visit_emphasis(self, node): self.text_properties["*"] = ("w:i", {}) # self.text_properties[ '*' ] = '<w:i/>' def depart_emphasis(self, node): del self.text_properties["*"] def calc_col_pct(self, col): width = int(self.colspecs[col]["colwidth"] * 100.0 / self.total_col_width + 0.5) return width def visit_entry(self, node): width = self.calc_col_pct(self.col) self.doc_tree.start("w:tc", {}) self.doc_tree.start("w:tcPr", {}) self.doc_tree.start("w:tcW", {"w": str(width), "w:type": "pct"}) self.doc_tree.end("w:tcW") self.body.append('<w:tc>\n <w:tcPr>\n <w:tcW w="' + str(width) + '" w:type="pct" />\n') self.has_text_output = 0 if node.has_key("morecols") and node.has_key("morerows"): raise NotImplementedError( "Table cell " + str(self.col) + "," + str(self.row) + " can't have both merged rows and columns." ) if node.has_key("morecols"): self.doc_tree.start("w:hmerge", {"w:val": "restart"}) self.doc_tree.end("w:hmerge") self.body.append('<w:hmerge w:val="restart" />') for i in range(node["morecols"]): span = "{" + str(self.col + i + 1) + "," + str(self.row) + "}" self.spans[span] = ("w:hmerge", {}) # '<w:hmerge />' if node.has_key("morerows"): self.doc_tree.start("w:vmerge", {"w:val": "restart"}) self.doc_tree.end("w:vmerge") self.body.append('<w:vmerge w:val="restart" />') for i in range(node["morerows"]): span = "{" + str(self.col) + "," + str(self.row + i + 1) + "}" self.spans[span] = ("w:vmerge", {}) # '<w:vmerge />' self.doc_tree.end("w:tcPr") self.body.append("</w:tcPr>\n") def depart_entry(self, node): if self.has_text_output == 0: self.doc_tree.start("w:p", {}) self.doc_tree.end("w:p") self.body.append(" <w:p />\n") self.doc_tree.end("w:tc") self.body.append("</w:tc>\n") # if there are any cells that are part of a span, then include them here as empty cells. col = self.col + 1 row = self.row while self.check_for_span(col, row): col = col + 1 self.col = col self.row = row def visit_enumerated_list(self, node): # to put any sort of customization in, it's necessary to add an entirely new listDef element. # so, I need to load the listDefs at the beginning of the run, and then customize them as needed. self.list_level += 1 self.list_count += 1 list_props = ( '<w:listPr>\n<w:ilvl w:val="' + str(self.list_level) + '" />\n<w:ilfo w:val="' + str(self.list_count) + '" />\n' ) # if the list has an explicit start, then set the text for it start = 1 if node.has_key("start"): start = int(node["start"]) nfc = 0 if node["enumtype"] == "arabic": nfc = 0 elif node["enumtype"] == "upperalpha": nfc = 3 elif node["enumtype"] == "loweralpha": nfc = 4 elif node["enumtype"] == "lowerroman": nfc = 2 elif node["enumtype"] == "upperroman": nfc = 1 self.list_defs.append(self.listdef_to_xml(0, self.list_level, start, nfc)) self.lists.append( '<w:list w:ilfo="' + str(self.list_count) + '">\n <w:ilst w:val="' + str(self.list_count + 1) + '">\n </w:ilst>\n</w:list>\n' ) list_props += "</w:listPr>\n" self.list_properties.append(list_props) def depart_enumerated_list(self, node): self.show_list_properties -= 1 self.list_properties.pop() self.list_level -= 1 def visit_error(self, node): pass def depart_error(self, node): pass def visit_field(self, node): self.paragraph_properties["field"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # self.paragraph_properties[ 'field' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_field(self, node): del self.paragraph_properties["field"] self.depart_paragraph(node) def visit_field_body(self, node): pass def depart_field_body(self, node): pass def visit_field_list(self, node): pass def depart_field_list(self, node): pass def visit_field_name(self, node): pass def depart_field_name(self, node): pass def visit_figure(self, node): self.in_figure = 1 def depart_figure(self, node): if self.in_figure: self.doc_tree.end("w:p") self.body.append("</w:p>\n") self.in_figure = 0 def visit_footer(self, node): pass def depart_footer(self, node): pass def visit_footnote(self, node): if not self.in_footnote: self.no_text += 1 def depart_footnote(self, node): if not self.in_footnote: self.no_text -= 1 def visit_footnote_reference(self, node): if not node.has_key("auto"): raise TypeError("footnotes required to be auto numbered") footnote = self.document.ids[node["refid"]] if not isinstance(footnote, nodes.footnote): raise TypeError("not a footnote node mapped to id") self.doc_tree.start("w:r", {}) self.doc_tree.start("w:rPr", {}) self.doc_tree.start("w:rStyle", {"w:val": "EndnoteReference"}) self.doc_tree.end("w:rStyle") self.doc_tree.end("w:rPr") self.doc_tree.start("w:endnote", {}) self.body.append('<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnote>\n') # figure out how to get the <w:endnoteRef/> self.in_footnote = 1 former_paragraph_properties = self.paragraph_properties.copy() self.paragraph_properties = {} self.paragraph_properties["footnote"] = ("w:pStyle", {"w:val": "EndnoteText"}) # self.paragraph_properties[ 'footnote' ] = '<w:pStyle w:val="EndnoteText"/>' # self.body.append( '<w:p>\n<w:pPr>\n<w:pStyle w:val="EndnoteText"/>\n</w:pPr>\n<w:r>\n<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n' ) # Find the label in the target footnode node and add it here. labels = footnote.traverse(condition=nodes.label) # replace label text with <w:endnoteRef /> for n in labels: footnote.children.remove(n) # n.children.append( nodes.Text('<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n')) p = footnote.traverse(condition=nodes.paragraph) # t = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n') t = XMLRegion(xml=[("w:endnoteRef", {})], styles=[("w:rStyle", {"w:val": "EndnoteReference"})]) p[0].children.insert(0, t) footnote.walkabout(self) p[0].children.remove(t) self.doc_tree.end("w:endnote") self.doc_tree.end("w:r") self.body.append("</w:endnote>\n</w:r>\n") del self.paragraph_properties["footnote"] self.in_footnote = 0 self.no_text += 1 self.paragraph_properties = former_paragraph_properties def depart_footnote_reference(self, node): # del self.paragraph_properties[ 'footnote' ] # self.in_footnote = 0 self.no_text -= 1 def visit_generated(self, node): pass def depart_generated(self, node): pass def visit_header(self, node): pass def depart_header(self, node): pass def visit_hint(self, node): pass def depart_hint(self, node): pass def visit_image(self, node): width = 100 height = 100 align = "center" use_width = 0 use_height = 0 if Image: try: im = Image.open(node["uri"]) width = im.size[0] height = im.size[1] use_width = 1 use_height = 1 except (IOError, UnicodeError): pass if node.has_key("width"): width = node["width"] use_width = 1 if node.has_key("height"): height = node["height"] use_height = 1 if node.has_key("align"): align = node["align"] self.doc_tree.start("w:p", {}) self.doc_tree.start("w:pPr", {}) self.doc_tree.start("w:jc", {"w:val": str(align)}) self.doc_tree.end("w:jc") self.doc_tree.end("w:pPr") self.doc_tree.start("w:pict", {}) style = "position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:" if use_width: style += str(width) + "px" else: style += "auto" style += ";height:" if use_height: style += str(height) + "px" else: style += "auto" style += ";z-index:1;mso-position-horizontal:center" self.doc_tree.start( "v:shape", { "id": str(self.gen_id()), "style": style, "coordsize": "", "o:spt": "100", "adj": "0,,0", "path": "", "stroked": "f", }, ) self.doc_tree.start("v:imagedata", {"src": node["uri"]}) self.doc_tree.end("v:imagedata") self.doc_tree.start("w10:wrap", {"type": "square"}) self.doc_tree.end("w10:wrap") self.doc_tree.end("v:shape") self.doc_tree.end("w:pict") self.body.append( '<w:p>\n<w:pPr>\n<w:jc w:val="' + str(align) + '" />\n</w:pPr>\n<w:pict>\n<v:shape id="' + str(self.gen_id()) + '" ' ) self.body.append('style="position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:') if use_width: self.body.append(str(width) + "px") else: self.body.append("auto") self.body.append(";height:") if use_height: self.body.append(str(height) + "px") else: self.body.append("auto") self.body.append( ';z-index:1;mso-position-horizontal:center" coordsize="" o:spt="100" adj="0,,0" path="" stroked="f" >\n' ) self.body.append('<v:imagedata src="' + node["uri"] + '"/>\n<w10:wrap type="square"/>\n</v:shape>\n</w:pict>\n') def depart_image(self, node): if not self.in_figure: self.doc_tree.end("w:p") self.body.append("</w:p>\n") def visit_important(self, node): pass def depart_important(self, node): pass def visit_inline(self, node): pass def depart_inline(self, node): pass def visit_label(self, node): self.text_properties["label"] = ("w:rStyle", {"w:val": '"EndnoteReference"'}) # self.text_properties[ 'label' ] = '<w:rStyle w:val="EndnoteReference"/>\n' # if self.in_footnote: # self.no_text += 1 # self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n</w:r>\n' ) pass def depart_label(self, node): del self.text_properties["label"] # if self.in_footnote: # self.no_text -= 1 pass def visit_legend(self, node): pass def depart_legend(self, node): pass def visit_line(self, node): pass def depart_line(self, node): pass def visit_line_block(self, node): pass def depart_line_block(self, node): pass def visit_list_item(self, node): pass def depart_list_item(self, node): pass def visit_literal(self, node): self.text_properties["literal"] = ("w:rStyle", {"w:val": "Literal"}) # self.text_properties[ 'literal' ] = '<w:rStyle w:val="Literal"/>\n' def depart_literal(self, node): del self.text_properties["literal"] def visit_literal_block(self, node): self.paragraph_properties["literal"] = ("w:pStyle", {"w:val": "LiteralBlock"}) # ~ self.paragraph_properties[ 'literal' ] = '<w:pStyle w:val="LiteralBlock" />\n' self.visit_paragraph(node) self.literal_text = 1 def depart_literal_block(self, node): del self.paragraph_properties["literal"] self.depart_paragraph(node) self.literal_text = 0 def visit_meta(self, node): pass def depart_meta(self, node): pass def visit_note(self, node): pass def depart_note(self, node): pass def visit_option(self, node): pass def depart_option(self, node): pass def visit_option_argument(self, node): pass def depart_option_argument(self, node): pass def visit_option_group(self, node): pass def depart_option_group(self, node): pass def visit_option_list(self, node): pass def depart_option_list(self, node): pass def visit_option_list_item(self, node): pass def depart_option_list_item(self, node): pass def visit_option_string(self, node): pass def depart_option_string(self, node): pass def visit_organization(self, node): self.paragraph_properties["organization"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # ~ self.paragraph_properties[ 'organization' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_organization(self, node): del self.paragraph_properties["organization"] self.depart_paragraph(node) def visit_paragraph(self, node): self.doc_tree.start("w:p", {}) self.body.append("<w:p>\n") if ( len(self.paragraph_properties) > 0 or len(self.list_properties) > 0 or (self.indentation > 0 and not self.in_footnote) ): self.doc_tree.start("w:pPr", {}) self.body.append("<w:pPr>\n") if self.indentation > 0 and not self.in_footnote: self.doc_tree.start("w:ind", {"w:left": str(self.indentation), "w:right": str(self.indentation)}) self.doc_tree.end("w:ind") self.body.append( '<w:ind w:left="' + str(self.indentation) + '" w:right="' + str(self.indentation) + '" />\n' ) for v in self.paragraph_properties.values(): if type(v) == type(()): element = "<" + v[0] + " " for k, a in v[1].iteritems(): element += k + '="' + a + '" ' element += "/>" self.doc_tree.start(v[0], v[1]) self.doc_tree.end(v[0]) self.body.append(element) else: self.body.append(v) if len(self.list_properties) > 0 and isinstance(node.parent, nodes.list_item): if type(self.list_properties[-1]) == type(()): t = self.list_properties[-1] element = "<" + t[0] + " " for k, a in t[1].iteritems(): element += k + '="' + a + '" ' element += "/>" self.doc_tree.start(t[0], t[1]) self.doc_tree.end(t[0]) self.body.append(element) else: self.body.append(self.list_properties[-1]) self.doc_tree.end("w:pPr") self.body.append("\n</w:pPr>\n") def depart_paragraph(self, node): self.doc_tree.end("w:p") self.body.append("</w:p>\n") def visit_problematic(self, node): pass def depart_problematic(self, node): pass def visit_raw(self, node): pass def visit_reference(self, node): if node.has_key("refid"): self.doc_tree.start("w:hlink", {"w:bookmark": node["refid"]}) self.body.append('<w:hlink w:bookmark="' + node["refid"] + '" >\n') if node.has_key("refuri"): self.doc_tree.start("w:hlink", {"w:dest": node["refuri"]}) self.body.append('<w:hlink w:dest="' + node["refuri"] + '" >\n') if not node.has_key("refuri") and not node.has_key("refid"): raise NotImplementedError("Unknown reference type") self.text_properties["ref"] = ("w:rStyle", {"w:val": "Hyperlink"}) # ~ self.text_properties['ref'] = '<w:rStyle w:val="Hyperlink" />\n' def depart_reference(self, node): del self.text_properties["ref"] self.doc_tree.end("w:hlink") self.body.append("</w:hlink>\n") def visit_revision(self, node): pass def depart_revision(self, node): pass def visit_row(self, node): self.doc_tree.start("w:tr", {}) self.body.append("<w:tr>\n") while self.check_for_span(self.col, self.row): self.col += 1 def depart_row(self, node): self.row += 1 self.col = 0 self.doc_tree.end("w:tr") self.body.append("</w:tr>\n") def visit_rubric(self, node): pass def depart_rubric(self, node): pass def visit_section(self, node): self.section_level += 1 if self.section_level > 3: raise NotImplementedError("Only 3 levels of headings supported.") if node.has_key("ids"): for id in node["ids"]: refid = self.gen_id() self.doc_tree.start( "aml:annotation", {"aml:id": str(refid), "w:type": "Word.Bookmark.Start", "w:name": id} ) self.doc_tree.end("aml:annotation") self.doc_tree.start( "aml:annotation", {"aml:id": str(refid), "w:type": "Word.Bookmark.End", "w:name": id} ) self.doc_tree.end("aml:annotation") self.body.append( '<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.Start" w:name="' + id + '" />' ) self.body.append( '<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.End" w:name="' + id + '" />' ) def depart_section(self, node): self.section_level -= 1 def visit_sidebar(self, node): pass def depart_sidebar(self, node): pass def visit_status(self, node): self.paragraph_properties["status"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # ~ self.paragraph_properties[ 'status' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_status(self, node): del self.paragraph_properties["status"] self.depart_paragraph(node) def visit_strong(self, node): self.text_properties["**"] = ("w:b", {}) # ~ self.text_properties[ '**' ] = '<w:b/>' def depart_strong(self, node): del self.text_properties["**"] def visit_subscript(self, node): self.text_properties["subscript"] = ("w:vertAlign", {"w:val": "subscript"}) # ~ self.text_properties[ 'subscript' ] = '<w:vertAlign w:val="subscript" />' def depart_subscript(self, node): del self.text_properties["subscript"] def visit_substitution_definition(self, node): raise nodes.SkipNode def visit_substitution_reference(self, node): raise NotImplementedError("substitution references not implemented") def visit_subtitle(self, node): self.paragraph_properties["subtitle"] = ("w:pStyle", {"w:val": self.title_styles[self.section_level + 1]}) # ~ self.paragraph_properties[ 'subtitle' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level + 1 ] + '"/>\n' self.visit_paragraph(node) def depart_subtitle(self, node): del self.paragraph_properties["subtitle"] self.depart_paragraph(node) def visit_superscript(self, node): self.text_properties["superscript"] = ("w:vertAlign", {"w:val": "superscript"}) # ~ self.text_properties[ 'superscript' ] = '<w:vertAlign w:val="superscript" />\n' def depart_superscript(self, node): del self.text_properties["superscript"] def visit_system_message(self, node): pass def depart_system_message(self, node): pass def visit_table(self, node): # include for now the default border around the table with a top vertical alignment self.in_table = 1 self.colspecs = [] self.spans = {} self.total_col_width = 0 self.row = 0 self.col = 0 self.doc_tree.start("w:tbl", {}) self.doc_tree.start("w:tblPr", {}) self.doc_tree.start("w:tblStyle", {"w:val": "Normal"}) self.doc_tree.end("w:tblStyle") self.doc_tree.start("w:tblW", {"w:w": "5000", "w:type": "pct"}) self.doc_tree.end("w:tblW") self.doc_tree.start("w:tblBorders", {}) self.doc_tree.start( "w:top", {"w:val": "single", "w:sz": "4", "wx:bdrwidth": "10", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:top") self.doc_tree.start( "w:left", {"w:val": "single", "w:sz": "4", "wx:bdrwidth": "10", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:left") self.doc_tree.start( "w:bottom", {"w:val": "single", "w:sz": "4", "wx:bdrwidth": "10", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:bottom") self.doc_tree.start( "w:right", {"w:val": "single", "w:sz": "4", "wx:bdrwidth": "10", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:right") self.doc_tree.start( "w:insideH", {"w:val": "single", "w:sz": "6", "wx:bdrwidth": "15", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:insideH") self.doc_tree.start( "w:insideV", {"w:val": "single", "w:sz": "6", "wx:bdrwidth": "15", "w:space": "0", "w:color": "auto"} ) self.doc_tree.end("w:insideV") self.doc_tree.end("w:tblBorders") self.doc_tree.start("w:tblLook", {"w:val": "000001e0"}) self.doc_tree.end("w:tblLook") self.doc_tree.end("w:tblPr") self.body.append( "<w:tbl>\n" " <w:tblPr>\n" ' <w:tblStyle w:val="Normal" />\n' ' <w:tblW w:w="5000" w:type="pct" />\n' " <w:tblBorders>\n" ' <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n' ' <w:insideH w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n' ' <w:insideV w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n' " </w:tblBorders>\n" ' <w:tblLook w:val="000001e0" />\n' " </w:tblPr>\n" ) def depart_table(self, node): self.doc_tree.end("w:tbl") self.doc_tree.start("w:p", {}) self.doc_tree.end("w:p") self.body.append("</w:tbl>\n") self.body.append("<w:p />") # add a blank line after the table self.in_table = 0 def visit_target(self, node): if node.has_key("refid"): refid = self.gen_id() self.doc_tree.start( "aml:annotation", {"aml:id": str(refid), "w:type": "Word.Bookmark.Start", "w:name": node["refid"]} ) self.doc_tree.end("aml:annotation") self.doc_tree.start( "aml:annotation", {"aml:id": str(refid), "w:type": "Word.Bookmark.End", "w:name": node["refid"]} ) self.doc_tree.end("aml:annotation") self.body.append( '<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.Start" w:name="' + node["refid"] + '" />\n' ) self.body.append( '<aml:annotation aml:id="' + str(refid) + '" w:type="Word.Bookmark.End" w:name="' + node["refid"] + '" />\n' ) def depart_target(self, node): pass def visit_tbody(self, node): pass def depart_tbody(self, node): pass def visit_term(self, node): self.paragraph_properties["term"] = ("w:pStyle", {"w:val": "DefinitionTerm"}) # ~ self.paragraph_properties[ 'term' ] = '<w:pStyle w:val="DefinitionTerm" />' self.visit_paragraph(node) def depart_term(self, node): del self.paragraph_properties["term"] self.depart_paragraph(node) def visit_tgroup(self, node): pass def depart_tgroup(self, node): pass def visit_thead(self, node): pass def depart_thead(self, node): pass def visit_tip(self, node): pass def depart_tip(self, node): pass def visit_title(self, node, move_ids=1): self.paragraph_properties["title"] = ("w:pStyle", {"w:val": self.title_styles[self.section_level]}) # ~ self.paragraph_properties[ 'title' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level ] + '"/>\n' self.visit_paragraph(node) def depart_title(self, node): del self.paragraph_properties["title"] self.depart_paragraph(node) def visit_title_reference(self, node): pass def depart_title_reference(self, node): pass def visit_topic(self, node): self.paragraph_properties["topic"] = ("w:pStyle", {"w:val": "Topic"}) # ~ self.paragraph_properties[ 'topic' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_topic(self, node): del self.paragraph_properties["topic"] self.depart_paragraph(node) def visit_transition(self, node): pass def depart_transition(self, node): pass def visit_version(self, node): self.paragraph_properties["version"] = ("w:pStyle", {"w:val": "BibliographMatter"}) # self.paragraph_properties[ 'version' ] = '<w:pStyle w:val="BibliographMatter" />' self.visit_paragraph(node) def depart_version(self, node): del self.paragraph_properties["version"] self.depart_paragraph(node) def visit_warning(self, node): pass def depart_warning(self, node): pass def visit_XMLRegion(self, node): self.doc_tree.start("w:r", {}) self.doc_tree.start("w:rPr", {}) for style in node["styles"]: self.doc_tree.start(style[0], style[1]) self.doc_tree.end(style[0]) self.doc_tree.end("w:rPr") for tag in node["xml"]: self.doc_tree.start(tag[0], tag[1]) self.doc_tree.end(tag[0]) def depart_XMLRegion(self, node): self.doc_tree.end("w:r") def unimplemented_visit(self, node): pass
class EtreeModuleSerializer(ModuleSerializer): def __init__(self, module, flags=types.DEFAULT): super(EtreeModuleSerializer, self).__init__(module, flags) self.stack = [ElementBuilder("module", {}, [])] self.builder = TreeBuilder() self.etree = None def run_ast(self): ast_el = ElementBuilder("ast", {}, []) self.add_child(ast_el) self.stack.append(ast_el) super(EtreeModuleSerializer, self).run_ast() self.stack.pop() def run_tokens(self): tokens_el = ElementBuilder("tokens", {}, []) self.add_child(tokens_el) self.stack.append(tokens_el) super(EtreeModuleSerializer, self).run_tokens() self.stack.pop() def get_root(self): if self.etree is None: assert len(self.stack) == 1 self._build(self.stack[0]) self.etree = ElementTree(self.builder.close()) return self.etree def process_token(self, token, offset): ttype, tval, tstart, tend, tline = token attrs = {"type": repr(ttype), "value": repr(tval).lstrip("u")[1:-1], "offset": repr(offset)} if tstart is not None: attrs.update({"start_line": repr(tstart[0]), "start_col": repr(tstart[1])}) if tend is not None: attrs.update({"end_line": repr(tend[0]), "end_col": repr(tend[1])}) if tline is not None: attrs["line"] = repr(tline).lstrip("u")[1:-1] el = ElementBuilder(tokenize.tok_name[ttype], attrs, []) self.add_child(el) def add_attr(self, attr, value): self.stack[-1].attrs[attr] = value def add_child(self, child): self.stack[-1].children.append(child) def start_ast(self, node): el = ElementBuilder(type(node).__name__, {}, []) line = getattr(node, "lineno", None) if line is not None: el.attrs["line"] = repr(line) col = getattr(node, "col_offset", None) if col is not None: el.attrs["col"] = repr(col) if self.flags & types.TOKENS: n = self.module.ast_map.get(node) if n is not None: if n.token_start < n.token_end: el.attrs["token_start"] = repr(n.token_start) el.attrs["token_end"] = repr(n.token_end) self.add_child(el) self.stack.append(el) def end_ast(self, node): self.stack.pop() def start_list_field(self, field, value): el = ElementBuilder(field, {}, []) self.add_child(el) self.stack.append(el) def end_list_field(self, field, value): self.stack.pop() def process_ast_field(self, field, value): el = ElementBuilder(field, {}, []) self.add_child(el) self.stack.append(el) super(EtreeModuleSerializer, self).process_ast_field(field, value) self.stack.pop() def process_string_field(self, field, value): self.add_attr(field, value) def process_number_field(self, field, value): self.add_attr(field, repr(value)) def process_null_field(self, field): self.add_child(ElementBuilder(field, {}, [])) def _build(self, el): self.builder.start(el.tag, el.attrs) for child in el.children: self._build(child) self.builder.end(el.tag) def write_xml(self, path): etree = self.get_root() if hasattr(path, "write"): etree.write(path, "utf-8") else: with open(path, "w") as f: etree.write(f, "utf-8") def xml_string(self): f = StringIO() self.write_xml(f) f.seek(0) return f.read() def generic_visit(self, node): super(EtreeModuleSerializer, self).generic_visit(node)
def _record_parse(self, key=None, **kwargs): """ Returns an element tree structure corresponding to a toolbox data file with all markers at the same level. Thus the following Toolbox database:: \_sh v3.0 400 Rotokas Dictionary \_DateStampHasFourDigitYear \lx kaa \ps V.A \ge gag \gp nek i pas \lx kaa \ps V.B \ge strangle \gp pasim nek after parsing will end up with the same structure (ignoring the extra whitespace) as the following XML fragment after being parsed by ElementTree:: <toolbox_data> <header> <_sh>v3.0 400 Rotokas Dictionary</_sh> <_DateStampHasFourDigitYear/> </header> <record> <lx>kaa</lx> <ps>V.A</ps> <ge>gag</ge> <gp>nek i pas</gp> </record> <record> <lx>kaa</lx> <ps>V.B</ps> <ge>strangle</ge> <gp>pasim nek</gp> </record> </toolbox_data> :param key: Name of key marker at the start of each record. If set to None (the default value) the first marker that doesn't begin with an underscore is assumed to be the key. :type key: str :param kwargs: Keyword arguments passed to ``StandardFormat.fields()`` :type kwargs: dict :rtype: ElementTree._ElementInterface :return: contents of toolbox data divided into header and records """ builder = TreeBuilder() builder.start('toolbox_data', {}) builder.start('header', {}) in_records = False for mkr, value in self.fields(**kwargs): if key is None and not in_records and mkr[0] != '_': key = mkr if mkr == key: if in_records: builder.end('record') else: builder.end('header') in_records = True builder.start('record', {}) builder.start(mkr, {}) builder.data(value) builder.end(mkr) if in_records: builder.end('record') else: builder.end('header') builder.end('toolbox_data') return builder.close()
def start(self, tag, attrs=None): if attrs is None: attrs = {} _TreeBuilder.start(self, tag, attrs)
def scheme_to_etree(scheme, data_format="literal", pickle_fallback=False): """ Return an `xml.etree.ElementTree` representation of the `scheme. """ builder = TreeBuilder(element_factory=Element) builder.start( "scheme", { "version": "2.0", "title": scheme.title or "", "description": scheme.description or "" }) ## Nodes node_ids = defaultdict(inf_range().next) builder.start("nodes", {}) for node in scheme.nodes: desc = node.description attrs = { "id": str(node_ids[node]), "name": desc.name, "qualified_name": desc.qualified_name, "project_name": desc.project_name or "", "version": desc.version or "", "title": node.title, } if node.position is not None: attrs["position"] = str(node.position) if type(node) is not SchemeNode: attrs["scheme_node_type"] = "%s.%s" % (type(node).__name__, type(node).__module__) builder.start("node", attrs) builder.end("node") builder.end("nodes") ## Links link_ids = defaultdict(inf_range().next) builder.start("links", {}) for link in scheme.links: source = link.source_node sink = link.sink_node source_id = node_ids[source] sink_id = node_ids[sink] attrs = { "id": str(link_ids[link]), "source_node_id": str(source_id), "sink_node_id": str(sink_id), "source_channel": link.source_channel.name, "sink_channel": link.sink_channel.name, "enabled": "true" if link.enabled else "false", } builder.start("link", attrs) builder.end("link") builder.end("links") ## Annotations annotation_ids = defaultdict(inf_range().next) builder.start("annotations", {}) for annotation in scheme.annotations: annot_id = annotation_ids[annotation] attrs = {"id": str(annot_id)} data = None if isinstance(annotation, SchemeTextAnnotation): tag = "text" attrs.update({"rect": repr(annotation.rect)}) # Save the font attributes font = annotation.font attrs.update({ "font-family": font.get("family", None), "font-size": font.get("size", None) }) attrs = [(key, value) for key, value in attrs.items() \ if value is not None] attrs = dict((key, unicode(value)) for key, value in attrs) data = annotation.text elif isinstance(annotation, SchemeArrowAnnotation): tag = "arrow" attrs.update({ "start": repr(annotation.start_pos), "end": repr(annotation.end_pos) }) # Save the arrow color try: color = annotation.color attrs.update({"fill": color}) except AttributeError: pass data = None else: log.warning("Can't save %r", annotation) continue builder.start(tag, attrs) if data is not None: builder.data(data) builder.end(tag) builder.end("annotations") builder.start("thumbnail", {}) builder.end("thumbnail") # Node properties/settings builder.start("node_properties", {}) for node in scheme.nodes: data = None if node.properties: try: data, format = dumps(node.properties, format=data_format, pickle_fallback=pickle_fallback) except Exception: log.error("Error serializing properties for node %r", node.title, exc_info=True) if data is not None: builder.start("properties", { "node_id": str(node_ids[node]), "format": format }) builder.data(data) builder.end("properties") builder.end("node_properties") builder.end("scheme") root = builder.close() tree = ElementTree(root) return tree
import sys data = json.load(open(sys.argv[1], "r")) route = data["plusService"]["route"] builder = TreeBuilder() gpxAttrs = { "version": "1.1", "creator": "Nike2GPX", "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "xmlns": "http://www.topografix.com/GPX/1/1", "xsi:schemaLocation": "http://www.topografix.com/GPX/1/1 http://www.topografix.com/gpx/1/1/gpx.xsd" } builder.start("gpx", gpxAttrs) builder.start("metadata", {}) builder.start("name", {}) builder.data("Run " + sys.argv[1][:-5]) builder.end("name") minLon = 10000 maxLon = -10000 minLat = 10000 maxLat = -10000 for waypoint in route["waypointList"]: if waypoint["lon"] > maxLon: maxLon = waypoint["lon"] if waypoint["lon"] < minLon:
class HTMLBuilder(Builder): """HTML builder.""" FORMAT = { xmltags.BOLD: html_tags.BOLD, xmltags.ITALIC: html_tags.ITALIC, xmltags.STRIKETHROUGH: html_tags.STRIKETROUGH, } LIST = { xmltags.BULLET_LIST: html_tags.UNORDERED_LIST, xmltags.NUMBERED_LIST: html_tags.ORDERED_LIST, xmltags.LIST_ITEM: html_tags.LIST_ITEM, } STYLESHEET = "ICTU-Kwaliteitsaanpak.css" def __init__(self, filename: pathlib.Path, stylesheet_path: pathlib.Path) -> None: super().__init__(filename) self.stylesheet_path = stylesheet_path self.builder = TreeBuilder() self.heading_class: List[str] = [] # Heading class stack self.heading_level: List[int] = [] # Heading level stack self.table_cell_html_tag: Optional[str] = None self.in_keep_together_div = False self.in_measure = False self.frontpage_done = False def start_element(self, tag: str, attributes: TreeBuilderAttributes) -> None: # pylint:disable=too-many-branches if tag == xmltags.DOCUMENT: self.builder.start(html_tags.HTML, {html_tags.LANGUAGE: "nl"}) self.builder.start(html_tags.HEAD, {}) self.builder.start(html_tags.META, {html_tags.META_CHARSET: "UTF-8"}) self.builder.end(html_tags.META) self.builder.start(html_tags.TITLE, {}) self.builder.data(f"{attributes['title']} versie {attributes['version']}") self.builder.end(html_tags.TITLE) self.builder.start( html_tags.LINK, {html_tags.LINK_REL: "stylesheet", html_tags.LINK_HREF: self.STYLESHEET}, ) self.builder.end(html_tags.LINK) self.builder.end(html_tags.HEAD) self.builder.start(html_tags.BODY, {}) elif tag == xmltags.PARAGRAPH: if not self.in_measure: self.builder.start(html_tags.PARAGRAPH, attributes) elif tag in self.LIST: self.builder.start(self.LIST[tag], {}) elif tag in self.FORMAT: self.builder.start(self.FORMAT[tag], {}) elif tag == xmltags.SECTION: self.heading_class.append("bijlage" if attributes.get(xmltags.SECTION_IS_APPENDIX) else "") self.heading_level.append(int(attributes[xmltags.SECTION_LEVEL])) elif tag == xmltags.TABLE: self.builder.start(html_tags.TABLE, {}) elif tag == xmltags.TABLE_HEADER_ROW: self.table_cell_html_tag = html_tags.TABLE_HEAD_CELL self.builder.start(html_tags.TABLE_HEAD, {}) self.builder.start(html_tags.TABLE_ROW, {}) elif tag == xmltags.TABLE_ROW: self.table_cell_html_tag = html_tags.TABLE_BODY_CELL self.builder.start(html_tags.TABLE_ROW, {}) elif tag == xmltags.TABLE_CELL: assert self.table_cell_html_tag alignment = str(attributes[xmltags.TABLE_CELL_ALIGNMENT]) self.builder.start(self.table_cell_html_tag, {html_tags.STYLE: f"text-align:{alignment}"}) elif tag == xmltags.ANCHOR: self.builder.start( html_tags.ANCHOR, {html_tags.ANCHOR_LINK: attributes[xmltags.ANCHOR_LINK]}, ) elif tag == xmltags.IMAGE: image_attributes = { html_tags.STYLE: "max-width: 100%", html_tags.IMAGE_SOURCE: attributes["src"], } title = attributes.get("title", "") alt = attributes.get("alt", "") image_attributes[html_tags.IMAGE_ALT] = f"{title}{': ' if title and alt else ''}{alt}" self.builder.start(html_tags.IMAGE, image_attributes) self.builder.end(html_tags.IMAGE) elif tag == xmltags.MEASURE: self.builder.start(html_tags.PARAGRAPH, {html_tags.CLASS: "maatregel"}) self.in_measure = True def text(self, tag: str, text: str, attributes: TreeBuilderAttributes) -> None: if tag == xmltags.TITLE: title = html_tags.PARAGRAPH self.builder.start(title, {html_tags.CLASS: "title"}) self.builder.data(text) self.builder.end(title) if tag == xmltags.HEADING: if self.heading_level[-1] > 1 and not self.in_keep_together_div: self.builder.start(html_tags.DIV, {html_tags.CLASS: "keep-together"}) self.in_keep_together_div = True heading_attributes: TreeBuilderAttributes = ( {html_tags.CLASS: self.heading_class[-1]} if self.heading_class[-1] else {} ) if self.heading_level[-1] <= 2: heading_attributes["id"] = slugify(text) self.builder.start(html_tags.HEADING + str(self.heading_level[-1]), heading_attributes) if tag not in (xmltags.IMAGE, xmltags.HEADER, xmltags.TITLE): self.builder.data(text) def end_element(self, tag: str, attributes: TreeBuilderAttributes) -> None: if tag == xmltags.DOCUMENT: self.builder.end(html_tags.BODY) self.builder.end(html_tags.HTML) elif tag == xmltags.FRONTPAGE: self.frontpage_done = True elif tag == xmltags.PARAGRAPH: self.end_paragraph() elif tag in self.LIST: self.end_list(tag) elif tag in self.FORMAT: self.builder.end(self.FORMAT[tag]) elif tag == xmltags.SECTION: self.heading_class.pop() self.heading_level.pop() elif tag == xmltags.HEADING: self.builder.end(html_tags.HEADING + str(self.heading_level[-1])) elif tag == xmltags.TABLE: self.builder.end(html_tags.TABLE_BODY) self.builder.end(html_tags.TABLE) elif tag == xmltags.TABLE_HEADER_ROW: self.builder.end(html_tags.TABLE_ROW) self.builder.end(html_tags.TABLE_HEAD) self.builder.start(html_tags.TABLE_BODY, {}) elif tag == xmltags.TABLE_ROW: self.builder.end(html_tags.TABLE_ROW) elif tag == xmltags.TABLE_CELL: assert self.table_cell_html_tag self.builder.end(self.table_cell_html_tag) elif tag == xmltags.ANCHOR: self.builder.end(html_tags.ANCHOR) elif tag == xmltags.MEASURE: self.builder.end(html_tags.PARAGRAPH) self.in_measure = False def end_paragraph(self) -> None: """End the paragraph.""" if self.in_measure: self.builder.start(html_tags.LINE_BREAK, {}) self.builder.end(html_tags.LINE_BREAK) else: self.builder.end(html_tags.PARAGRAPH) if self.in_keep_together_div: self.in_keep_together_div = False self.builder.end(html_tags.DIV) def end_list(self, tag: str) -> None: """End the list.""" self.builder.end(self.LIST[tag]) if tag in (xmltags.NUMBERED_LIST, xmltags.BULLET_LIST) and self.in_keep_together_div: self.in_keep_together_div = False self.builder.end(html_tags.DIV) def end_document(self) -> None: tree = ElementTree(self.builder.close()) with open(self.filename, mode="w", encoding="utf-8") as html_file: html_file.write("<!DOCTYPE html>\n") tree.write(html_file, "unicode", method="html")
def start(self, tag, attrib={}, **extra): attrib = attrib.copy() attrib.update(extra) return TreeBuilder.start(self, tag, attrib)