Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/docutils/writers/docutils_xml.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
1 # $Id: docutils_xml.py 8368 2019-08-27 12:10:14Z milde $ | |
2 # Author: David Goodger, Paul Tremblay, Guenter Milde | |
3 # Maintainer: docutils-develop@lists.sourceforge.net | |
4 # Copyright: This module has been placed in the public domain. | |
5 | |
6 """ | |
7 Simple document tree Writer, writes Docutils XML according to | |
8 http://docutils.sourceforge.net/docs/ref/docutils.dtd. | |
9 """ | |
10 | |
11 __docformat__ = 'reStructuredText' | |
12 | |
13 import sys | |
14 import xml.sax.saxutils | |
15 | |
16 import docutils | |
17 from docutils import frontend, writers, nodes | |
18 | |
19 if sys.version_info >= (3, 0): | |
20 from io import StringIO # noqa | |
21 else: | |
22 from StringIO import StringIO # noqa | |
23 | |
24 | |
25 if sys.version_info >= (3, 0): | |
26 unicode = str # noqa | |
27 | |
28 | |
29 class RawXmlError(docutils.ApplicationError): pass | |
30 | |
31 | |
32 class Writer(writers.Writer): | |
33 | |
34 supported = ('xml',) | |
35 """Formats this writer supports.""" | |
36 | |
37 settings_spec = ( | |
38 '"Docutils XML" Writer Options', | |
39 None, | |
40 (('Generate XML with newlines before and after tags.', | |
41 ['--newlines'], | |
42 {'action': 'store_true', 'validator': frontend.validate_boolean}), | |
43 ('Generate XML with indents and newlines.', | |
44 ['--indents'], #@ TODO use integer value for number of spaces? | |
45 {'action': 'store_true', 'validator': frontend.validate_boolean}), | |
46 ('Omit the XML declaration. Use with caution.', | |
47 ['--no-xml-declaration'], | |
48 {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', | |
49 'validator': frontend.validate_boolean}), | |
50 ('Omit the DOCTYPE declaration.', | |
51 ['--no-doctype'], | |
52 {'dest': 'doctype_declaration', 'default': 1, | |
53 'action': 'store_false', 'validator': frontend.validate_boolean}),)) | |
54 | |
55 settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'} | |
56 | |
57 config_section = 'docutils_xml writer' | |
58 config_section_dependencies = ('writers',) | |
59 | |
60 output = None | |
61 """Final translated form of `document`.""" | |
62 | |
63 def __init__(self): | |
64 writers.Writer.__init__(self) | |
65 self.translator_class = XMLTranslator | |
66 | |
67 def translate(self): | |
68 self.visitor = visitor = self.translator_class(self.document) | |
69 self.document.walkabout(visitor) | |
70 self.output = ''.join(visitor.output) | |
71 | |
72 | |
73 class XMLTranslator(nodes.GenericNodeVisitor): | |
74 | |
75 xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' | |
76 # TODO: add stylesheet options similar to HTML and LaTeX writers? | |
77 #xml_stylesheet = '<?xml-stylesheet type="text/xsl" href="%s"?>\n' | |
78 doctype = ( | |
79 '<!DOCTYPE document PUBLIC' | |
80 ' "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML"' | |
81 ' "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n') | |
82 generator = '<!-- Generated by Docutils %s -->\n' | |
83 | |
84 xmlparser = xml.sax.make_parser() | |
85 """SAX parser instance to check/exctract raw XML.""" | |
86 xmlparser.setFeature( | |
87 "http://xml.org/sax/features/external-general-entities", True) | |
88 | |
89 def __init__(self, document): | |
90 nodes.NodeVisitor.__init__(self, document) | |
91 | |
92 # Reporter | |
93 self.warn = self.document.reporter.warning | |
94 self.error = self.document.reporter.error | |
95 | |
96 # Settings | |
97 self.settings = settings = document.settings | |
98 self.indent = self.newline = '' | |
99 if settings.newlines: | |
100 self.newline = '\n' | |
101 if settings.indents: | |
102 self.newline = '\n' | |
103 self.indent = ' ' #@ TODO make this configurable? | |
104 self.level = 0 # indentation level | |
105 self.in_simple = 0 # level of nesting inside mixed-content elements | |
106 self.fixed_text = 0 # level of nesting inside FixedText elements | |
107 | |
108 # Output | |
109 self.output = [] | |
110 if settings.xml_declaration: | |
111 self.output.append( | |
112 self.xml_declaration % settings.output_encoding) | |
113 if settings.doctype_declaration: | |
114 self.output.append(self.doctype) | |
115 self.output.append(self.generator % docutils.__version__) | |
116 | |
117 # initialize XML parser | |
118 self.the_handle=TestXml() | |
119 self.xmlparser.setContentHandler(self.the_handle) | |
120 | |
121 # generic visit and depart methods | |
122 # -------------------------------- | |
123 | |
124 simple_nodes = (nodes.TextElement, | |
125 nodes.image, nodes.colspec, nodes.transition) # empty elements | |
126 | |
127 def default_visit(self, node): | |
128 """Default node visit method.""" | |
129 if not self.in_simple: | |
130 self.output.append(self.indent*self.level) | |
131 self.output.append(node.starttag(xml.sax.saxutils.quoteattr)) | |
132 self.level += 1 | |
133 # @@ make nodes.literal an instance of FixedTextElement? | |
134 if isinstance(node, (nodes.FixedTextElement, nodes.literal)): | |
135 self.fixed_text += 1 | |
136 if isinstance(node, self.simple_nodes): | |
137 self.in_simple += 1 | |
138 if not self.in_simple: | |
139 self.output.append(self.newline) | |
140 | |
141 def default_departure(self, node): | |
142 """Default node depart method.""" | |
143 self.level -= 1 | |
144 if not self.in_simple: | |
145 self.output.append(self.indent*self.level) | |
146 self.output.append(node.endtag()) | |
147 if isinstance(node, (nodes.FixedTextElement, nodes.literal)): | |
148 self.fixed_text -= 1 | |
149 if isinstance(node, self.simple_nodes): | |
150 self.in_simple -= 1 | |
151 if not self.in_simple: | |
152 self.output.append(self.newline) | |
153 | |
154 | |
155 # specific visit and depart methods | |
156 # --------------------------------- | |
157 | |
158 def visit_Text(self, node): | |
159 text = xml.sax.saxutils.escape(node.astext()) | |
160 # indent text if we are not in a FixedText element: | |
161 if not self.fixed_text: | |
162 text = text.replace('\n', '\n'+self.indent*self.level) | |
163 self.output.append(text) | |
164 | |
165 def depart_Text(self, node): | |
166 pass | |
167 | |
168 def visit_raw(self, node): | |
169 if 'xml' not in node.get('format', '').split(): | |
170 # skip other raw content? | |
171 # raise nodes.SkipNode | |
172 self.default_visit(node) | |
173 return | |
174 # wrap in <raw> element | |
175 self.default_visit(node) # or not? | |
176 xml_string = node.astext() | |
177 self.output.append(xml_string) | |
178 self.default_departure(node) # or not? | |
179 # Check validity of raw XML: | |
180 if isinstance(xml_string, unicode) and sys.version_info < (3, 0): | |
181 xml_string = xml_string.encode('utf8') | |
182 try: | |
183 self.xmlparser.parse(StringIO(xml_string)) | |
184 except xml.sax._exceptions.SAXParseException as error: | |
185 col_num = self.the_handle.locator.getColumnNumber() | |
186 line_num = self.the_handle.locator.getLineNumber() | |
187 srcline = node.line | |
188 if not isinstance(node.parent, nodes.TextElement): | |
189 srcline += 2 # directive content start line | |
190 msg = 'Invalid raw XML in column %d, line offset %d:\n%s' % ( | |
191 col_num, line_num, node.astext()) | |
192 self.warn(msg, source=node.source, line=srcline+line_num-1) | |
193 raise nodes.SkipNode # content already processed | |
194 | |
195 | |
196 class TestXml(xml.sax.handler.ContentHandler): | |
197 | |
198 def setDocumentLocator(self, locator): | |
199 self.locator = locator |