def _docutils_rest_to(rest, writer): """ Uses docutils to convert a ReST string to HTML. Returns a tuple containg the HTML string and the list of warning nodes that were removed from the HTML. """ # Make sure any Sphinx polution of docutils has been removed. if Sphinx is not None: for key, value in docutils_roles.items(): if value.__module__.startswith('sphinx'): docutils_roles.pop(key) pub = Publisher(source_class=docutils.io.StringInput, destination_class=docutils.io.StringOutput) pub.set_reader('standalone', None, 'restructuredtext') pub.set_writer(writer) pub.writer.default_stylesheet_path='' pub.get_settings() # Get the default settings pub.settings.halt_level = 6 # Don't halt on errors pub.settings.warning_stream = StringIO() pub.set_source(rest) pub.set_destination() pub.document = pub.reader.read(pub.source, pub.parser, pub.settings) pub.apply_transforms() # Walk the node structure of a docutils document and remove 'problematic' # and 'system_message' nodes. Save the system_message nodes. warning_nodes = [] for node in pub.document.traverse(docutils.nodes.problematic): node.parent.replace(node, node.children[0]) for node in pub.document.traverse(docutils.nodes.system_message): warning_nodes.append(node) node.parent.remove(node) return pub.writer.write(pub.document, pub.destination), warning_nodes
def read_doc(app, env, filename): # type: (Sphinx, BuildEnvironment, unicode) -> nodes.document """Parse a document and convert to doctree.""" filetype = get_filetype(app.config.source_suffix, filename) input_class = app.registry.get_source_input(filetype) reader = SphinxStandaloneReader(app) source = input_class(app, env, source=None, source_path=filename, encoding=env.config.source_encoding) parser = app.registry.create_source_parser(app, filetype) if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == (): # a workaround for recommonmark # If recommonmark.AutoStrictify is enabled, the parser invokes reST parser # internally. But recommonmark-0.4.0 does not provide settings_spec for reST # parser. As a workaround, this copies settings_spec for RSTParser to the # CommonMarkParser. parser.settings_spec = RSTParser.settings_spec pub = Publisher(reader=reader, parser=parser, writer=SphinxDummyWriter(), source_class=SphinxDummySourceClass, destination=NullOutput()) pub.set_components(None, 'restructuredtext', None) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source, filename) pub.publish() return pub.document
def publish(writer_name): reader=None reader_name='standalone' parser=None parser_name='restructuredtext' writer=None settings=None settings_spec=None settings_overrides=options[writer_name] config_section=None enable_exit=1 argv=[] usage=default_usage pub = Publisher(reader, parser, writer, settings=settings) pub.set_components(reader_name, parser_name, writer_name) settings = pub.get_settings(settings_spec=settings_spec, config_section=config_section) if settings_overrides: settings._update(settings_overrides, 'loose') source = file(source_path) pub.set_source(source, source_path) destination_path = 'pg1.' + extensions[writer_name] destination = file(destination_path, 'w') pub.set_destination(destination, destination_path) pub.publish(argv, usage, description, settings_spec, settings_overrides, config_section=config_section, enable_exit=enable_exit)
def parse_docstring(doc): p = Publisher(source=doc, source_class=io.StringInput) p.set_reader('standalone', p.parser, 'restructuredtext') p.writer = Writer() p.process_programmatic_settings(None, None, None) p.set_source(doc, None) return p.publish()
def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.document: """Parse a document and convert to doctree.""" # set up error_handler for the target document error_handler = UnicodeDecodeErrorHandler(env.docname) codecs.register_error('sphinx', error_handler) # type: ignore reader = SphinxStandaloneReader() reader.setup(app) filetype = get_filetype(app.config.source_suffix, filename) parser = app.registry.create_source_parser(app, filetype) if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == ( ): # a workaround for recommonmark # If recommonmark.AutoStrictify is enabled, the parser invokes reST parser # internally. But recommonmark-0.4.0 does not provide settings_spec for reST # parser. As a workaround, this copies settings_spec for RSTParser to the # CommonMarkParser. parser.settings_spec = RSTParser.settings_spec pub = Publisher(reader=reader, parser=parser, writer=SphinxDummyWriter(), source_class=SphinxFileInput, destination=NullOutput()) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source_path=filename) pub.publish() return pub.document
def inspect(filename, source_path=None): "returns the document object before any transforms)" from docutils.core import Publisher pub = Publisher(source_class=io.FileInput) pub.set_reader("standalone", None, "restructuredtext") pub.process_programmatic_settings(None, None, None) pub.set_source(source_path=source_path) pub.set_io() return pub.reader.read(pub.source, pub.parser, pub.settings)
def get_html(self, body_only=True, content_only=False, noclasses=False): import sys import pygments_rest from docutils.core import Publisher from docutils.io import StringInput, StringOutput from cStringIO import StringIO settings = { 'doctitle_xform': 1, 'pep_references': 1, 'rfc_references': 1, 'footnote_references': 'superscript', 'output_encoding': 'unicode', 'report_level': 2, # 2=show warnings, 3=show only errors, 5=off (docutils.utils } if content_only: post_rst = self.get_rst(noclasses=noclasses) else: post_rst = render_to('post_single.rst', post=self, noclasses=noclasses) pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=StringInput, destination_class=StringOutput) pub.set_components(reader_name='standalone', parser_name='restructuredtext', writer_name='html') pub.process_programmatic_settings(settings_spec=None, settings_overrides=settings, config_section=None) pub.set_source(post_rst, source_path=self.module_path) pub.set_destination(None, None) errors_io = StringIO() real_stderr = sys.stderr sys.stderr = errors_io try: html_full = pub.publish(enable_exit_status=False) html_body = ''.join(pub.writer.html_body) finally: sys.stderr = real_stderr errors = errors_io.getvalue() self._process_rest_errors(errors) errors_io.close() return html_body if body_only else html_full
def inspect( filename, source_path=None, ): "returns the document object before any transforms)" from docutils.core import Publisher pub = Publisher(source_class=io.FileInput, ) pub.set_reader('standalone', None, "restructuredtext") pub.process_programmatic_settings(None, None, None) pub.set_source(source_path=source_path) pub.set_io() return pub.reader.read(pub.source, pub.parser, pub.settings)
def convert(infilename, outfilename): print "converting %s to %s" % (infilename, outfilename) pub = Publisher() pub.set_components('standalone', # reader 'restructuredtext', # parser 'latex') # writer (arg, will be discarded) pub.reader = StandaloneReader() pub.writer = VerseLaTeXWriter() pub.process_programmatic_settings(None, None, None) pub.set_source(source_path=infilename) pub.set_destination(destination_path=outfilename) pub.publish()
def get_html(self, body_only=True, content_only=False, noclasses=False): import sys import pygments_rest from docutils.core import Publisher from docutils.io import StringInput, StringOutput from cStringIO import StringIO settings = {'doctitle_xform' : 1, 'pep_references' : 1, 'rfc_references' : 1, 'footnote_references': 'superscript', 'output_encoding' : 'unicode', 'report_level' : 2, # 2=show warnings, 3=show only errors, 5=off (docutils.utils } if content_only: post_rst = self.get_rst(noclasses=noclasses) else: post_rst = render_to('post_single.rst', post=self, noclasses=noclasses) pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=StringInput, destination_class=StringOutput) pub.set_components(reader_name='standalone', parser_name='restructuredtext', writer_name='html') pub.process_programmatic_settings(settings_spec=None, settings_overrides=settings, config_section=None) pub.set_source(post_rst,source_path=self.module_path) pub.set_destination(None, None) errors_io = StringIO() real_stderr = sys.stderr sys.stderr = errors_io try: html_full = pub.publish(enable_exit_status=False) html_body = ''.join(pub.writer.html_body) finally: sys.stderr = real_stderr errors = errors_io.getvalue() self._process_rest_errors(errors) errors_io.close() return html_body if body_only else html_full
def convert(infilename, outfilename): print "converting %s to %s" % (infilename, outfilename) pub = Publisher() pub.set_components( 'standalone', # reader 'restructuredtext', # parser 'latex') # writer (arg, will be discarded) pub.reader = OptikReader() pub.writer = PyLaTeXWriter() pub.process_programmatic_settings(None, None, None) pub.set_source(source_path=infilename) pub.set_destination(destination_path=outfilename) pub.publish()
def process_labels(site, logger, source, post): site.processing_labels = True pub = Publisher(reader=Reader(), parser=None, writer=None) pub.set_components(None, 'restructuredtext', 'html') # Reading the file will generate output/errors that we don't care about # at this stage. The report_level = 5 means no output pub.process_programmatic_settings( settings_spec=None, settings_overrides={'report_level': 5}, config_section=None, ) pub.set_source(None, source) pub.publish() document = pub.document site.processing_labels = False # Code based on Sphinx std domain for name, is_explicit in document.nametypes.items(): if not is_explicit: continue labelid = document.nameids[name] if labelid is None: continue node = document.ids[labelid] if node.tagname == 'target' and 'refid' in node: node = document.ids.get(node['refid']) labelid = node['names'][0] if node.tagname == 'footnote' or 'refuri' in node or node.tagname.startswith( 'desc_'): continue if name in site.ref_labels: logger.warn( 'Duplicate label {dup}, other instance in {other}'.format( dup=name, other=site.ref_labels[name][0])) site.anon_ref_labels[name] = post.permalink(), labelid def clean_astext(node): """Like node.astext(), but ignore images. Taken from sphinx.util.nodes""" node = node.deepcopy() for img in node.traverse(nodes.image): img['alt'] = '' for raw in node.traverse(nodes.raw): raw.parent.remove(raw) return node.astext() if node.tagname in ('section', 'rubric'): sectname = clean_astext(node[0]) else: continue site.ref_labels[name] = post.permalink(), labelid, sectname
class HTMLGenerator: """ Really simple HTMLGenerator starting from publish_parts It reuses the docutils.core.Publisher class, which means it is *not* threadsafe. """ def __init__(self, settings_spec=None, settings_overrides=None, config_section='general'): if settings_overrides is None: settings_overrides = {'report_level': 5, 'halt_level': 5} self.pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=io.StringInput, destination_class=io.StringOutput) self.pub.set_components(reader_name='standalone', parser_name='restructuredtext', writer_name='html') # hack: JEP-0071 does not allow HTML char entities, so we hack our way # out of it. # — == u"\u2014" # a setting to only emit charater entities in the writer would be nice # FIXME: several are emitted, and they are explicitly forbidden # in the JEP # == u"\u00a0" self.pub.writer.translator_class.attribution_formats['dash'] = ( '\u2014', '') self.pub.process_programmatic_settings(settings_spec, settings_overrides, config_section) def create_xhtml(self, text, destination=None, destination_path=None, enable_exit_status=None): """ Create xhtml for a fragment of IM dialog. We can use the source_name to store info about the message """ self.pub.set_source(text, None) self.pub.set_destination(destination, destination_path) output = self.pub.publish(enable_exit_status=enable_exit_status) # kludge until we can get docutils to stop generating (rare) # entities return '\u00a0'.join( self.pub.writer.parts['fragment'].strip().split(' '))
def _get_publisher(self, source_path): extra_params = {'initial_header_level': '2', 'syntax_highlight': 'short', 'input_encoding': 'utf-8'} user_params = self.settings.get('DOCUTILS_SETTINGS') if user_params: extra_params.update(user_params) pub = Publisher(destination_class=StringOutput) pub.set_components('standalone', 'restructuredtext', 'html') pub.writer.translator_class = HTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish() return pub
def read_doc(app, env, filename): # type: (Sphinx, BuildEnvironment, unicode) -> nodes.document """Parse a document and convert to doctree.""" reader = SphinxStandaloneReader(app, parsers=app.registry.get_source_parsers()) source = SphinxFileInput(app, env, source=None, source_path=filename, encoding=env.config.source_encoding) pub = Publisher(reader=reader, writer=SphinxDummyWriter(), source_class=SphinxDummySourceClass, destination=NullOutput()) pub.set_components(None, 'restructuredtext', None) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source, filename) pub.publish() return pub.document
def check_rst(self, rst): pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=io.StringInput, destination_class=io.StringOutput) pub.set_components(reader_name='standalone', parser_name='restructuredtext', writer_name='pseudoxml') pub.process_programmatic_settings( settings_spec=None, settings_overrides={'output_encoding': 'unicode'}, config_section=None, ) pub.set_source(rst, source_path=None) pub.set_destination(destination=None, destination_path=None) output = pub.publish(enable_exit_status=False) self.assertLess(pub.document.reporter.max_level, 0) return output, pub
def render_map(builder, node): if node: doc = new_document(b('<partial node>')) doc.append(node) publisher = Publisher( source_class = DocTreeInput, destination_class=StringOutput) publisher.set_components('standalone', 'restructuredtext', 'pseudoxml') publisher.reader = DoctreeReader() publisher.writer = DitaMapWriter(builder) publisher.process_programmatic_settings(None, {'output_encoding': 'utf-8'}, None) publisher.set_source(doc, None) publisher.set_destination(None, None) publisher.publish() return publisher.writer.output output = XML_HEAD output += u"<map></map>" return output
def _get_publisher(self, source_path): extra_params = { "initial_header_level": "2", "syntax_highlight": "short", "input_encoding": "utf-8", } user_params = self.settings.get("DOCUTILS_SETTINGS") if user_params: extra_params.update(user_params) pub = Publisher(destination_class=StringOutput) pub.set_components("standalone", "restructuredtext", "html") pub.writer.translator_class = HTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish() return pub
def _get_publisher(self, source_path): extra_params = { 'initial_header_level': '2', 'syntax_highlight': 'short', 'input_encoding': 'utf-8' } user_params = self.settings.get('DOCUTILS_SETTINGS') if user_params: extra_params.update(user_params) pub = Publisher(destination_class=StringOutput) pub.set_components('standalone', 'restructuredtext', 'html') pub.writer.translator_class = HTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish() return pub
def publish_doctree(source, logger): # type: (str, Any) -> Node pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=io.StringInput, destination_class=io.NullOutput) pub.reader = Reader(None, 'restructuredtext') pub.reader.doc_logger = logger pub.set_writer('null') pub.parser = pub.reader.parser pub.process_programmatic_settings(None, None, None) pub.set_source(source, None) pub.set_destination(None, None) output = pub.publish(enable_exit_status=False) return pub.document
class HTMLGenerator: '''Really simple HTMLGenerator starting from publish_parts. It reuses the docutils.core.Publisher class, which means it is *not* threadsafe. ''' def __init__(self, settings_spec=None, settings_overrides=dict(report_level=5, halt_level=5), config_section='general'): self.pub = Publisher(reader=None, parser=None, writer=None, settings=None, source_class=io.StringInput, destination_class=io.StringOutput) self.pub.set_components(reader_name='standalone', parser_name='restructuredtext', writer_name='html') # hack: JEP-0071 does not allow HTML char entities, so we hack our way # out of it. # — == u"\u2014" # a setting to only emit charater entities in the writer would be nice # FIXME: several are emitted, and they are explicitly forbidden # in the JEP # == u"\u00a0" self.pub.writer.translator_class.attribution_formats['dash'] = ( u'\u2014', '') self.pub.process_programmatic_settings(settings_spec, settings_overrides, config_section) def create_xhtml(self, text, destination=None, destination_path=None, enable_exit_status=None): ''' Create xhtml for a fragment of IM dialog. We can use the source_name to store info about the message.''' self.pub.set_source(text, None) self.pub.set_destination(destination, destination_path) output = self.pub.publish(enable_exit_status=enable_exit_status) # kludge until we can get docutils to stop generating (rare) # entities return u'\u00a0'.join(self.pub.writer.parts['fragment'].strip().split( ' '))
def publish_string_with_traceback(reader=None,reader_name=None, parser_name=None,writer_name=None, source=None,source_path=None): """A modified version of publish_string, so I can request traceback. """ from docutils.core import Publisher from docutils import io pub = Publisher(reader=reader, source_class=io.StringInput, destination_class=io.StringOutput) pub.set_components(reader_name="python", parser_name="restructuredtext", writer_name="pseudoxml") pub.process_command_line(argv=["--traceback"]) pub.set_source(source=source, source_path=source_path) return pub.publish(enable_exit=False)
def aoeuaoeuaoeu_docs(f): ''' I couldn't figure out how to use the docutils docstring parser, so I wrote my own. Can somebody show me the right way to do this? ''' raise NotImplementedError from docutils.core import Publisher from docutils.io import StringInput pub = Publisher(None, None, None, settings = settings, source_class = StringInput, destination_class = destination_class) pub.set_components('standalone', 'restructuredtext', 'pseudoxml') pub.process_programmatic_settings( settings_spec, settings_overrides, config_section) pub.set_source(f.__doc__, f.__name__) pub.set_destination(None, f.__name__) output = pub.publish(enable_exit_status = False) return output, pub return publish_parts(f.__doc__, source_class = StringInput, source_path = f.__name__)
def read_doc(app, env, filename): # type: (Sphinx, BuildEnvironment, unicode) -> nodes.document """Parse a document and convert to doctree.""" input_class = app.registry.get_source_input(filename) reader = SphinxStandaloneReader(app) source = input_class(app, env, source=None, source_path=filename, encoding=env.config.source_encoding) parser = app.registry.create_source_parser(app, filename) pub = Publisher(reader=reader, parser=parser, writer=SphinxDummyWriter(), source_class=SphinxDummySourceClass, destination=NullOutput()) pub.set_components(None, 'restructuredtext', None) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source, filename) pub.publish() return pub.document
def read_doc(app, env, filename): # type: (Sphinx, BuildEnvironment, str) -> nodes.document """Parse a document and convert to doctree.""" # set up error_handler for the target document error_handler = UnicodeDecodeErrorHandler(env.docname) codecs.register_error('sphinx', error_handler) # type: ignore reader = SphinxStandaloneReader(app) filetype = get_filetype(app.config.source_suffix, filename) parser = app.registry.create_source_parser(app, filetype) if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == (): # a workaround for recommonmark # If recommonmark.AutoStrictify is enabled, the parser invokes reST parser # internally. But recommonmark-0.4.0 does not provide settings_spec for reST # parser. As a workaround, this copies settings_spec for RSTParser to the # CommonMarkParser. parser.settings_spec = RSTParser.settings_spec input_class = app.registry.get_source_input(filetype) if input_class: # Sphinx-1.8 style source = input_class(app, env, source=None, source_path=filename, # type: ignore encoding=env.config.source_encoding) pub = Publisher(reader=reader, # type: ignore parser=parser, writer=SphinxDummyWriter(), source_class=SphinxDummySourceClass, destination=NullOutput()) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source, filename) else: # Sphinx-2.0 style pub = Publisher(reader=reader, parser=parser, writer=SphinxDummyWriter(), source_class=SphinxFileInput, destination=NullOutput()) pub.process_programmatic_settings(None, env.settings, None) pub.set_source(source_path=filename) pub.publish() return pub.document
def read_initial_doctree(filename: pathlib.Path, logger: logging.Logger) -> Optional[nodes.document]: """Parse the given reStructuredText file into its "initial" doctree. An "initial" doctree can be thought of as the abstract syntax tree of a reStructuredText document. This method disables all role and directives from being executed, instead they are replaced with nodes that simply represent that they exist. Parameters ---------- filename Returns the doctree that corresponds with the given file. logger Logger to log debug info to. """ parser = Parser() if filename.suffix.replace(".", "") not in parser.supported: return None logger.debug("Getting initial doctree for: '%s'", filename) with disable_roles_and_directives(): publisher = Publisher( reader=InitialDoctreeReader(logger), parser=parser, writer=DummyWriter(), source_class=FileInput, destination=NullOutput(), ) publisher.process_programmatic_settings(None, default_settings, None) publisher.set_source(source_path=str(filename)) publisher.publish() return publisher.document
def _get_publisher(self, source_path, translator_class=BlogHTMLTranslator): extra_params = { "initial_header_level": "2", "syntax_highlight": "short", "input_encoding": "utf-8", "exit_status_level": 2, "language_code": self._language_code, "halt_level": 2, "traceback": True, "warning_stream": StringIO(), "embed_stylesheet": False, } user_params = self.settings.get("DOCUTILS_SETTINGS") if user_params: extra_params.update(user_params) pub = Publisher(writer=self.writer_class(), destination_class=StringOutput) pub.set_components("standalone", "restructuredtext", "html") pub.writer.translator_class = translator_class pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish() return pub
class _PydocParser: def __init__(self): # Set up the instance we'll be using to render docstrings. self.errors = [] self.writer = _DocumentPseudoWriter() self.publisher = Publisher(_EpydocReader(self.errors), writer=self.writer, source_class=io.StringInput) self.publisher.set_components('standalone', 'restructuredtext', 'pseudoxml') settings_overrides={ 'report_level':10000, 'halt_level':10000, 'warning_stream':None, } self.publisher.process_programmatic_settings(None, settings_overrides, None) self.publisher.set_destination() def parse_docstring(self, docstring, errors): """Parse a docstring for eventual transformation into HTML This function is a replacement for parse_docstring from epydoc.markup.restructuredtext.parse_docstring. This function reuses the Publisher instance while the original did not. Using This function yields significantly faster WADL generation for complex systems. """ # Clear any errors from previous calls. del self.errors[:] self.publisher.set_source(docstring, None) self.publisher.publish() # Move any errors into the caller-provided list. errors[:] = self.errors[:] return ParsedRstDocstring(self.writer.document)
from docutils.core import publish_cmdline, default_description,\ publish_doctree,\ Publisher from dotmpe.du.ext.writer.formresults import Writer as FormResultsWriter #publish_cmdline(reader=FormReader(), writer_name='pseudoxml')#writer=xhtmlform.Writer()) source_path = sys.argv[1] source = open(source_path) #doctree = publish_doctree(source, reader=FormReader())#, writer_name='pseudoxml') #print doctree pub = Publisher(FormReader(), writer=FormResultsWriter(), source_class=io.FileInput, destination_class=io.StringOutput)#, parser, writer, settings=settings, # source_class=source_class, # destination_class=destination_class) pub.set_components(None, 'rst', 'pseudoxml') pub.process_programmatic_settings(None, None, None) # settings_spec, settings_overrides, config_section) pub.set_source(source, source_path) pub.set_destination(None, None)#destination, destination_path) output = pub.publish(enable_exit_status=False) #print pub.document.form_processor.fields #print pub.document.form_processor.messages #print pub.document.form_processor.values print output
def env_updated(app, env): config = app.builder.config doctree = env.get_doctree(config.master_doc) from sphinx import addnodes toctrees = [] for toctreenode in doctree.traverse(addnodes.toctree): toctree = env.resolve_toctree(config.master_doc, app.builder, toctreenode, prune = False, includehidden = True, maxdepth = 0, collapse = False) toctrees.append(toctree) if not toctrees: toc = None else: toc = toctrees[0] for toctree in toctrees[1:]: toc.extend(toctree.children) # toc = env.get_toctree_for(config.master_doc, app.builder, False) node = toc doc = new_document(b('<partial node>')) doc.append(node) pub = Publisher( source_class = DocTreeInput, destination_class=StringOutput) pub.set_components('standalone', 'restructuredtext', 'pseudoxml') pub.reader = DoctreeReader() pub.writer = Writer() pub.writer.format = 'pseudoxml' pub.process_programmatic_settings( None, {'output_encoding': 'unicode'}, None) pub.set_source(doc, None) pub.set_destination(None, None) pub.publish() import xml.etree.cElementTree as ET from cStringIO import StringIO #out = re.sub(r'^<!DOCTYPE[^>]*>\s*', '<?xml version="1.0"?>', pub.writer.output) out = pub.writer.output.encode('utf-8').replace(' encoding="unicode"', ' encoding="utf-8"') #pprint.pprint(out) doctree = ET.fromstring(out) #pprint.pprint(doctree) #pprint.pprint(dir(doctree)) if hasattr(doctree, 'getroot'): doctree = doctree.getroot() #root = doctree.getroot() fuzzy_find_entries = [] docs = {} def indexentries(entry, links, cap = ''): if links: fuzzy_find_entries.append(dict( href = links[0][1], name = entry, path = "index/%s/%s" % (char,cap), info = "INDEX", detail = '', )) for i, (ismain, link) in enumerate(links[1:], start=1): doclink = link.split('#', 1)[0] docname = docs.get(doclink, i) fuzzy_find_entries.append(dict( href = link, name = "%s (%s)" % (entry, docname), path = "index/%s/%s" % (char, cap), info = "INDEX", detail = '', )) return '' else: return entry if app.config.html_findanything_add_topics: if hasattr(doctree, 'iter'): references = doctree.iter('reference') else: references = doctree.getiterator('reference') # fuzzy_find_entries.append(dict( # href = link, # name = entry, # path = "index/%s/" % char, # info = "INDEX", # detail = '', # )) refset = set() for ref in references: refuri = ref.attrib['refuri'] docs[refuri] = ref.text path = "/" if "/" in refuri: path = refuri.rsplit('/', 1)[0]+"/" if '#' in refuri: docname = docs.get(refuri.split('#', 1)[0]) if docname: path += docname + "/" info = 'SECTION' else: info = 'PAGE' e = dict( href = ref.attrib['refuri'], name = ref.text, info = info, path = path, detail = '', ) refid = "%(href)s^%(path)s^%(name)s^%(info)s" % e if refid in refset: continue refset.add(refid) fuzzy_find_entries.append(e) if app.config.html_findanything_add_indexentries: genindex = env.create_index(app.builder) for char,char_list in genindex: for entry, (links, subitems) in char_list: cap = indexentries(entry, links) if subitems: if cap: cap += '/' for subname, sublinks in subitems: indexentries(subname, sublinks, cap=cap) s = json.dumps(fuzzy_find_entries) static_dir = os.path.join(app.builder.outdir, '_static') if not os.path.exists(static_dir): os.makedirs(static_dir) with open(os.path.join(static_dir, 'fuzzyindex.js'), 'wb') as f: f.write("DOCUMENTATION_OPTIONS.FIND_ANYTHING_ENTRIES = %s;" % s); if app.config.html_findanything_use_cached_hits: f.write("DOCUMENTATION_OPTIONS.FIND_ANYTHING_USE_CACHED_HITS = true;") f.write("DOCUMENTATION_OPTIONS.FIND_ANYTHING_WIDTH = '%s';" % app.config.html_findanything_width);
def process_targets(site, logger, source, permalink): """Process the target locations in the reST files.""" site.processing_targets = True reader = Reader() reader.l_settings = {"source": source} with open(source, "r", encoding="utf8") as in_file: data = in_file.read() pub = Publisher( reader=reader, parser=None, writer=None, settings=None, source_class=StringInput, destination_class=StringOutput, ) pub.set_components(None, "restructuredtext", "html") # Reading the file will generate output/errors that we don't care about # at this stage. The report_level = 5 means no output pub.process_programmatic_settings(settings_spec=None, settings_overrides={"report_level": 5}, config_section=None) pub.set_source(data, None) pub.set_destination(None, None) pub.publish() document = pub.document site.processing_targets = False # Code based on Sphinx std domain for name, is_explicit in document.nametypes.items(): if not is_explicit: continue labelid = document.nameids[name] if labelid is None: continue node = document.ids[labelid] if node.tagname == "target" and "refid" in node: node = document.ids.get(node["refid"]) labelid = node["names"][0] if (node.tagname == "footnote" or "refuri" in node or node.tagname.startswith("desc_")): continue if name in site.ref_targets: logger.warn( "Duplicate label {dup}, other instance in {other}".format( dup=name, other=site.ref_targets[name][0])) site.anon_ref_targets[name] = permalink, labelid def clean_astext(node): """Like node.astext(), but ignore images. Taken from sphinx.util.nodes """ node = node.deepcopy() for img in node.traverse(nodes.image): img["alt"] = "" for raw in node.traverse(nodes.raw): raw.parent.remove(raw) return node.astext() if node.tagname in ("section", "rubric"): sectname = clean_astext(node[0]) else: continue site.ref_targets[name] = permalink, labelid, sectname
class RstPublisher: ############################################## def __init__(self): self._publisher = Publisher(source_class=StringInput, destination_class=StringOutput) self._publisher.set_components('standalone', 'restructuredtext', 'html') self._publisher.writer.translator_class = MyHTMLTranslator self._publisher.process_programmatic_settings(None, extra_params, None) ############################################## def init_plugins(self, plugins): site.addsitedir(str(PurePath(__file__).parent / 'RstPlugins')) for plugin in plugins: print('Register {}'.format(plugin)) plugin = __import__(plugin, globals(), locals(), str('module')) plugin.register(self) ############################################## def register_directive(self, directive_name, directive_class): directives.register_directive(directive_name, directive_class) ############################################## def register_role(self, role_name, role_class): roles.register_local_role(role_name, role_class) ############################################## def register_node(self, node_class, visit, depart): print(node_class.__name__, visit, depart) setattr(MyHTMLTranslator, 'visit_' + node_class.__name__, visit) setattr(MyHTMLTranslator, 'depart_' + node_class.__name__, depart) ############################################## def publish(self, source, header_level=None, report_level=None): settings_overrides = DOCUTILS_RENDERER_SETTINGS.copy() if header_level is not None: # starts from 1 settings_overrides['initial_header_level'] = header_level if report_level is not None: # starts from 1 too settings_overrides['report_level'] = 0 # report_level self._publisher.set_source(source=source) self._publisher.publish(enable_exit_status=True) parts = self._publisher.writer.parts return parts[ 'html_body'] # parts['body_pre_docinfo'] + parts['fragment']