def run(self): for auto in ("autolist", "autolist-classes", "autolist-functions"): if auto in self.options: # Get current module name module_name = self.env.ref_context.get("py:module") # Import module module = import_module(module_name) # Get public names (if possible) try: names = getattr(module, "__all__") except AttributeError: # Get classes defined in the module cls_names = [ name[0] for name in getmembers(module, isclass) if name[-1].__module__ == module_name and not (name[0].startswith("_")) ] # Get functions defined in the module fn_names = [ name[0] for name in getmembers(module, isfunction) if (name[-1].__module__ == module_name) and not (name[0].startswith("_")) ] names = cls_names + fn_names # It may happen that module doesn't have any defined class or func if not names: names = [name[0] for name in getmembers(module)] # Filter out members w/o doc strings names = [name for name in names if getattr(module, name).__doc__ is not None] if auto == "autolist": # Get list of all classes and functions inside module names = [ name for name in names if (isclass(getattr(module, name)) or isfunction(getattr(module, name))) ] else: if auto == "autolist-classes": # Get only classes check = isclass elif auto == "autolist-functions": # Get only functions check = isfunction else: raise NotImplementedError names = [name for name in names if check(getattr(module, name))] # Update content self.content = StringList(names) return super().run()
def test_directive(test_module): """Return an instance of HensonCLIDirective.""" return sphinx.HensonCLIDirective( name='hensoncli', arguments=['fake_extension:FakeExtension'], options={}, content=StringList([], items=[]), lineno=1, content_offset=0, block_text='.. hensoncli:: fake_extension:FakeExtension\n', state=None, state_machine=None, )
def run(self): zenpy_client = Zenpy(subdomain="party", email="face@toe", password="******") node_list = [] doc_sections = self.generate_sections(zenpy_client) output = '.. py:class:: Zenpy%s\n\n' % inspect.signature( zenpy_client.__class__) output += ' %s' % zenpy_client.__doc__ node = container() self.state.nested_parse(StringList(output.split('\n')), 0, node) node_list.append(node) for doc_section in doc_sections: node = paragraph() self.state.nested_parse(StringList(doc_section.split('\n')), 0, node) node_list.append(node) return node_list
def _assemble(node, directive): title_text = directive.arguments[0] directive.add_name(node) header = node.HEADER_PRETITLE.format(**node.options).split('\n') directive.state.nested_parse(StringList(header), directive.content_offset, node) textnodes, messages = directive.state.inline_text(title_text, directive.lineno) node += textnodes node += messages header = node.HEADER_POSTTITLE.format(**node.options).split('\n') directive.state.nested_parse(StringList(header), directive.content_offset, node) directive.state.nested_parse(directive.content, directive.content_offset, node) footer = node.FOOTER.format(**node.options).split('\n') directive.state.nested_parse(StringList(footer), directive.content_offset, node)
def run(self): lines = [] body_lines = self._role_lines() for i, line in enumerate(body_lines): suffix = '.' if i == len(body_lines) - 1 else ';' lines.append('{}{}'.format(line, suffix)) node = self.code_links_node('\n'.join(lines)) self.state.nested_parse(StringList(lines), self.content_offset, node) if 'timeout' in self.options: for node in node.traverse(runrole_reference): if node['reftype'] == 'fullnotebook': node['timeout'] = self.options['timeout'] return [node]
def run(self): zenpy = Zenpy.__new__(Zenpy) zenpy.__init__(zenpy, ' ', ' ') node_list = [] cache_node = container() cache_sections = self.generate_cache_sections(zenpy) for cache_section in cache_sections: node = paragraph() self.state.nested_parse(StringList(cache_section.split('\n')), 0, node) node_list.append(node) node_list.append(cache_node) return node_list
def run(self): self.assert_has_content() hidden_until = self.arguments[0] try: hidden_until = parse_date(hidden_until) except: raise self.error('Unknown date format in the "%s" directive; ' '%s' % (self.name, hidden_until)) force_show = self.state.document.settings.force_show_hidden_until after_deadline = hidden_until <= datetime.now() if after_deadline or force_show: output = [] # Add a warning for teachers/tutors/... if not after_deadline and force_show: node = nodes.caution() self.add_name(node) text = "The feedback below will be hidden to the students until %s." % hidden_until.strftime( "%d/%m/%Y %H:%M:%S") self.state.nested_parse(StringList(text.split("\n")), 0, node) output.append(node) text = '\n'.join(self.content) node = nodes.compound(text) self.add_name(node) self.state.nested_parse(self.content, self.content_offset, node) output.append(node) return output else: node = nodes.caution() self.add_name(node) text = "A part of this feedback is hidden until %s. Please come back later and reload the submission to see the full feedback." % \ hidden_until.strftime("%d/%m/%Y %H:%M:%S") self.state.nested_parse(StringList(text.split("\n")), 0, node) return [node]
def test_prepend_prolog_without_CR(app): # prolog not having CR at tail prolog = 'this is rst_prolog\nhello reST!' content = StringList( ['hello Sphinx world', 'Sphinx is a document generator'], 'dummy.rst') prepend_prolog(content, prolog) assert list(content.xitems()) == [ ('<rst_prolog>', 0, 'this is rst_prolog'), ('<rst_prolog>', 1, 'hello reST!'), ('<generated>', 0, ''), ('dummy.rst', 0, 'hello Sphinx world'), ('dummy.rst', 1, 'Sphinx is a document generator') ]
def run(self): node = nodes.container() node['classes'].append('toggle-content') par = nodes.container() par['classes'].append('toggle-header') if self.arguments and self.arguments[0]: par['classes'].append(self.arguments[0]) self.state.nested_parse(StringList([self.options["header"]]), self.content_offset, par) self.state.nested_parse(self.content, self.content_offset, node) return [par, node]
def run(self): sl = StringList([" " for _ in range(int(self.arguments[0]))]) if not self.content: self.content = sl else: self.content.append(sl) par = nodes.raw( '', """<pre style="background-color: #ffffff; border: 1px solid #000000">%s</pre>""" % "\n".join(self.content), format='html') return [par]
def run(self): ytid = self.arguments[0] description = [i if i != "" else "<br><br>" for i in self.content] thumbnail_rst = YOUTUBE_TEMPLATE.format( id=ytid, title=self.options["title"], author=self.options["author"], description=" ".join(description)) thumbnail = StringList(thumbnail_rst.split('\n')) thumb = nodes.paragraph() self.state.nested_parse(thumbnail, self.content_offset, thumb) return [thumb]
def run(self): """Run the directive.""" reporter = self.state.document.reporter self.result = StringList() self.generate() node = nodes.paragraph() node.document = self.state.document self.state.nested_parse(self.result, 0, node) return node.children
def run(self): if len(self.arguments) == 1: spec = get_obj_from_module(self.arguments[0].strip()) else: spec = json.loads('\n'.join(self.content)) content = doc_spec(spec) # parse the RST text node = addnodes.desc_content() self.state.nested_parse(StringList(content), self.content_offset, node) return [node]
def run(self) -> Sequence[nodes.Node]: # type: ignore """ Process the content of the directive. """ if "hooks" in self.options: hooks = self.options["hooks"] else: cwd = PathPlus.cwd() for directory in (cwd, *cwd.parents): if (directory / ".pre-commit-hooks.yaml").is_file(): hooks = [ h["id"] for h in yaml.safe_load(( directory / ".pre-commit-hooks.yaml").read_text()) ] break else: warnings.warn( "No hooks specified and no .pre-commit-hooks.yaml file found." ) return [] repo = make_github_url(self.env.config.github_username, self.env.config.github_repository) config: _Config = {"repo": str(repo)} if "rev" in self.options: config["rev"] = self.options["rev"] config["hooks"] = [{"id": hook_name} for hook_name in hooks] if "args" in self.options: config["hooks"][0]["args"] = self.options["args"] targetid = f'pre-commit-{self.env.new_serialno("pre-commit"):d}' targetnode = nodes.section(ids=[targetid]) yaml_output = yaml.round_trip_dump([config], default_flow_style=False) if not yaml_output: return [] content = f".. code-block:: yaml\n\n{indent(yaml_output, ' ')}\n\n" view = StringList(content.split('\n')) pre_commit_node = nodes.paragraph(rawsource=content) self.state.nested_parse(view, self.content_offset, pre_commit_node) pre_commit_node_purger.add_node(self.env, pre_commit_node, targetnode, self.lineno) return [pre_commit_node]
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 run(self) -> List[nodes.Node]: """ Process the content of the directive. """ summary = getattr(self.config, "documentation_summary", '').strip() if not summary: return [] # pragma: no cover # if self.env.app.builder.format.lower() == "latex" or not summary: # return [] targetid = f'documentation-summary-{self.env.new_serialno("documentation-summary"):d}' onlynode = addnodes.only(expr="html") content = f'**{summary}**' content_node = nodes.paragraph(rawsource=content, ids=[targetid]) onlynode += content_node self.state.nested_parse(StringList([content]), self.content_offset, content_node) summary_node_purger.add_node(self.env, content_node, content_node, self.lineno) if "meta" in self.options: meta_content = f'.. meta::\n :description: {self.config.project} -- {summary}\n' meta_node = nodes.paragraph(rawsource=meta_content, ids=[targetid]) onlynode += meta_node self.state.nested_parse( StringList(meta_content.split('\n')), self.content_offset, meta_node, ) summary_node_purger.add_node(self.env, meta_node, meta_node, self.lineno) return [onlynode]
def run(self): def walk(cls): """Render the given class, then recursively render its descendants depth first. Appends to the outer ``lines`` variable. :param cls: The Jinja ``Node`` class to render. """ lines.append(".. autoclass:: {}({})".format( cls.__name__, ", ".join(cls.fields))) # render member methods for nodes marked abstract if cls.abstract: members = [] for key, value in cls.__dict__.items(): if (not key.startswith("_") and not hasattr(cls.__base__, key) and callable(value)): members.append(key) if members: members.sort() lines.append(" :members: " + ", ".join(members)) # reference the parent node, except for the base node if cls.__base__ is not object: lines.append("") lines.append(" :Node type: :class:`{}`".format( cls.__base__.__name__)) lines.append("") children = cls.__subclasses__() children.sort(key=lambda x: x.__name__.lower()) # render each child for child in children: walk(child) # generate the markup starting at the base class lines = [] target = import_object(self.arguments[0]) walk(target) # parse the generated markup into nodes doc = StringList(lines, "<jinja>") node = nodes.Element() self.state.nested_parse(doc, self.content_offset, node) return node.children
def read(self): # type: () -> StringList inputstring = SphinxBaseFileInput.read(self) lines = string2lines(inputstring, convert_whitespace=True) content = StringList() for lineno, line in enumerate(lines): content.append(line, self.source_path, lineno) if self.env.config.rst_prolog: self.prepend_prolog(content, self.env.config.rst_prolog) if self.env.config.rst_epilog: self.append_epilog(content, self.env.config.rst_epilog) return content
def run(self): filename = ''.join(self.content) for folder in self.env.config.ibf_folders: candidate = os.path.join(folder, filename) if os.path.isfile(candidate): filename = candidate break content = open(filename).readlines() content = [line.rstrip('\n') for line in content] # parse the string list node = nodes.Element() nested_parse_with_titles(self.state, StringList(content), node) self.state.document.settings.env.note_dependency(filename) return node.children
def run(self): if self.content: sl = StringList(["{% if ((logged_in is not none) and (logged_in['right'] in ['admin', 'teacher'])) %}"]) sl.append(StringList([""])) sl.append(StringList([".. container:: framed"])) sl.append(StringList([""])) new_content = StringList([]) for item in self.content: new_content.append(StringList([" %s" % item])) sl.append(new_content) sl.append(StringList([""])) sl.append(StringList(["{% endif %}"])) self.content = sl return Container(content=self.content, arguments=[], lineno=self.lineno, block_text=self.block_text, content_offset=self.content_offset, name="container", options=self.options, state=self.state, state_machine=self.state_machine).run()
def auto_code_block(self, node): """Try to automatically generate nodes for codeblock syntax. Parameters ---------- node : nodes.literal_block Original codeblock node Returns ------- tocnode: docutils node The converted toc tree node, None if conversion is not possible. """ assert isinstance(node, nodes.literal_block) original_node = node if 'language' not in node: return None self.state_machine.reset(self.document, node.parent, self.current_level) # content = node.rawsource.split('\n') content = ''.join([child.astext() for child in node.children]).split('\n') language = node['language'] if language == 'math': if self.config['enable_math']: return self.state_machine.run_directive('math', content=content) elif language == 'eval_rst': if self.config['enable_eval_rst']: # allow embed non section level rst node = nodes.section() self.state_machine.state.nested_parse(StringList( content, source=original_node.source), 0, node=node, match_titles=True) return node.children[:] else: match = re.search(r'[ ]?[\w_-]+::.*', language) if match: parser = Parser() new_doc = new_document(None, self.document.settings) newsource = u'.. ' + match.group(0) + '\n' + node.rawsource parser.parse(newsource, new_doc) return new_doc.children[:] else: return self.state_machine.run_directive('code-block', arguments=[language], content=content) return None
def run(self): # timeout = 20 #default # if 'timeout' in self.options: # timeout = self.options['timeout'] timeout = self.options.get('timeout', 20) raw = 'raw' in self.options fname_sch = get_fname(self) elems = [] if raw: def export_func(fname_sch, fname_img_abs): return raw_partlist(fname_sch, timeout=timeout) s = do_action(fname_sch, None, self, export_func) else: def export_func(fname_sch, fname_img_abs): return structured_partlist(fname_sch, timeout=timeout) (header, data) = do_action(fname_sch, None, self, export_func) if raw: node_class = nodes.literal_block elems = [node_class(s, s)] else: if 'header' in self.options: selected = self.options['header'] selected = selected.split(',') selected = [x.strip() for x in selected] else: selected = header d = [ ','.join(['"' + dic[x] + '"' for x in selected]) for dic in data ] selected = ','.join(['"' + x + '"' for x in selected]) # self.options['header-rows'] = 1 self.options['header'] = selected self.content = StringList(d) self.arguments[0] = '' elems = CSVTable.run(self) return elems
def run(self): args = self.arguments fname = args[-1] env = self.state.document.settings.env fname, abs_fname = env.relfn2path(fname) basename = os.path.basename(fname) dirname = os.path.dirname(fname) try: if 'intro' in self.options: intro = self.options['intro'][:195] + '...' else: _, blocks = sphinx_gallery.gen_rst.split_code_and_text_blocks( abs_fname) intro, _ = sphinx_gallery.gen_rst.extract_intro_and_title( abs_fname, blocks[0][1]) thumbnail_rst = sphinx_gallery.backreferences._thumbnail_div( dirname, basename, intro) if 'figure' in self.options: rel_figname, figname = env.relfn2path(self.options['figure']) save_figname = os.path.join('_static/thumbs/', os.path.basename(figname)) try: os.makedirs('_static/thumbs') except OSError: pass x, y = (400, 280) if 'size' in self.options: x, y = self.options['size'].split(" ") sphinx_gallery.gen_rst.scale_image(figname, save_figname, x, y) # replace figure in rst with simple regex thumbnail_rst = re.sub(r'..\sfigure::\s.*\.png', '.. figure:: /{}'.format(save_figname), thumbnail_rst) thumbnail = StringList(thumbnail_rst.split('\n')) thumb = nodes.paragraph() self.state.nested_parse(thumbnail, self.content_offset, thumb) return [thumb] except FileNotFoundError as e: print(e) return []
def parse_doc(self, doc: str, source: str, idt: int = 0) -> StringList: """Convert doc string to StringList Args: doc: Documentation text source: Source filename idt: Result indentation in characters (default 0) Returns: StringList of re-indented documentation wrapped in newlines """ doc = dedent(doc or "").strip("\n") doc = indent(doc, " " * idt) doclines = [''] + doc.splitlines() + [''] return StringList(doclines, source)
def numpyclass_directive(desctype, arguments, options, content, lineno, content_offset, block_text, state, state_machine): try: doc = SphinxDocString(content) sig = doc.extract_signature() text = StringList(doc.format()) if sig is not None: arguments[0] += sig interpreted = desc_directive('class', arguments, options, text, lineno, content_offset, text, state, state_machine) return interpreted except: raise
def run(self): zenpy_client = Zenpy(subdomain="party", email="face@toe", password="******") node_list = [] cache_node = container() cache_sections = self.generate_cache_sections(zenpy_client) for cache_section in cache_sections: node = paragraph() self.state.nested_parse(StringList(cache_section.split('\n')), 0, node) node_list.append(node) node_list.append(cache_node) return node_list
def run(self): if len(self.arguments) == 0: types = json.loads('\n'.join(self.content)) else: types = self.iter_types( [get_obj_from_module(arg.strip()) for arg in self.arguments]) content = [] for typ in types: content.extend(doc_type(typ)) node = addnodes.desc_content() self.state.nested_parse(StringList(content), self.content_offset, node) return [node]
def setUp(self) -> None: self.untouched_sys_path = sys.path[:] sample_prog_path = os.path.join(os.path.dirname(__file__), "..", "doc") sys.path.insert(0, sample_prog_path) self.directive = AutoprogramDirective( "autoprogram", ["cli:parser"], {"prog": "cli.py"}, StringList([], items=[]), 1, 0, ".. autoprogram:: cli:parser\n :prog: cli.py\n", None, None, )
def format_attr(package, attr, formatter_name='default_formatter'): value = getattr(package, attr, None) field_name = attr if not attr.endswith('s') else attr[:-1] field_header = u':' + field_name + ':' formatter = FORMATTERS[formatter_name] field_content = [] if value: if attr.endswith('s'): for v in value: field_content.append(field_header) field_content.extend([' ' + line for line in formatter(v)]) else: field_content.append(field_header) field_content.extend([' ' + line for line in formatter(value)]) return StringList(field_content)
def run(self): try: if 'tooltip' in self.options: tooltip = self.options['tooltip'][:195] else: raise ValueError('tooltip not found') tags = "" if 'tags' in self.options: tags = self.options['tags'] if 'figure' in self.options: env = self.state.document.settings.env rel_figname, figname = env.relfn2path(self.options['figure']) thumbnail = os.path.join('_static/thumbs/', os.path.basename(figname)) try: os.makedirs('_static/thumbs') except FileExistsError: pass sphinx_gallery.gen_rst.scale_image(figname, thumbnail, 400, 280) else: thumbnail = '_static/thumbs/code.png' if 'description' in self.options: description = self.options['description'] else: raise ValueError('description not doc found') except FileNotFoundError as e: print(e) return [] except ValueError as e: print(e) raise return [] thumbnail_rst = GALLERY_TEMPLATE.format(tooltip=tooltip, thumbnail=thumbnail, description=description, tags=tags) thumbnail = StringList(thumbnail_rst.split('\n')) thumb = nodes.paragraph() self.state.nested_parse(thumbnail, self.content_offset, thumb) return [thumb]