def __init__(self) -> None: settings = Struct(tab_width=8) document = Struct(settings=settings) env = BuildEnvironment() env.config = Config() state = Struct(document=document) super().__init__(env, None, Options(), 0, state)
def __init__(self) -> None: settings = Struct(tab_width=8) document = Struct(settings=settings) app = FakeApplication() app.config.add('autodoc_class_signature', 'mixed', True, None) env = BuildEnvironment(app) # type: ignore state = Struct(document=document) super().__init__(env, None, Options(), 0, state)
def __init__(self) -> None: settings = Struct(tab_width=8) document = Struct(settings=settings) env = BuildEnvironment() env.config = Config() env.config.add('autodoc_class_signature', 'mixed', True, None) state = Struct(document=document) super().__init__(env, None, Options(), 0, state)
def parse_rst(parent, text, lineno, inliner): context = Struct( document=inliner.document, reporter=inliner.reporter, language=inliner.language) processed, messages = inliner.parse(unescape(text), lineno, context, parent) parent += processed return messages
def __init__(self, env: BuildEnvironment, reporter: Reporter, options: Options, lineno: int, state: Any = None) -> None: self.env = env self.reporter = reporter self.genopt = options self.lineno = lineno self.filename_set = set() # type: Set[str] self.result = StringList() if state: self.state = state else: # create fake object for self.state.document.settings.tab_width warnings.warn('DocumenterBridge requires a state object on instantiation.', RemovedInSphinx40Warning, stacklevel=2) settings = Struct(tab_width=8) document = Struct(settings=settings) self.state = Struct(document=document)
def check_docutils_inliner(po, msgstr): inliner = Inliner() settings = AttrDict({'character_level_inline_markup': False, 'pep_references': None, 'rfc_references': None}) inliner.init_customizations(settings) document = new_document(None) document.settings.syntax_highlight = 'long' stream = StringIO() reporter = Reporter(po.file, report_level=Reporter.WARNING_LEVEL, halt_level=Reporter.SEVERE_LEVEL, stream=stream) memo = Struct(document=document, reporter=reporter, language=None, inliner=inliner) inliner.parse(msgstr, po.current_index, memo, None) return stream.getvalue()
def _alink_role( # See roleName_. roleName, # See rawtext_. rawtext, # See text_. text, # See lineno_. lineno, # See inliner_. inliner, # See options_. options={}, # See content_. content=[], ): # Look for ``title <refname#anchor>``. m = re.search(r"(.*\s+<[^#]+)(#.+)(>\s*)$", text) if not m: msg = inliner.reporter.error( 'Expected "title <refname#anchor>", but saw "{}"'.format(text)) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] anchor = m.group(2) # Reassemble this into a reference, but removing the anchor. It then becomes ## `title <refname_>`_ no_anchor_reference = "`" + m.group(1) + "_" + m.group(3) + "`_" # Parse this. Booger a bit to be able to invoke the inliner. Just creating a reference node doesn't work, since the parser modifies internal data structures which relate refnames to references. memo = Struct(reporter=inliner.reporter, document=inliner.document, language=inliner.language) parsed_nodes, system_messages = inliner.parse(no_anchor_reference, lineno, memo, inliner.parent) # This should return [refence_node, target_node]. assert isinstance(parsed_nodes[0], nodes.reference) assert isinstance(parsed_nodes[1], nodes.target) # Add in the anchor to the reference node. parsed_nodes[0]["anchor"] = anchor # I'd like ``:alink:`foo <bar#thing>``` followed by ``foo_`` to link to ``bar#thing``, but it instead links to ``bar``. That's because: # # #. ``:alink:`foo <bar#thing>``` is translated to ```foo <bar_>_```, an indirect reference to ``bar``. # #. In (I think) ``docutils.transforms.references.IndirectHyperlinks``, the ``nodes.target`` referring to ``bar`` is replaced with the ``nodes.target`` for ``bar``. So, any info (such as an ``anchor`` field) specific to this target will be lost in the replacement. # #. In the ``ExternalAnchorTargets`` transform, the ``nodes.target`` with the actual ``refuri`` (name of the URL in a Docutils node) will have the ``node.reference anchor`` value appended. However, this will **only** apply to the original ``node.reference`` -- references to this reference won't have the ``anchor`` field. I'm not sure how or where to fix this (to make ``anchor`` propagate). # # Test cases: source link is # :alink:`.space directive <asmguide#page=75>` # and the following should refer to the same thing (but leaves off the anchor) # `.space directive`_. return parsed_nodes, system_messages
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 parsed_text_role(name, rawtext, text, lineno, inliner, options={}, content=[]): # Prepare context for nested parsing memo = Struct(document=inliner.document, reporter=inliner.reporter, language=inliner.language) # Create parent node options['classes'] = class_names parent = node_class(rawtext, '', **options) # Parse role text for markup and add to parent processed, messages = inliner.parse(text, lineno, memo, parent) parent += processed # Return parent node, and any messages from nested parsing return [parent], messages
def _role_annot( name: str, rawtext: str, text: str, lineno: int, inliner: Inliner, options: Dict[str, Any] = {}, content: Sequence[str] = (), # *, # https://github.com/ambv/black/issues/613 additional_classes: Iterable[str] = (), ) -> Tuple[List[Node], List[SystemMessage]]: options = options.copy() set_classes(options) if additional_classes: options["classes"] = options.get("classes", []).copy() options["classes"].extend(additional_classes) memo = Struct(document=inliner.document, reporter=inliner.reporter, language=inliner.language) node = nodes.inline(unescape(rawtext), "", **options) children, messages = inliner.parse(_unescape(text), lineno, memo, node) node.extend(children) return [node], messages
def __init__(self, app, need, layout, node, style=None, fromdocname=None): self.app = app self.need = need self.layout_name = layout available_layouts = getattr(app.config, 'needs_layouts', {}) if self.layout_name not in available_layouts.keys(): raise SphinxNeedLayoutException( 'Given layout "{}" is unknown for need {}. Registered layouts are: {}' .format(self.layout_name, need['id'], ' ,'.join(available_layouts.keys()))) self.layout = available_layouts[self.layout_name] self.node = node # Used, if need is referenced from another page if fromdocname is None: self.fromdocname = need['docname'] else: self.fromdocname = fromdocname classes = [ "need", 'needs_grid_' + self.layout['grid'], 'needs_layout_' + self.layout_name ] if style is not None: self.style = style elif self.need['style'] is not None: self.style = self.need['style'] else: self.style = getattr(self.app.config, 'needs_default_style', None) if self.style and len(self.style) > 0: for style in self.style.strip().split(','): style = style.strip() classes.append('needs_style_' + style) else: classes.append('needs_style_none') classes.append('needs_type_' + ''.join(self.need['type'].split())) self.node_table = nodes.table(classes=classes, ids=[self.need['id']]) self.node_tbody = nodes.tbody() self.grids = { 'simple': { 'func': self._grid_simple, 'configs': { 'colwidths': [100], 'side_left': False, 'side_right': False, 'footer': False } }, 'simple_side_left': { 'func': self._grid_simple, 'configs': { 'colwidths': [30, 70], 'side_left': 'full', 'side_right': False, 'footer': False } }, 'simple_side_right': { 'func': self._grid_simple, 'configs': { 'colwidths': [70, 30], 'side_left': False, 'side_right': 'full', 'footer': False } }, 'simple_side_left_partial': { 'func': self._grid_simple, 'configs': { 'colwidths': [20, 80], 'side_left': 'part', 'side_right': False, 'footer': False } }, 'simple_side_right_partial': { 'func': self._grid_simple, 'configs': { 'colwidths': [80, 20], 'side_left': False, 'side_right': 'part', 'footer': False } }, 'complex': self._grid_complex, 'content': { 'func': self._grid_content, 'configs': { 'colwidths': [100], 'side_left': False, 'side_right': False, 'footer': False } }, 'content_footer': { 'func': self._grid_content, 'configs': { 'colwidths': [100], 'side_left': False, 'side_right': False, 'footer': True } }, 'content_side_left': { 'func': self._grid_content, 'configs': { 'colwidths': [5, 95], 'side_left': True, 'side_right': False, 'footer': False } }, 'content_side_right': { 'func': self._grid_content, 'configs': { 'colwidths': [95, 5], 'side_left': False, 'side_right': True, 'footer': False } }, 'content_footer_side_left': { 'func': self._grid_content, 'configs': { 'colwidths': [5, 95], 'side_left': True, 'side_right': False, 'footer': True } }, 'content_footer_side_right': { 'func': self._grid_content, 'configs': { 'colwidths': [95, 5], 'side_left': False, 'side_right': True, 'footer': True } }, } # Dummy Document setup self.doc_settings = OptionParser( components=(Parser, )).get_default_values() self.dummy_doc = new_document("dummy", self.doc_settings) self.doc_language = languages.get_language( self.dummy_doc.settings.language_code) self.doc_memo = Struct(document=self.dummy_doc, reporter=self.dummy_doc.reporter, language=self.doc_language, title_styles=[], section_level=0, section_bubble_up_kludge=False, inliner=None) self.functions = { 'meta': self.meta, 'meta_all': self.meta_all, 'meta_links': self.meta_links, 'meta_links_all': self.meta_links_all, 'meta_id': self.meta_id, 'image': self.image, 'link': self.link, 'collapse_button': self.collapse_button }
def __init__(self) -> None: settings = Struct(tab_width=8) document = Struct(settings=settings) state = Struct(document=document) super().__init__({}, None, Options(), 0, state) # type: ignore
def __init__(self): self.memo = Struct(title_styles=[], inliner=None) self.state = RSTState(self) self.input_offset = 0
def __init__(self, app, need, layout, node, style=None, fromdocname=None): self.app = app self.need = need self.layout_name = layout available_layouts = app.config.needs_layouts if self.layout_name not in available_layouts.keys(): raise SphinxNeedLayoutException( 'Given layout "{}" is unknown for need {}. Registered layouts are: {}'.format( self.layout_name, need["id"], " ,".join(available_layouts.keys()) ) ) self.layout = available_layouts[self.layout_name] self.node = node # Used, if need is referenced from another page if fromdocname is None: self.fromdocname = need["docname"] else: self.fromdocname = fromdocname # For ReadTheDocs Theme we need to add 'rtd-exclude-wy-table'. classes = ["need", "needs_grid_" + self.layout["grid"], "needs_layout_" + self.layout_name] classes.extend(app.config.needs_table_classes) self.style = style or self.need["style"] or getattr(self.app.config, "needs_default_style", None) if self.style: for style in self.style.strip().split(","): style = style.strip() classes.append("needs_style_" + style) else: classes.append("needs_style_none") classes.append("needs_type_" + "".join(self.need["type"].split())) self.node_table = nodes.table(classes=classes, ids=[self.need["id"]]) self.node_tbody = nodes.tbody() self.grids = { "simple": { "func": self._grid_simple, "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": False}, }, "simple_footer": { "func": self._grid_simple, "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": True}, }, "simple_side_left": { "func": self._grid_simple, "configs": {"colwidths": [30, 70], "side_left": "full", "side_right": False, "footer": False}, }, "simple_side_right": { "func": self._grid_simple, "configs": {"colwidths": [70, 30], "side_left": False, "side_right": "full", "footer": False}, }, "simple_side_left_partial": { "func": self._grid_simple, "configs": {"colwidths": [20, 80], "side_left": "part", "side_right": False, "footer": False}, }, "simple_side_right_partial": { "func": self._grid_simple, "configs": {"colwidths": [80, 20], "side_left": False, "side_right": "part", "footer": False}, }, "complex": self._grid_complex, "content": { "func": self._grid_content, "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": False}, }, "content_footer": { "func": self._grid_content, "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": True}, }, "content_side_left": { "func": self._grid_content, "configs": {"colwidths": [5, 95], "side_left": True, "side_right": False, "footer": False}, }, "content_side_right": { "func": self._grid_content, "configs": {"colwidths": [95, 5], "side_left": False, "side_right": True, "footer": False}, }, "content_footer_side_left": { "func": self._grid_content, "configs": {"colwidths": [5, 95], "side_left": True, "side_right": False, "footer": True}, }, "content_footer_side_right": { "func": self._grid_content, "configs": {"colwidths": [95, 5], "side_left": False, "side_right": True, "footer": True}, }, } # Dummy Document setup self.doc_settings = OptionParser(components=(Parser,)).get_default_values() self.dummy_doc = new_document("dummy", self.doc_settings) self.doc_language = languages.get_language(self.dummy_doc.settings.language_code) self.doc_memo = Struct( document=self.dummy_doc, reporter=self.dummy_doc.reporter, language=self.doc_language, title_styles=[], section_level=0, section_bubble_up_kludge=False, inliner=None, ) self.functions = { "meta": self.meta, "meta_all": self.meta_all, "meta_links": self.meta_links, "meta_links_all": self.meta_links_all, "meta_id": self.meta_id, "image": self.image, "link": self.link, "collapse_button": self.collapse_button, "permalink": self.permalink, } # Prepare string_links dict, so that regex and templates get not recompiled too often. # # Do not set needs_string_links here and update it. # This would lead to deepcopy()-errors, as needs_string_links gets some "pickled" and jinja Environment is # too complex for this. self.string_links = {} for link_name, link_conf in app.config.needs_string_links.items(): self.string_links[link_name] = { "url_template": Environment(loader=BaseLoader).from_string(link_conf["link_url"]), "name_template": Environment(loader=BaseLoader).from_string(link_conf["link_name"]), "regex_compiled": re.compile(link_conf["regex"]), "options": link_conf["options"], "name": link_name, }