def parse(doc: List[str], settings: Any) -> nodes.document: state_machine = RSTStateMachine(state_classes, 'Body') node = new_document('', settings) node.reporter = NullReporter() state_machine.run(doc, node) return node
def extract_summary(doc, document): # type: (List[unicode], Any) -> unicode """Extract summary from docstring.""" # Skip a blank lines at the top while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break # Try to find the "first sentence", which may span multiple lines sentences = periods_re.split(" ".join(doc)) # type: ignore if len(sentences) == 1: summary = sentences[0].strip() else: summary = '' state_machine = RSTStateMachine(state_classes, 'Body') while sentences: summary += sentences.pop(0) + '.' node = new_document('', document.settings) node.reporter = NullReporter() state_machine.run([summary], node) if not node.traverse(nodes.system_message): # considered as that splitting by period does not break inline markups break return summary
def extract_summary(doc, document): # type: (List[unicode], Any) -> unicode """Extract summary from docstring.""" # Skip a blank lines at the top while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break # Try to find the "first sentence", which may span multiple lines sentences = periods_re.split(" ".join(doc)) # type: ignore if len(sentences) == 1: summary = sentences[0].strip() else: summary = '' state_machine = RSTStateMachine(state_classes, 'Body') while sentences: summary += sentences.pop(0) + '.' node = new_document('', document.settings) node.reporter = NullReporter() state_machine.run([summary], node) if not node.traverse(nodes.system_message): # considered as that splitting by period does not break inline markups break return summary
def sphinx_state(local_app): """ Fixture which will provide a sphinx state for use in testing sphinx directives. Yields: :class:`docutils.parsers.rst.states.State`: A state for use in testing directive functionality. """ # Get the environment and decorate it with what sphinx may need for the # parsing. env = local_app.env env.temp_data["docname"] = "test" # A fake document name # Create a document and inliner object, to be perfectly honest not sure # exactly what these are or do, but needed to get the directive to run. document = new_document(__file__) document.settings.pep_references = 1 document.settings.rfc_references = 1 document.settings.env = env document.settings.tab_width = 4 inliner = Inliner() inliner.init_customizations(document.settings) # Create a state machine so that we can get a state to pass back. statemachine = RSTStateMachine(state_classes=state_classes, initial_state="Body") statemachine.input_lines = StringList([""] * 40) state = statemachine.get_state() state.document = document state.memo = Struct( inliner=inliner, language=en, title_styles=[], reporter=document.reporter, document=document, section_level=0, section_bubble_up_kludge=False, ) state.memo.reporter.get_source_and_line = statemachine.get_source_and_line # The environemnt isn't normally available on the state in sphinx, but it's # done here to make testing easier. state.env = env # Sphinx monkeypatches docutils when run. This is how it get's # monkeypatched so that the python directives and roles can be found with sphinx_domains(env): # Provide the state back to the test. yield state
def wideformat(): state = Body(RSTStateMachine(None, None)) #state = Mock() lineno = 1 app = None return wide_format.WideFormat(state, lineno, app)
def extract_summary(doc, document): # type: (List[str], Any) -> str """Extract summary from docstring.""" # Skip a blank lines at the top while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break if doc == []: return '' # parse the docstring state_machine = RSTStateMachine(state_classes, 'Body') node = new_document('', document.settings) node.reporter = NullReporter() state_machine.run(doc, node) if not isinstance(node[0], nodes.paragraph): # document starts with non-paragraph: pick up the first line summary = doc[0].strip() else: # Try to find the "first sentence", which may span multiple lines sentences = periods_re.split(" ".join(doc)) if len(sentences) == 1: summary = sentences[0].strip() else: summary = '' while sentences: summary += sentences.pop(0) + '.' node[:] = [] state_machine.run([summary], node) if not node.traverse(nodes.system_message): # considered as that splitting by period does not break inline markups break # strip literal notation mark ``::`` from tail of summary summary = literal_re.sub('.', summary) return summary
def wideformat(): state = Body(RSTStateMachine([], None)) state.build_table = Mock() lineno = 1 source = '' options = {} app = None return wide_format.WideFormat(state, lineno, source, options, app)
def __init__(self, app): # After much digging through source code, this is how we emulate Sphinx's builtin reST parsing state # https://github.com/sphinx-doc/sphinx/blob/68cc0f7e94f360a2c62ebcb761f8096e04ebf07f/sphinx/io.py#L204 # Here we're bypassing the RST Parser, and just doing the relevant code ops parser = app.registry.create_source_parser(app, "restructuredtext") # autosummary uses tab width 8; not set by publisher/env for some reason settings = dict(app.env.settings) if "tab_width" not in settings: settings["tab_width"] = 8 p2 = Publisher() p2.process_programmatic_settings(None, settings, None) document = new_document('dummy_kissapi_source', p2.settings) # (source path, settings) document.reporter = NullReporter() state_machine = RSTStateMachine( state_classes, 'Body') # (state machine classes, initial state) # needed to set various self.[attr] values of state_machine state_machine.run([""], document) # (input lines, document) # the directive attrs that are needed self.state = state_machine.get_state() self.env = app.env self.lineno = 0
def extract_summary(doc, document): # type: (List[str], Any) -> str """Extract summary from docstring.""" # Skip a blank lines at the top while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break if doc == []: return '' # parse the docstring state_machine = RSTStateMachine(state_classes, 'Body') node = new_document('', document.settings) node.reporter = NullReporter() state_machine.run(doc, node) if not isinstance(node[0], nodes.paragraph): # document starts with non-paragraph: pick up the first line summary = doc[0].strip() else: # Try to find the "first sentence", which may span multiple lines sentences = periods_re.split(" ".join(doc)) if len(sentences) == 1: summary = sentences[0].strip() else: summary = '' while sentences: summary += sentences.pop(0) + '.' node[:] = [] state_machine.run([summary], node) if not node.traverse(nodes.system_message): # considered as that splitting by period does not break inline markups break # strip literal notation mark ``::`` from tail of summary summary = literal_re.sub('.', summary) return summary
def render_rst( source, format='xhtml', encoding='utf-8', with_props=False, with_docinfo=False, as_whole=False ): """Return the rendered ``source`` with optional extracted properties.""" global SEEN_TAGS_CACHE, TAG_COUNTER, CURRENT_PLAN_ID SEEN_TAGS_CACHE = set() TAG_COUNTER = 0 CURRENT_PLAN_ID = None if format in ('xhtml', 'html'): format, translator, transforms, option_parser = HTML_SETUP elif format in ('tex', 'latex'): format, translator, transforms, option_parser = LATEX_SETUP elif format == 'raw': format, translator, transforms, option_parser = RAW_SETUP else: raise ValueError("Unknown format: %r" % format) settings = option_parser.get_default_values() settings._update_loose({ 'footnote_references': 'superscript', # 'mixed', 'brackets' 'halt_level': 6, # 'report_level': 2, 'trim_footnote_reference_space': 1, }) document = new_document('[dynamic-text]', settings) if not isinstance(source, unicode): source = unicode(source, encoding) source = replace_whitespace(' ', source) source_lines = [s.expandtabs(4).rstrip() for s in source.splitlines()] if with_props: source_lines, props = parse_headers(source_lines, {}, True) document.reporter.attach_observer(document.note_parse_message) RSTStateMachine( state_classes=state_classes, initial_state='Body', ).run(source_lines, document) document.reporter.detach_observer(document.note_parse_message) document.current_source = document.current_line = None document.transformer.add_transforms(transforms) document.transformer.apply_transforms() if not format: return unicode(document) visitor = translator(document) document.walkabout(visitor) # see HTML_VISITOR_ATTRIBUTES/LATEX_VISITOR_ATTRIBUTES to see other attrs if as_whole: output = visitor.astext() else: if format == 'html' and with_docinfo: output = ( u'<div class="docinfo">\n%s\n</div>\n<div class="document">\n%s</div>' % (u''.join(visitor.docinfo), u''.join(visitor.body)) ) else: output = u''.join(visitor.body) # post rst-konversion prosessing if format == 'html': # [[plexlinks]] # output = re.sub( # '(?sm)\[\[(.*?)\]\]', # render_plexlink, # output) # syntax highlighting for kode snippets # output = re.sub( # '(?sm)<p>(?:\s)?<code class="(.*?)">(?::)?</p>(?:\n<blockquote>)?\n<pre class="literal-block">(.*?)</pre>(?:\n</blockquote>)?\n<p>(?:\s)?</code></p>', # code2html, # output) # support for embedding html into rst dokuments and prettifikation output = escape_and_prettify(output) # toc href id and div adder output = replace_toc_attributes( '<p class="topic-title\\1"><a name="\\2"></a><span id="document-toc">\\3</span></p>\n<div id="document-toc-listing">\\4</div></div>', output) # inserting an "#abstract" id output = replace_abstract_attributes( r'<div id="abstract" class="abstract topic">', output) # footnote refs looking a bit too superskripted # output = re.sub( # '(?sm)<a class="footnote-reference" (.*?)><sup>(.*?)</sup></a>', # r'<a class="footnote-reference" \1>\2</a>', # output) # drop shadow wrappers for figures output = replace_drop_shadows( r'<div class="figure\1<div class="wrap1"><div class="wrap2"><div class="wrap3"><img\2/></div></div></div>\3</div>', output) # @/@ reinstate this? -- name="" no no # output = re.sub(r'<a name="table-of-contents"></a>', '', output) # output = re.sub(r'<a (.*?) name="(.*?)">', r'<a \1>', output) # get rid of <p>around floating images</p> # output = re.sub( # '(?sm)<p><img (.*?) class="float-(.*?) /></p>', # r'<img \1 class="float-\2 />', # output) # niser <hr /> # output = re.sub( # '<hr />', # r'<hr noshade="noshade" />', # output) # drop cap them first letters # output = re.sub( # '(?sm)<p>(.*?)</p>', # render_drop_cap, # output, count=1) # strip out comments output = replace_comments('', output) # strip out title headings output = replace_title_headings('', output) if with_props: if format == 'html': props.setdefault(u'title', visitor.title and visitor.title[0] or u'') props.setdefault(u'subtitle', visitor.subtitle and visitor.subtitle[0] or u'') return output, props return output