def generate_func_autodoc(app, func): ad = AutoDirective(name='autofunc', arguments=[FULL_NAMES[func]], options={'noindex': True}, content=StringList([], items=[]), lineno=0, content_offset=1, block_text='', state=None, state_machine=None) ad.env = BuildEnvironment(app) ad.genopt = Options(noindex=True) ad.filename_set = set() ad.result = ViewList() documenter = FunctionDocumenter(ad, ad.arguments[0]) documenter.generate(all_members=True) with open(OUTPUT_FILES[func], 'a') as fid: for line in ad.result: fid.write(line + '\n')
def run(self): # If the user specifies a team, track only the deliverables # for that team. self.team_name = self.options.get('name') if not self.team_name: error = self.state_machine.reporter.error( 'No team name in team directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error] self.team_deliverables = _deliverables.get_team_deliverables( self.team_name) all_series = reversed( sorted(_deliverables.get_team_series(self.team_name))) result = ViewList() def _add(text): result.append(text, '<team tag>') for series in all_series: series_title = series.lstrip('_').title() _add(series_title) _add('=' * len(series_title)) _add('') _add('.. deliverable::') _add(' :series: %s' % series) _add(' :team: %s' % self.team_name) _add('') # NOTE(dhellmann): Useful for debugging. # print('\n'.join(result)) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def run(self) -> List[nodes.Node]: """ Create the extras_require node. """ extra: str = self.arguments[0] targetid = f'extras_require-{self.env.new_serialno("extras_require"):d}' targetnode = nodes.target('', '', ids=[targetid]) valid_requirements = get_requirements( env=self.env, extra=extra, options=self.options, content=self.content, ) if not valid_requirements: return self._problematic( "No requirements specified! No notice will be shown in the documentation." ) scope = self.options.get("scope", "module") pypi_name = self.env.config.pypi_name or self.env.config.project content = make_node_content(valid_requirements, pypi_name, extra, scope=scope) view = ViewList(content.split('\n')) extras_require_node = nodes.attention(rawsource=content) self.state.nested_parse(view, self.content_offset, extras_require_node) # type: ignore[arg-type] extras_require_purger.add_node(self.env, extras_require_node, targetnode, self.lineno) return [targetnode, extras_require_node]
def run(self): env = self.state.document.settings.env app = env.app builder = app.builder templates = getattr(builder, 'templates', None) if not templates: return [] region_name = self.options['region'] output = ViewList() template_name = 'include/meetups/listing.jinja' rendered = builder.templates.render( template_name, { 'meetups': meetups_by_region[region_name], }) for line in rendered.splitlines(): output.append(line, 'meetup-data') node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, output, node) return node.children
def setup_test(): global options, directive global processed_signatures options = Options( inherited_members=False, undoc_members=False, private_members=False, special_members=False, imported_members=False, show_inheritance=False, noindex=False, annotation=None, synopsis='', platform='', deprecated=False, members=[], member_order='alphabetic', exclude_members=set(), ignore_module_all=False, ) directive = Struct( env=app.builder.env, genopt=options, result=ViewList(), filename_set=set(), state=Mock(), ) directive.state.document.settings.tab_width = 8 processed_signatures = [] app._status.truncate(0) app._warning.truncate(0) yield app.registry.autodoc_attrgettrs.clear()
def run(self): size = self.options.get('size', 15) indices = self.options.get('indices', []) shuffle = 'shuffle' in self.options seed = self.options.get('seed', 42) titles = self.options.get('titles', False) width = self.options.get('width', None) env = self.state.document.settings.env app = env.app gallery_dir = app.builder.config.altair_gallery_dir gallery_ref = app.builder.config.altair_gallery_ref examples = populate_examples() if indices: examples = [examples[i] for i in indices] if shuffle: random.seed(seed) random.shuffle(examples) if size: examples = examples[:size] include = MINIGALLERY_TEMPLATE.render(image_dir='/_static', gallery_dir=gallery_dir, examples=examples, titles=titles, width=width) # parse and return documentation result = ViewList() for line in include.split('\n'): result.append(line, "<altair-minigallery>") node = nodes.paragraph() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def run(self) -> List[nodes.Node]: """ Process the content of the directive. """ summary = getattr(self.config, "documentation_summary", None) if self.env.app.builder.format.lower() == "latex" or not summary: return [] targetid = f'documentation-summary-{self.env.new_serialno("documentation-summary"):d}' content = f'**{summary}**' targetnode = nodes.paragraph(rawsource=f'**{summary}**', ids=[targetid]) self.state.nested_parse(ViewList([content]), self.content_offset, targetnode) # type: ignore summary_node_purger.add_node(self.env, targetnode, targetnode, self.lineno) return [targetnode]
def run(self): env = self.state.document.settings.env warning = self.state.document.reporter.warning config = env.config result_node = ViewList() def_path = os.path.join(config['rest_api_source_root'], self.arguments[0]) #print(config) #print('..') #print(self.options) base = { "rest_api_domain": config['rest_api_domain'], "rest_api_http_request_example_title": config['rest_api_http_request_example_title'], "rest_api_http_response_example_title": config['rest_api_http_response_example_title'], "rest_api_source_root": config['rest_api_source_root'], "global_codes": config['global_codes'], "global_headers": config['global_headers'], } #print(base) base.update(self.options) o = RestAPIContext(config['rest_api_domain'], def_path, **base) rst_context = o.get_rst_content() #print(rst_context) node = nodes.section() node.document = self.state.document with StringIO(rst_context) as fr: for index, line in enumerate(fr): new_line = line.rstrip() result_node.append(new_line, "<rest>") # Parse the rst. nested_parse_with_titles(self.state, result_node, node) return node.children
def run(self): fcts = lasif_cli._get_functions() all_nodes = [] node = nodes.section() node.document = self.state.document result = ViewList() mpi_enabled = [] # Find function that have MPI. for fct_name, fct in fcts.iteritems(): if not hasattr(fct, "_is_mpi_enabled") or not fct._is_mpi_enabled: continue mpi_enabled.append(fct_name) for fct_name in sorted(mpi_enabled): result.append("* `lasif %s`_" % fct_name, "<lasif_cli_list>") self.state.nested_parse(result, 0, node, match_titles=1) all_nodes.extend(node.children) return all_nodes
def run(self): table_code, test_code = CodeDiffParser().parse(list(self.content), **self.options) # Create a test node as a comment node so it won't show up in the docs. # We add attribute "testnodetype" so it is be picked up by the doctest # builder. This functionality is not officially documented but can be found # in the source code: # https://github.com/sphinx-doc/sphinx/blob/3.x/sphinx/ext/doctest.py # (search for 'testnodetype'). test_code = '\n'.join(test_code) test_node = nodes.comment(test_code, test_code, testnodetype='testcode') # Set the source info so the error message is correct when testing. self.set_source_info(test_node) test_node['options'] = {} test_node['language'] = 'python3' # The table node is the side-by-side diff view that will be shown on RTD. table_node = nodes.paragraph() self.content = ViewList(table_code, self.content.parent) self.state.nested_parse(self.content, self.content_offset, table_node) return [table_node, test_node]
def run(self): self.env = env = self.state.document.settings.env self.genopt = {} self.warnings = [] self.result = ViewList() names = [ x.strip().split()[0] for x in self.content if x.strip() and re.search(r'^[~a-zA-Z_]', x.strip()[0]) ] if 'automembers' in self.options: names.extend(self.find_automembers()) items = self.get_items(names) nodes = self.get_table(items) if 'toctree' in self.options: dirname = posixpath.dirname(env.docname) tree_prefix = self.options['toctree'].strip() docnames = [] for name, sig, summary, real_name in items: docname = posixpath.join(tree_prefix, real_name) docname = posixpath.normpath(posixpath.join(dirname, docname)) if docname not in env.found_docs: self.warn('toctree references unknown document %r' % docname) docnames.append(docname) tocnode = addnodes.toctree() tocnode['includefiles'] = docnames tocnode['entries'] = [(None, docname) for docname in docnames] tocnode['maxdepth'] = -1 tocnode['glob'] = None tocnode = autosummary_toc('', '', tocnode) nodes.append(tocnode) return self.warnings + nodes
def run(self): node = nodes.section() node.document = self.state.document result = ViewList() for line in QuickReferenceFlaskDirective.header: result.append(line, '<qrefflask>') table={} table_sorted_names=[] for table_row in self.make_rst(qref=True): name = table_row['name'] if table.get(name) is None: table[name]=[] table[name].append(table_row) if name not in table_sorted_names: table_sorted_names.append(name) table_sorted_names.sort() for name in table_sorted_names: # Keep table display clean by not repeating duplicate # resource names and descriptions display_name = name previous_description=None for row in table[name]: result.append(' * - %s' % display_name, '<qrefflask>') display_name ="" result.append(row['operation'], '<qrefflask>') description = row['description'] if previous_description is not None and previous_description == description: description ="" else: previous_description = description result.append(' - %s' % description, '<qrefflask>') result.append('', '<qrefflask>') nested_parse_with_titles(self.state, result, node) return node.children
def run(self): # type: () -> List[nodes.Node] self.genopt = Options() self.warnings = [] # type: List[nodes.Node] self.result = ViewList() names = [x.strip().split()[0] for x in self.content if x.strip() and re.search(r'^[~a-zA-Z_]', x.strip()[0])] items = self.get_items(names) nodes = self.get_table(items) if 'toctree' in self.options: dirname = posixpath.dirname(self.env.docname) tree_prefix = self.options['toctree'].strip() docnames = [] excluded = Matcher(self.config.exclude_patterns) for name, sig, summary, real_name in items: docname = posixpath.join(tree_prefix, real_name) docname = posixpath.normpath(posixpath.join(dirname, docname)) if docname not in self.env.found_docs: if excluded(self.env.doc2path(docname, None)): self.warn('toctree references excluded document %r' % docname) else: self.warn('toctree references unknown document %r' % docname) docnames.append(docname) tocnode = addnodes.toctree() tocnode['includefiles'] = docnames tocnode['entries'] = [(None, docn) for docn in docnames] tocnode['maxdepth'] = -1 tocnode['glob'] = None tocnode = autosummary_toc('', '', tocnode) nodes.append(tocnode) return self.warnings + nodes
def run(self): env = self.state.document.settings.env relpath, abspath = env.relfn2path(directives.path(self.arguments[0])) # Add OpenAPI spec as a dependency to the current document. That means # the document will be rebuilt if the spec is changed. env.note_dependency(relpath) # Read the spec using encoding passed to the directive or fallback to # the one specified in Sphinx's config. if abspath not in _specCache: encoding = self.options.get('encoding', env.config.source_encoding) with io.open(abspath, 'rt', encoding=encoding) as stream: spec = yaml.load(stream, _YamlOrderedLoader) _specCache[abspath] = spec else: spec = _specCache[abspath] # URI parameter is crucial for resolving relative references. So # we need to set this option properly as it's used later down the # stack. self.options.setdefault('uri', 'file://%s' % abspath) # reStructuredText DOM manipulation is pretty tricky task. It requires # passing dozen arguments which is not easy without well-documented # internals. So the idea here is to represent OpenAPI spec as # reStructuredText in-memory text and parse it in order to produce a # real DOM. viewlist = ViewList() for line in openapi2httpdomain(spec, **self.options): viewlist.append(line, '<openapi>') # Parse reStructuredText contained in `viewlist` and return produced # DOM nodes. node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, viewlist, node) return node.children
def run(self): model_path = self.arguments[0] module_name, model_name = model_path.rsplit(".", 1) try: module = importlib.import_module(module_name) except ImportError: pass model = getattr(module, model_name, None) if model is None: pass if type(model) != Viewable: pass model_obj = model() model_json = json.dumps(json.loads( serialize_json(model_obj.dump(changed_only=False, validate=False))), sort_keys=True, indent=2, separators=(',', ': ')) rst_text = MODEL_TEMPLATE.render( model_path=model_path, model_json=model_json, ) result = ViewList() for line in rst_text.split("\n"): result.append(line, "<bokeh-model>") node = nodes.paragraph() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def run(self): # Get the series we are reporting on series = self.options.get('series') if not series: raise self.error('series value must be set to a valid cycle name.') LOG.debug('[highlights] gathering highlights for {}'.format(series)) result = ViewList() series_highlights = self._get_deliverable_highlights(series) source_name = '<{}>'.format(__name__) for team in sorted(series_highlights.keys(), key=lambda x: x.lower()): LOG.debug('[highlights] rendering %s highlights for %s', team.title(), series) tdata = _GOV_DATA.get_team(team) title = team.title() if tdata.service: title = "{} - {}".format(title, tdata.service) result.append(title, source_name) result.append('-' * len(title), source_name) if tdata.mission: result.append(tdata.mission, source_name) result.append('', source_name) result.append('**Notes:**', source_name) result.append('', source_name) for item in series_highlights[team]: result.append('- {}'.format(item), source_name) result.append('', source_name) # NOTE(dhellmann): Useful for debugging. # print('\n'.join(result)) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def _setup(**kw): global options, directive, _warnings, app from schedula.ext.dispatcher import PLOT _warnings = [] options = Struct( des=True, opt=PLOT, data=True, func=True, code=True, dsp=True, height=None, width=None, inherited_members=False, undoc_members=False, private_members=False, special_members=False, imported_members=False, show_inheritance=False, noindex=False, annotation=None, synopsis='', platform='', deprecated=False, members=[], member_order='alphabetic', exclude_members=set(), ) settings = Struct(tab_width=8) document = Struct(settings=settings) from docutils.statemachine import ViewList directive = Struct(env=app.builder.env, genopt=options, result=ViewList(), warn=warnfunc, filename_set=set(), state=Struct(document=document), **kw)
def run(self): plugin_name = self.arguments[0] parent, plugin = util.object_from_name(plugin_name) if isinstance(plugin, types.ModuleType): # document all plugins in module module = plugin mod_name = module.__name__ plugins = self.plugins(module) else: if "module" in self.options: mod_name = self.options["module"] else: mod_name = plugin_name[0:plugin_name.index(plugin.__name__) - 1] plugins = [plugin] rst = ViewList() if mod_name: rst.append(u".. automodule :: %s\n" % mod_name, AD) rst.append(u"", AD) for plug in plugins: self.document(rst, plug) # parse rst and generate new nodelist state = self.state node = nodes.section() node.document = state.document surrounding_title_styles = state.memo.title_styles surrounding_section_level = state.memo.section_level state.memo.title_styles = [] state.memo.section_level = 0 state.nested_parse(rst, 0, node, match_titles=1) state.memo.title_styles = surrounding_title_styles state.memo.section_level = surrounding_section_level return node.children
def run(self) -> List[Node]: try: from mantidimaging.core.operations.loader import load_filter_packages except ImportError: raise ValueError( "operations_user_doc could not import load_filter_packages") rst_lines = [] operations = load_filter_packages() for op in operations: # Title rst_lines += make_heading(op.filter_name, "-") # Description from class doc string rst_lines += split_lines(inspect.cleandoc(op.__doc__)) rst_lines.append("") # parameters from filter_func if op.filter_func.__doc__ is not None: rst_lines += get_params(op.filter_func.__doc__) rst_lines.append("") rst_lines.append( f":class:`{op.filter_name} API docs<{op.__module__}>`") rst_lines.append("") rst = ViewList() for n, rst_line in enumerate(rst_lines): rst.append(rst_line, "generated.rst", n) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, rst, node) return node.children
def run(self): # implementation is based on the docs for parsing directive content as ReST doc: # https://www.sphinx-doc.org/en/master/extdev/markupapi.html#parsing-directive-content-as-rest # which is how we will create rst here and have sphinx parse it # we need to add content lines into a ViewList which represents the content # of this directive, each one is appended with a "source" name # the best documentation for docutils is the source, so for ViewList, see... # https://sourceforge.net/p/docutils/code/HEAD/tree/trunk/docutils/docutils/statemachine.py # writing the source name with angle-brackets seems to be the norm, but it's not # clear why -- perhaps docutils will care about the source in some way viewlist = ViewList() for line in self.gen_rst(): viewlist.append(line, "<automethodlist>") # create a section node (it doesn't really matter what node type we use here) # and add the viewlist we just created as the children of the new node via the # nested_parse method # then return the children (i.e. discard the docutils node) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, viewlist, node) return node.children
def run(self) -> List[nodes.Node]: """ Create the rest_example node. """ targetid = f'example-{self.env.new_serialno("sphinx-toolbox rest_example"):d}' targetnode = nodes.target('', '', ids=[targetid]) content = make_rest_example( self.options, self.env, self.content, # type: ignore ) view = ViewList(content) example_node = nodes.paragraph(rawsource=content) # type: ignore self.state.nested_parse(view, self.content_offset, example_node) # type: ignore rest_example_purger.add_node(self.env, example_node, targetnode, self.lineno) return [targetnode, example_node]
def run_section(self, comment, base_ids): r""" Execute a nested parsing on a block comment that will contains probably some restructured text stuff. We are using nested parsing with titles and returning the whole section childrens. In general it can be seed as a function that converts `CommentField` in parsed document, using nested parsing methods. :param comment: the comment block to parse :param ids: the id to be used for the source file name generation (Sphinx requirements) and section ids (lost in return) :return: the children of a section to be added to the document corpus """ ids = f"{base_ids}.{id(comment)}" comment_file = f"{ids}.rst" rst = ViewList() for line_no, line_txt in enumerate(comment.lines): rst.append(line_txt, comment_file, line_no) section = nodes.section(ids=[ids], classes=[ids], names=[ids]) section.document = self.state.document nested_parse_with_titles(self.state, rst, section) return section.children
def run(self): # pragma: no cover """Called by Sphinx to generate documentation for this directive.""" if self.directive_name is None: raise NotImplementedError('directive_name must be implemented by ' 'subclasses of BaseDirective') env, state = self._prepare_env() state.doc_names.add(env.docname) directive_name = '<{}>'.format(self.directive_name) node = nodes.section() node.document = self.state.document result = ViewList() for line in self._render_rst(): if line.startswith(HEADING_TOKEN): # Remove heading token, then append 2 lines, one with # the heading text, and the other with the dashes to # underline the heading. heading = line[HEADING_TOKEN_LENGTH:] result.append(heading, directive_name) result.append('-' * len(heading), directive_name) else: result.append(line, directive_name) nested_parse_with_titles(self.state, result, node) return node.children
def _get_row(self, obj): template = ":{}:`{} <{}>`\\ {}" if "nosignatures" in self.options: template = ":{}:`{} <{}>`" col1 = template.format("obj", obj.short_name, obj.name, escape("({})".format(obj.args))) col2 = obj.summary row = nodes.row("") for text in (col1, col2): node = nodes.paragraph("") view_list = ViewList() view_list.append(text, "<autosummary>") self.state.nested_parse(view_list, 0, node) try: if isinstance(node[0], nodes.paragraph): node = node[0] except IndexError: pass row.append(nodes.entry("", node)) return row
def run(self): config_nodes = [] for name, (attr, doc) in CONFIG_META.items(): # add title and link id = nodes.make_id('config-' + name) node = talisker_config() section = nodes.section(ids=[id]) section += nodes.title(name, name) node += section # render docstring as ReST viewlist = ViewList() docstring = extract_docstring(doc) for i, line in enumerate(docstring.splitlines()): viewlist.append(line, 'config.py', i) doc_node = nodes.section() doc_node.document = self.state.document nested_parse_with_titles(self.state, viewlist, doc_node) node += doc_node config_nodes.append(node) return config_nodes
def setup_test(): global options, directive global processed_docstrings, processed_signatures, _warnings options = Struct( inherited_members=False, undoc_members=False, private_members=False, special_members=False, imported_members=False, show_inheritance=False, noindex=False, annotation=None, synopsis='', platform='', deprecated=False, members=[], member_order='alphabetic', exclude_members=set(), ignore_module_all=False, ) directive = Struct( env=app.builder.env, genopt=options, result=ViewList(), warn=warnfunc, filename_set=set(), ) processed_docstrings = [] processed_signatures = [] _warnings = [] yield AutoDirective._special_attrgetters.clear()
def run(self): prop_path = self.arguments[0] module_path, model_name, prop_name = prop_path.rsplit('.', 2) try: module = importlib.import_module(module_path) except ImportError: pass model = getattr(module, model_name, None) if model is None: pass if type(model) != Viewable: pass model_obj = model() prop = getattr(model_obj.__class__, prop_name) type_info = self._get_type_info(prop) rst_text = PROP_TEMPLATE.render( name=prop_name, module=module_path, type_info=type_info, doc="" if prop.__doc__ is None else textwrap.dedent(prop.__doc__), ) result = ViewList() for line in rst_text.split("\n"): result.append(line, "<bokeh-prop>") node = nodes.paragraph() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def _parse_file(self, source): comments = {} with open(source, 'r') as src: doc = src.read() in_docstring = False for linenum, line in enumerate(doc.splitlines(), start=1): line = line.lstrip() if line.startswith(self.config.autoyaml_doc_delimiter): in_docstring = True comment = ViewList() elif line.startswith(self.config.autoyaml_comment) \ and in_docstring: line = line[len(self.config.autoyaml_comment):] # strip preceding whitespace if line and line[0] == ' ': line = line[1:] comment.append(line, source, linenum) elif in_docstring: comments[linenum] = comment in_docstring = False loader = Loader(doc) token = None while True: last_token, token = token, loader.get_token() if token is None: break end_line = token.end_mark.line if isinstance(last_token, tokens.KeyToken) \ and isinstance(token, tokens.ScalarToken): comment = comments.get(end_line + 1) if comment: with switch_source_input(self.state, comment): node = nodes.paragraph(text=token.value) definition = nodes.definition() node += definition self.state.nested_parse(comment, 0, definition) yield node
def run(self): size = self.options.get('size', 4) indices = self.options.get('indices', []) shuffle = 'shuffle' in self.options seed = self.options.get('seed', 42) titles = self.options.get('titles', False) width = self.options.get('width', None) env = self.state.document.settings.env app = env.app gallery_dir = app.builder.config.altair_gallery_dir gallery_ref = app.builder.config.altair_gallery_ref examples = populate_examples(indices=indices, shuffle=shuffle, shuffle_seed=seed, num_examples=size, gallery_dir=gallery_dir, gallery_ref=gallery_ref, code_below=True) include = MINIGALLERY_TEMPLATE.render(image_dir='/_images', gallery_dir=gallery_dir, examples=examples, titles=titles, width=width) # parse and return documentation result = ViewList() for line in include.split('\n'): result.append(line, "<altair-minigallery>") node = nodes.paragraph() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def run(self): path_to_model = self.arguments[0] np = os.path.normpath(os.path.join(os.getcwd(), path_to_model)) # check that the file exists if not os.path.isfile(np): raise IOError('File does not exist({0})'.format(np)) html_name = os.path.join( os.getcwd(), (os.path.basename(path_to_model).split('.')[0] + "_n2.html")) cmd = subprocess.Popen([ 'openmdao', 'view_model', np, '--no_browser', '--embed', '-o' + html_name ]) cmd_out, cmd_err = cmd.communicate() rst = ViewList() # Add the content one line at a time. # Second argument is the filename to report in any warnings # or errors, third argument is the line number. env = self.state.document.settings.env docname = env.doc2path(env.docname) rst.append(".. raw:: html", docname, self.lineno) rst.append(" :file: %s" % html_name, docname, self.lineno) # Create a node. node = nodes.section() # Parse the rst. nested_parse_with_titles(self.state, rst, node) # And return the result. return node.children