def genindex_nodes(genindexentries): indexlabel = _('Index') indexunder = '='*len(indexlabel) output=['DUMMY','=====','.. _genindex:\n\n',indexlabel,indexunder,''] for key, entries in genindexentries: #from pudb import set_trace; set_trace() output.append('.. cssclass:: heading4\n\n%s\n\n'%key) # initial for entryname, (links, subitems) in entries: if links: output.append('`%s <#%s>`_'%(entryname,nodes.make_id(links[0][1]))) for i,link in enumerate(links[1:]): output[-1]+=(' `[%s] <#%s>`_ '%(i+1,nodes.make_id(link[1]))) output.append('') else: output.append(entryname) if subitems: for subentryname, subentrylinks in subitems: if subentrylinks: output.append(' `%s <%s>`_'%(subentryname,subentrylinks[0])) for i,link in enumerate(subentrylinks[1:]): output[-1]+=(' `[%s] <%s>`_ '%(i+1,link)) output.append('') else: output.append(subentryname) output.append('') doctree = docutils.core.publish_doctree('\n'.join(output)) return doctree[1]
def resolve_xref(self, env, src_doc, builder, obj_type, target, node, cont_node): if obj_type == 'issue': return sphinx.util.nodes.make_refnode(builder, src_doc, src_doc, nodes.make_id(target), cont_node, None) else: dst_doc = self.find_doc(target, obj_type) if (dst_doc): return sphinx.util.nodes.make_refnode(builder, src_doc, dst_doc, nodes.make_id(target), cont_node, 'records.config')
def _outlinepath(self, term, g): p = [ nodes.make_id(term.astext()) ] while term.parent: term = term.parent if term.__class__.__name__ in g.outline_schema_terms: key = nodes.make_id(term.astext()) p.insert(0, key) return '.'.join(p)
def run(self): # type: () -> List[nodes.Node] objects = self.env.domaindata['std']['objects'] node = addnodes.productionlist() messages = [] # type: List[nodes.Node] i = 0 for rule in self.arguments[0].split('\n'): if i == 0 and ':' not in rule: # production group continue i += 1 try: name, tokens = rule.split(':', 1) except ValueError: break subnode = addnodes.production() subnode['tokenname'] = name.strip() if subnode['tokenname']: idname = nodes.make_id('grammar-token-%s' % subnode['tokenname']) if idname not in self.state.document.ids: subnode['ids'].append(idname) self.state.document.note_implicit_target(subnode, subnode) objects['token', subnode['tokenname']] = self.env.docname, idname subnode.extend(token_xrefs(tokens)) node.append(subnode) return [node] + messages
def make_glossary_term(env, textnodes, index_key, source, lineno, new_id=None): # get a text-only representation of the term and register it # as a cross-reference target term = nodes.term('', '', *textnodes) term.source = source term.line = lineno gloss_entries = env.temp_data.setdefault('gloss_entries', set()) objects = env.domaindata['std']['objects'] termtext = term.astext() if new_id is None: new_id = nodes.make_id('term-' + termtext) if new_id in gloss_entries: new_id = 'term-' + str(len(gloss_entries)) gloss_entries.add(new_id) objects['term', termtext.lower()] = env.docname, new_id # add an index entry too indexnode = addnodes.index() indexnode['entries'] = [('single', termtext, new_id, 'main', index_key)] indexnode.source, indexnode.line = term.source, term.line term.append(indexnode) term['ids'].append(new_id) term['names'].append(new_id) return term
def ref_role(role, rawtext, text, lineno, inliner, options={}, content=[]): """ ---------------------- Docutils role: ``ref`` ---------------------- Inserts a hyperlink reference to a figure or table with a custom label. Example ------- :: :ref:`image-filename.png` This will hyperlink to:: .. fig:: Some image here :image: image-filename.png :scale: 0.75 or :: :fig:`trapezoid` This will hyperlink to:: .. fig:: Sample Trapezoid :position: side :label: trapezoid \begin{tikzpicture} \draw [fill=black!10] (-1,0.7) -- (1,0.7) -- (0.7,-0.7) -- (-0.7,-0.7) -- cycle; \end{tikzpicture} Notes ----- * Works only for ``latex`` writer ... for now :) """ ref = nodes.make_id(text) if role in ['fig', 'tbl']: ref = role + ':' + ref t = dict() t['latex'] = r'\hyperref[%s]{\ref*{%s}}' % (ref, ref) t['html'] = r'<a href="#%s">[link]</a>' % (ref,) node_list = [ nodes.raw(text=t['latex'], format='latex'), nodes.raw(text=t['html'], format='html') ] return node_list, []
def eq_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # FIXME add stylable span inside link text = utils.unescape(text) target = "#eq-" + nodes.make_id(text) pnode = nodes.reference(text, text, internal=True, refuri=target) pnode["classes"] = ["reference"] return [pnode], []
def make_glossary_term(env, textnodes, index_key, source, lineno, new_id=None): # type: (BuildEnvironment, Iterable[nodes.Node], str, str, int, str) -> nodes.term # get a text-only representation of the term and register it # as a cross-reference target term = nodes.term('', '', *textnodes) term.source = source term.line = lineno gloss_entries = env.temp_data.setdefault('gloss_entries', set()) termtext = term.astext() if new_id is None: new_id = nodes.make_id('term-' + termtext) if new_id in gloss_entries: new_id = 'term-' + str(len(gloss_entries)) gloss_entries.add(new_id) std = cast(StandardDomain, env.get_domain('std')) std.add_object('term', termtext.lower(), env.docname, new_id) # add an index entry too indexnode = addnodes.index() indexnode['entries'] = [('single', termtext, new_id, 'main', index_key)] indexnode.source, indexnode.line = term.source, term.line term.append(indexnode) term['ids'].append(new_id) term['names'].append(new_id) return term
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA assert typ == 'eq' docname, number = self.data['objects'].get(target, (None, None)) if docname: if builder.name == 'latex': newnode = eqref('', **node.attributes) newnode['docname'] = docname newnode['target'] = target return newnode else: # TODO: perhaps use rather a sphinx-core provided prefix here? node_id = make_id('equation-%s' % target) if env.config.math_numfig and env.config.numfig: if docname in env.toc_fignumbers: number = env.toc_fignumbers[docname]['displaymath'].get(node_id, ()) number = '.'.join(map(str, number)) else: number = '' try: eqref_format = env.config.math_eqref_format or "({number})" title = nodes.Text(eqref_format.format(number=number)) except KeyError as exc: logger.warning(__('Invalid math_eqref_format: %r'), exc, location=node) title = nodes.Text("(%d)" % number) title = nodes.Text("(%d)" % number) return make_refnode(builder, fromdocname, docname, node_id, title) else: return None
def run(self): # type: () -> List[nodes.Node] domain = cast(StandardDomain, self.env.get_domain('std')) node = addnodes.productionlist() # type: nodes.Element i = 0 for rule in self.arguments[0].split('\n'): if i == 0 and ':' not in rule: # production group continue i += 1 try: name, tokens = rule.split(':', 1) except ValueError: break subnode = addnodes.production() subnode['tokenname'] = name.strip() if subnode['tokenname']: idname = nodes.make_id('grammar-token-%s' % subnode['tokenname']) if idname not in self.state.document.ids: subnode['ids'].append(idname) self.state.document.note_implicit_target(subnode, subnode) domain.add_object('token', subnode['tokenname'], self.env.docname, idname) subnode.extend(token_xrefs(tokens)) node.append(subnode) return [node]
def run(self): classes = self.options.get('class', []) classes.extend(self.options.get('header_class', '').split(' ')) self.options['class'] = classes set_classes(self.options) self.assert_has_content() text = '\n'.join(self.content) admonition_node = self.node_class(text, **self.options) self.add_name(admonition_node) if self.node_class is nodes.admonition: title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if not 'classes' in self.options: admonition_node['classes'] += [ 'admonition-' + nodes.make_id(title_text) ] body = nodes.container( classes=self.options.get('body_class', '').split(' ') ) self.state.nested_parse(self.content, self.content_offset, body) return [admonition_node, body]
def run(self): # largely lifted from the superclass in order to make titles work set_classes(self.options) # self.assert_has_content() text = '\n'.join(self.content) admonition_node = self.node_class(text, **self.options) self.add_name(admonition_node) if self.arguments: title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages else: # no title, make something up so we have an ID title_text = str(hash(' '.join(self.content))) if not 'classes' in self.options: admonition_node['classes'] += ['admonition-' + nodes.make_id(title_text)] self.state.nested_parse(self.content, self.content_offset, admonition_node) return [admonition_node]
def apply(self): settings = self.document.settings if not hasattr(settings, 'cc_embed') or not settings.cc_embed: return logger.debug('Running cc_embed xform') subrefname = nodes.fully_normalize_name( settings.cc_license_substitution_reference) subrefid = nodes.make_id(subrefname) subrefpath = nodes.fully_normalize_name( settings.cc_license_location) subreflist = self.document.traverse(nodes.substitution_reference) if subrefname not in subreflist: subrefloc = self.find_location(subrefpath) # append sub. ref. at location subrefnode = nodes.substitution_reference(None, None, refname=subrefname) subrefloc.append(subrefnode) self.document.note_substitution_ref(subrefnode, subrefname) license = self.generate_cc_license() # append sub. def. to document subdefnode = nodes.substitution_definition(names=subrefname) subdefnode.append(license) self.document.append(subdefnode) self.document.note_substitution_def(subdefnode, subrefname)
def option_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # FIXME add stylable span inside link text = utils.unescape(text) target = '#cmdoption-arg-' + nodes.make_id(text) pnode = nodes.reference(text, text, internal=True, refuri=target) pnode['classes'] = ['reference'] return [pnode], []
def apply(self): if not hasattr(self.document.settings, 'breadcrumb') \ or not getattr(self.document.settings, 'breadcrumb', None): return logger.debug('Running breadcrumb xform') subrefname = nodes.fully_normalize_name( self.document.settings.breadcrumb_substitution_reference) subrefid = nodes.make_id(subrefname) subreflist = self.document.traverse(nodes.substitution_reference) if subrefname not in subreflist: subloc = self.find_breadcrumb_location() # append sub. reference at location subrefnode = nodes.substitution_reference(None, subrefname) subrefnode['refname'] = subrefname subloc.append(subrefnode) self.document.note_substitution_ref(subrefnode, subrefname) breadcrumb = self.generate_breadcrumb() # append sub. definition to document subdefnode = nodes.substitution_definition() subdefnode.append(breadcrumb) subdefnode['names'].append(subrefname) self.document.append(subdefnode) self.document.note_substitution_def(subdefnode, subrefname)
def _new_config(conf_name, kind=None, **props): if not conf_name: conf_name = str(nodes.make_id(props['title'])) if not kind: if 'writer' in props: #assert 'builder_config' in props kind = PublishConfiguration elif 'builder' in props: kind = BuilderConfiguration #else: # kind = ProcessConfiguration if not kind: raise KeyError, "Missing parameter to determine Configuration kind. " if kind == BuilderConfiguration: assert 'builder' in props elif kind == ProcessConfiguration: #assert 'builder_config' in props assert props.get('parent','') elif kind == PublishConfiguration: assert 'writer' in props assert props.get('parent','') #assert 'builder_config' in props #parent = None #if 'builder_config' in props: # parent = BuilderConfiguration\ # .get_by_key_name(props['builder_config']) # assert parent, "No such builder-config: %(builder_config)s" % props # del props['builder_config'] c = kind(key_name=conf_name, **props) return c
def make_module_section(tree,parent_name=None): """Return a docutils tree constructed from this Module sub-tree """ module_name = os.path.splitext(tree.filename)[0] if parent_name: tree_name = "%s.%s"%(parent_name,module_name) else: tree_name = module_name title = "Module %s"%(tree_name) # @@@ Same considerations on id/name as above section = nodes.section(CLASS="module",id=nodes.make_id(title), name=nodes.fully_normalize_name(title)) title = nodes.title(text=title) section.append(title) # Assume that the docstring must be the first child if len(tree.children) > 0 and \ isinstance(tree.children[0],Docstring): section.append(make_docstring(tree.children[0])) # @@@ Again, I'm looking for classes before anything else for child in tree.children: if isinstance(child,Class): subsection = make_class_section(child,tree_name) section.append(subsection) return section
def glossary_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Glossary with cross-reference targets for :dfn: roles.""" env = state.document.settings.env node = addnodes.glossary() state.nested_parse(content, content_offset, node) # the content should be definition lists dls = [child for child in node if isinstance(child, nodes.definition_list)] # now, extract definition terms to enable cross-reference creation for dl in dls: dl['classes'].append('glossary') for li in dl.children: if not li.children or not isinstance(li[0], nodes.term): continue termtext = li.children[0].astext() new_id = 'term-' + nodes.make_id(termtext) if new_id in env.gloss_entries: new_id = 'term-' + str(len(env.gloss_entries)) env.gloss_entries.add(new_id) li[0]['names'].append(new_id) li[0]['ids'].append(new_id) state.document.settings.env.note_reftarget('term', termtext.lower(), new_id) return [node]
def visit_document(self, node): if isinstance(node[0], nodes.title): # insert section node if doc has only ONE section section = nodes.section() section['ids'].append(nodes.make_id(node[0].astext())) transpose_subnodes(node, section) node += section
def role(name, rawtext, text, lineno, inliner, options={}, content=[]): #version = self.arguments[0] #summary = self.arguments[1] version, summary = text.split(':', 1) summary = summary.strip() indexstring = 'bareos-{}; {}'.format(version, summary) idstring = 'bareos-{}-{}'.format(version, summary) _id = nodes.make_id(idstring) # Generic index entries indexnode = addnodes.index() indexnode['entries'] = [] indexnode['entries'].append([ 'pair', indexstring, _id, '', None ]) targetnode = nodes.target('', '', ids=[_id]) #text_node = nodes.Text(text='Version >= {}'.format(version)) #text_node = nodes.strong(text='Version >= {}'.format(version)) text_node = nodes.emphasis(text='Version >= {}'.format(version)) # target does not work with generated. #text_node = nodes.generated(text='Version >= {}'.format(version)) return [targetnode, text_node, indexnode], []
def add_target(self, ret): # type: (List[nodes.Node]) -> None node = cast(nodes.math_block, ret[0]) # assign label automatically if math_number_all enabled if node['label'] == '' or (self.config.math_number_all and not node['label']): seq = self.env.new_serialno('sphinx.ext.math#equations') node['label'] = "%s:%d" % (self.env.docname, seq) # no targets and numbers are needed if not node['label']: return # register label to domain domain = self.env.get_domain('math') try: eqno = domain.add_equation(self.env, self.env.docname, node['label']) # type: ignore # NOQA node['number'] = eqno # add target node node_id = make_id('equation-%s' % node['label']) target = nodes.target('', '', ids=[node_id]) self.state.document.note_explicit_target(target) ret.insert(0, target) except UserWarning as exc: self.state_machine.reporter.warning(exc, line=self.lineno)
def run(self): env = self.state.document.settings.env node = addnodes.glossary() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) # the content should be definition lists dls = [child for child in node if isinstance(child, nodes.definition_list)] # now, extract definition terms to enable cross-reference creation new_dl = nodes.definition_list() new_dl['classes'].append('glossary') items = [] for dl in dls: for li in dl.children: if not li.children or not isinstance(li[0], nodes.term): continue termtext = li.children[0].astext() new_id = 'term-' + nodes.make_id(termtext) if new_id in env.gloss_entries: new_id = 'term-' + str(len(env.gloss_entries)) env.gloss_entries.add(new_id) li[0]['names'].append(new_id) li[0]['ids'].append(new_id) env.note_reftarget('term', termtext.lower(), new_id) # add an index entry too indexnode = addnodes.index() indexnode['entries'] = [('single', termtext, new_id, termtext)] li.insert(0, indexnode) items.append((termtext, li)) if 'sorted' in self.options: items.sort(key=lambda x: x[0].lower()) new_dl.extend(item[1] for item in items) node.children = [new_dl] return [node]
def visit_term(self, node): #print 'visit-dt', node.line, node ce = { # FIXME: '_line': node.line always last line in dl tree? '_label': node.astext() } ce['_id'] = nodes.make_id(ce['_label']) self.context.element = ce
def visit_title( self, node ): self.__super.visit_title( self, node ) if self.re_auto_id.match( self._node_id( node.parent ) ): name = nodes.make_id( node.astext() ) self = self.active_visitor() self.body.append( self.starttag( {}, 'a', '', name=name, href='#%s' % name, CLASS='subsection-title' ) )
def new_alias_for(user): newalias = str(nodes.make_id(user.email.split('@')[0])) assert not find_alias(None,newalias), "Primary alias in use for new user.. " if not find_alias(None,newalias): newalias = new_alias(user, newalias) return newalias else: logger.error("New name %s not available for user %s." % (newalias, user.email()))
def add(self, text): ids = make_id(text) if ids in self.refs: raise ValueError("adding a duplicate reference: {}".format(text)) else: name = fully_normalize_name(text) ref = Reference(text=text, ids=ids, names=name) self.refs[ids] = ref return ref
def flush_outline(self, node): """ There is nothing to add to current outline, finalize. """ ce = self.current_element ce['_id'] = nodes.make_id(ce['_label']) print 'end', self.current_element, self.previous_elements
def identifier_list(argument): names = argument.split() class_names = [] for name in names: class_name = nodes.make_id(name) if not class_name: raise ValueError('cannot make "%s" into a class name' % name) class_names.append(class_name) return class_names
def run(self): node = nodes.Element() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) node[0]['classes'] = ['glossary', 'docutils'] # Set correct IDs for terms for term in node[0]: new_id = 'term-' + nodes.make_id(term[0].astext()) term[0]['ids'].append(new_id) return [node[0]]
def _add_target(self, signode, name): """Register a link target ‘name’, pointing to signode.""" targetid = make_target(self.objtype, nodes.make_id(name)) if targetid not in self.state.document.ids: signode['ids'].append(targetid) signode['names'].append(name) signode['first'] = (not self.names) self.state.document.note_explicit_target(signode) self._record_name(name, targetid) return targetid
def section(self, block): new_section = nodes.section() new_section.line = block.start_line new_section['level'] = block.level title_node = nodes.title() title_node.line = block.start_line append_inlines(title_node, block.inline_content) new_section.append(title_node) name = nodes.fully_normalize_name(title_node.astext()) new_section['names'].append(name) self.current_node.document.note_implicit_target( new_section, new_section) new_section['ids'].append(nodes.make_id(name)) self.section_handler.add_new_section(new_section, block.level) self.current_node = new_section
def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index_key: str, source: str, lineno: int, node_id: str = None, document: nodes.document = None) -> nodes.term: # get a text-only representation of the term and register it # as a cross-reference target term = nodes.term('', '', *textnodes) term.source = source term.line = lineno termtext = term.astext() if node_id: # node_id is given from outside (mainly i18n module), use it forcedly term['ids'].append(node_id) elif document: node_id = make_id(env, document, 'term', termtext) term['ids'].append(node_id) document.note_explicit_target(term) else: warnings.warn( 'make_glossary_term() expects document is passed as an argument.', RemovedInSphinx40Warning) gloss_entries = env.temp_data.setdefault('gloss_entries', set()) node_id = nodes.make_id('term-' + termtext) if node_id == 'term': # "term" is not good for node_id. Generate it by sequence number instead. node_id = 'term-%d' % env.new_serialno('glossary') while node_id in gloss_entries: node_id = 'term-%d' % env.new_serialno('glossary') gloss_entries.add(node_id) term['ids'].append(node_id) std = cast(StandardDomain, env.get_domain('std')) std.note_object('term', termtext, node_id, location=term) # add an index entry too indexnode = addnodes.index() indexnode['entries'] = [('single', termtext, node_id, 'main', index_key)] indexnode.source, indexnode.line = term.source, term.line term.append(indexnode) return term
def run(self): self.assert_has_content() title = self.arguments[0] content = '\n'.join(self.content) latex = self.prepare_latex(content) math_node = self.make_math_node(latex) tid = nodes.make_id(title) target = nodes.target('', '', ids=['inference-' + tid]) self.state.document.note_explicit_target(target) term, desc = nodes.term('', title), nodes.description('', math_node) dli = nodes.definition_list_item('', term, desc) dl = nodes.definition_list(content, target, dli) set_source_info(self, dl) return [dl]
def class_option(argument): """ Convert the argument into a list of ID-compatible strings and return it. (Directive option conversion function.) Raise ``ValueError`` if no argument is found. """ if argument is None: raise ValueError('argument required but none supplied') names = argument.split() class_names = [] for name in names: class_name = nodes.make_id(name) if not class_name: raise ValueError('cannot make "%s" into a class name' % name) class_names.append(class_name) return class_names
def _generate_nodes(self, name, command, parent=None, show_nested=False, link_commands_prefix=None): """Generate the relevant Sphinx nodes. Format a `click.Group` or `click.Command`. :param name: Name of command, as used on the command line :param command: Instance of `click.Group` or `click.Command` :param parent: Instance of `click.Context`, or None :param show_nested: Whether subcommands should be included in output :returns: A list of nested docutil nodes """ ctx = click.Context(command, info_name=name, parent=parent) # Title section = nodes.section( '', nodes.title(text=name), ids=[nodes.make_id(ctx.command_path)], names=[nodes.fully_normalize_name(ctx.command_path)]) # Summary source_name = ctx.command_path result = statemachine.ViewList() lines = _format_command(ctx, show_nested, link_commands_prefix) for line in lines: result.append(line, source_name) self.state.nested_parse(result, 0, section) # Subcommands if show_nested: commands = getattr(ctx.command, 'commands', {}) for command_name, command_obj in sorted(commands.items()): section.extend(self._generate_nodes( command_name, command_obj, ctx, show_nested, link_commands_prefix)) return [section]
def _generate_section(self, name, config, cfg_section='default', remove_sasbase=False): """Generate the relevant Sphinx nodes. Generates a section for the Tree datamodel. Formats a tree section as a list-table directive. Parameters: name (str): The name of the config to be documented, e.g. 'sdsswork' config (dict): The tree dictionary of the loaded config environ cfg_section (str): The section of the config to load remove_sasbase (bool): If True, removes the SAS_BASE_DIR from the beginning of each path Returns: A section docutil node """ # the source name source_name = name # Title section = nodes.section( '', nodes.title(text=cfg_section), ids=[nodes.make_id(cfg_section)], names=[nodes.fully_normalize_name(cfg_section)]) # Summarize result = statemachine.ViewList() base = config['default']['filesystem'] if remove_sasbase else None lines = _format_command(cfg_section, config[cfg_section], base=base) for line in lines: result.append(line, source_name) self.state.nested_parse(result, 0, section) return [section]
def _generate_nodes(self, title, command_name, command_class, ignored_opts): """Generate the relevant Sphinx nodes. This is a little funky. Parts of this use raw docutils nodes while other parts use reStructuredText and nested parsing. The reason for this is simple: it avoids us having to reinvent the wheel. While raw docutils nodes are helpful for the simpler elements of the output, they don't provide an easy way to use Sphinx's own directives, such as the 'option' directive. Refer to [1] for more information. [1] http://www.sphinx-doc.org/en/stable/extdev/markupapi.html :param title: Title of command :param command_name: Name of command, as used on the command line :param command_class: Subclass of :py:class:`cliff.command.Command` :param prefix: Prefix to apply before command, if any :param ignored_opts: A list of options to exclude from output, if any :returns: A list of nested docutil nodes """ command = command_class(None, None) parser = command.get_parser(command_name) ignored_opts = ignored_opts or [] # Drop the automatically-added help action for action in list(parser._actions): for option_string in action.option_strings: if option_string in ignored_opts: del parser._actions[parser._actions.index(action)] break section = nodes.section('', nodes.title(text=title), ids=[nodes.make_id(title)], names=[nodes.fully_normalize_name(title)]) source_name = '<{}>'.format(command.__class__.__name__) result = statemachine.ViewList() for line in _format_parser(parser): result.append(line, source_name) self.state.nested_parse(result, 0, section) return [section]
def run(self): set_classes(self.options) self.assert_has_content() text = '\n'.join(self.content) admonition_node = self.node_class(text, **self.options) self.add_name(admonition_node) if self.node_class is nodes.admonition: title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if not 'classes' in self.options: admonition_node['classes'] += ['admonition-' + nodes.make_id(title_text)] self.state.nested_parse(self.content, self.content_offset, admonition_node) return [admonition_node]
def generate_help_text(command, prefix): ctx = click.Context(command) help_opts = command.get_help_option(ctx).opts full_cmd = ' '.join(prefix) block = section(None, title(None, full_cmd), ids=[make_id(full_cmd)], names=[full_cmd]) if help_opts: h = "$ {} {}\n".format(full_cmd, help_opts[0]) + command.get_help(ctx) block.append(literal_block(None, h, language='console')) if isinstance(command, click.core.MultiCommand): for c in command.list_commands(ctx): c = command.resolve_command(ctx, [c])[1] block.append(generate_help_text(c, prefix + [c.name])) return block
def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """""" class_value = nodes.make_id(arguments[0]) if class_value: pending = nodes.pending(misc.ClassAttribute, { 'class': class_value, 'directive': name }, block_text) state_machine.document.note_pending(pending) return [pending] else: error = state_machine.reporter.error( 'Invalid class attribute value for "%s" directive: %s' % (name, arguments[0]), nodes.literal_block(block_text, block_text), line=lineno) return [error]
def run(self): self.assert_has_content() text = '\n'.join(self.content) admonition_node = self.node_class(text) if self.arguments: title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if 'class' in self.options: classes = self.options['class'] else: classes = ['admonition-' + nodes.make_id(title_text)] admonition_node['classes'] += classes self.state.nested_parse(self.content, self.content_offset, admonition_node) return [admonition_node]
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA assert typ == 'eq' docname, number = self.data['objects'].get(target, (None, None)) if docname: if builder.name == 'latex': newnode = eqref('', **node.attributes) newnode['docname'] = docname newnode['target'] = target return newnode else: title = nodes.Text("(%d)" % number) node_id = make_id('equation-%s' % target) return make_refnode(builder, fromdocname, docname, node_id, title) else: return None
def run(self): # options given to the directive options = self.options # # ## make section # # make id idb = nodes.make_id('roadmap-'+options['title']) section = nodes.section(ids=[idb], classes=['roadmap-'+options['priority']]) # # # add title # header = nodes.section(ids=[nodes.make_id('roadmap-title-'+options['title'])], # classes=['roadmap-header-container']) header = nodes.inline() title = nodes.title(options['title'],options['title'], classes=['roadmap-title', 'roadmap-priority-'+options['priority']]) # link = nodes.raw() link_str = '<span><a href="'+options['dblink']+'" class="roadmap-dblink">priority: '+options['priority']+' | discuss>></a></span>' link = nodes.raw(link_str,link_str, format='html') # # # add content par = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, par) # # node = self.__class__.roadmap_class() # node += section # node += par # node = nodes.paragraph() node = section title += link node += title # node += link node += header # node += link node += par return [node]
def badge_role(name, rawtext, text, lineno, inliner, options=None, content=None): options = options or {} set_classes(options) classes = ['badge'] if color is None: classes.append('badge-' + make_id(text)) else: classes.append('badge-' + color) if len(text) == 1: classes.append('badge-one') options['classes'] = classes node = inline(rawtext, text, **options) return [node], []
def create_ref_node(contents, url): """ Creates reference node inside a paragraph. Args: contents (str): Text to be displayed. url (str): URL to be used for the reference. Returns: (nodes.paragraph) Paragraph node containing a reference based on the given url. """ p_node = nodes.paragraph() itemlink = nodes.reference() itemlink['refuri'] = url itemlink.append(nodes.Text(contents)) targetid = nodes.make_id(contents) target = nodes.target('', '', ids=[targetid]) p_node += target p_node += itemlink return p_node
def make_admonition(node_class, name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): warnings.warn('make_admonition is deprecated, use ' 'docutils.parsers.rst.directives.admonitions.BaseAdmonition ' 'instead', DeprecationWarning, stacklevel=2) text = '\n'.join(content) admonition_node = node_class(text) if arguments: title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if 'class' in options: classes = options['class'] else: classes = ['admonition-' + nodes.make_id(title_text)] admonition_node['classes'] += classes state.nested_parse(content, content_offset, admonition_node) return [admonition_node]
def make_not_python_section(tree,parent_name=None): """Return a docutils tree constructed from this NotPython (file) sub-tree """ if parent_name: tree_name = "%s.%s"%(parent_name,tree.filename) else: tree_name = tree.filename title = "File %s"%(tree_name) # @@@ Same considerations on id/name as above section = nodes.section(CLASS="file",id=nodes.make_id(title), name=nodes.fully_normalize_name(title)) title = nodes.title(text=title) section.append(title) paragraph = nodes.paragraph(text="File ") paragraph.append(nodes.literal(text=tree.filename)) paragraph.append(nodes.Text(" is not a Python module.")) section.append(paragraph) return section
def _generate_nodes(self, title, command_name, command_class, ignored_opts): """Generate the relevant Sphinx nodes. This doesn't bother using raw docutils nodes as they simply don't offer the power of directives, like Sphinx's 'option' directive. Instead, we generate reStructuredText and parse this in a nested context (to obtain correct header levels). Refer to [1] for more information. [1] http://www.sphinx-doc.org/en/stable/extdev/markupapi.html :param title: Title of command :param command_name: Name of command, as used on the command line :param command_class: Subclass of :py:class:`cliff.command.Command` :param prefix: Prefix to apply before command, if any :param ignored_opts: A list of options to exclude from output, if any :returns: A list of nested docutil nodes """ command = command_class(None, None) parser = command.get_parser(command_name) ignored_opts = ignored_opts or [] # Drop any ignored actions for action in list(parser._actions): for option_string in action.option_strings: if option_string in ignored_opts: del parser._actions[parser._actions.index(action)] break section = nodes.section('', nodes.title(text=title), ids=[nodes.make_id(title)], names=[nodes.fully_normalize_name(title)]) source_name = '<{}>'.format(command.__class__.__name__) result = statemachine.ViewList() for line in _format_parser(parser): result.append(line, source_name) self.state.nested_parse(result, 0, section) return [section]
def _init(self, name: str, qualified_type_name: str): self._node_id = nodes.make_id(nodes.fully_normalize_name(name)) self._node = ModelElementNode(ids=[self._node_id]) self._parse_msgs = [] self._target = nodes.target() self.state.add_target(self._node_id, '', self._target, self.lineno) ## add node to index name_in_index = 'ModelElement; ' + name target_anchor = self._node_id self._indexnode = addnodes.index() self._indexnode['entries'] = ne = [] self._indexnode['inline'] = False set_source_info(self, self._indexnode) ne.extend(process_index_entry(name_in_index, target_anchor)) self._model_element_type = reflectionutil.model_element_type( qualified_type_name=qualified_type_name, )
def run(self): self.signatures = [] indexnode = super().run()[0] # makes calls to handle_signature table = nodes.inline(classes=['prodn-table']) tgroup = nodes.inline(classes=['prodn-column-group']) for i in range(3): tgroup += nodes.inline(classes=['prodn-column']) table += tgroup tbody = nodes.inline(classes=['prodn-row-group']) table += tbody # create rows for signature in self.signatures: lhs, op, rhs = signature position = self.state_machine.get_source_and_line(self.lineno) row = nodes.inline(classes=['prodn-row']) entry = nodes.inline(classes=['prodn-cell-nonterminal']) if lhs != "": target_name = 'grammar-token-' + nodes.make_id(lhs) target = nodes.target('', '', ids=[target_name], names=[target_name]) # putting prodn-target on the target node won't appear in the tex file inline = nodes.inline(classes=['prodn-target']) inline += target entry += inline entry += notation_to_sphinx('@'+lhs, *position) else: entry += nodes.literal('', '') row += entry entry = nodes.inline(classes=['prodn-cell-op']) entry += nodes.literal(op, op) row += entry entry = nodes.inline(classes=['prodn-cell-production']) entry += notation_to_sphinx(rhs, *position) row += entry tbody += row return [indexnode, table] # only this node goes into the doc
def run(self): sett = self.state.document.settings language_code = sett.language_code env = self.state.document.settings.env config = env.config options = self.options idb = nodes.make_id("csharpdocs-class-" + self.content[0].replace(" ", "_")) node = csharpdocs_class_node(ids=[idb], classes=["csharpdocs-class-node"]) node = csharpdocs_method_node(ids=[idb], classes=["csharpdocs-property-node"]) def_node = csharpdocs_property_definition_node( classes=["csharpdocs-property-definition-node"]) property_node = nodes.paragraph( classes=["csharpdocs-property-definition-property"]) if options["access"] != "": property_node += nodes.inline( text=options["access"] + " ", classes=["csharpdocs-property-definition-access"]) reader = DefinitionReader(self.content[0]) xtype = reader.read_next_type() name = reader.read_next_name() self._append_type(property_node, xtype) property_node += nodes.inline(text=" ") self._append_name(property_node, name) def_node += property_node node += def_node node += nodes.paragraph(text="\n".join(self.content[1:]), classes=["csharpdocs-property-description"]) return [node]
def apply(self): # desc nodes of sphinx represent domain-specific entities, # their first children, desc_signature nodes, are their "heads" for signode in self.document.traverse(addnodes.desc_signature): descnode = signode.parent domain = descnode['domain'] objtype = descnode['objtype'] # only interested in py:class and py:function entities if domain != 'py' or objtype not in ['class', 'function']: continue # wrap the desc node in a section node, which will appear in TOC name = signode['fullname'] secname = objtype + ' ' + name _ = '' secnode = nodes.section(_, nodes.title(_, objtype + ' ', nodes.literal(_, name)), ids=[nodes.make_id(secname)], names=[nodes.fully_normalize_name(secname)]) descnode.replace_self(secnode) secnode += descnode
def make_external_item_ref(app, targettext, relationship): '''Generate a reference to an external item''' if relationship not in app.config.traceability_external_relationship_to_url: return p_node = nodes.paragraph() link = nodes.reference() txt = nodes.Text(targettext) tgt_strs = targettext.split(':') # syntax = field1:field2:field3:... url = app.config.traceability_external_relationship_to_url[relationship] cnt = 0 for tgt_str in tgt_strs: cnt += 1 url = url.replace(EXTERNAL_LINK_FIELDNAME + str(cnt), tgt_str) link['refuri'] = url link.append(txt) targetid = nodes.make_id(targettext) target = nodes.target('', '', ids=[targetid]) p_node += target p_node += link return p_node
def run(self): if not hasattr(self.env, 'bioconda_lint_checks'): self.env.bioconda_lint_checks = { str(check): check for check in get_checks() } # gather data check_name = self.arguments[0] if check_name not in self.env.bioconda_lint_checks: self.error("Duplicate lint description") check = self.env.bioconda_lint_checks.pop(check_name) _, lineno = inspect.getsourcelines(check) lineno += 1 fname = inspect.getfile(check) doclines = inspect.getdoc(check).splitlines() docline_src = [(fname, i) for i in range(lineno, lineno + len(doclines))] lines = StringList(doclines, items=docline_src) # create a new section with title section = nodes.section(ids=[nodes.make_id(check_name)]) title_text = f'":py:class:`{check_name}`"' title_nodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.title(check_name, '', *title_nodes) section += title admonition = nodes.admonition() title_text = doclines[0].rstrip('.') title_nodes, messages = self.state.inline_text(title_text, lineno) title = nodes.title(title_text, '', *title_nodes) admonition += title admonition += messages self.state.nested_parse(lines[1:], 0, admonition) section += admonition # add remaining content of directive par = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, par) section += par return [section]
def _generate_nodes(self, snakefile, rules): """Generate Sphinx nodes from parsed snakefile""" section = nodes.section('', nodes.title("thetitle"), ids=[nodes.make_id(snakefile)], names=[nodes.fully_normalize_name(snakefile)]) result = statemachine.ViewList() for rule in rules: result.append(".. class:: {}".format(rule.name), snakefile) result.append("", snakefile) if rule.docstring: for line in rule.docstring.splitlines(): result.append(" " + line, snakefile) result.append("", snakefile) self.state.nested_parse(result, 0, section) return [section]
def run(self, **kwargs: Any) -> None: """Run the post-transform. Iterate over all nodes. If the node is a ``section`` node, obtain the title from the names field. If the node is an admonition (but not a ``desc`` node), assign an ID of the form ``<sectiontitle>-note-<#>``. """ note_id = 1 title = "undefined" for node in self.document.traverse(): if isinstance(node, nodes.section): if node["names"]: # pragma: nocover title = nodes.make_id(node["names"][0]) # add automatic IDs only to admonition nodes that are not <desc> # and that don't already have an explicit label if (isinstance(node, nodes.Admonition) and not isinstance(node, desc) and not node["ids"]): node["ids"] = [f"{title}-note-{note_id}"] note_id += 1
def make_admonition(node_class, name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): #if not content: # error = state_machine.reporter.error( # 'The "%s" admonition is empty; content required.' % (name), # nodes.literal_block(block_text, block_text), line=lineno) # return [error] text = '\n'.join(content) admonition_node = node_class(text) if arguments: title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) admonition_node += nodes.title(title_text, '', *textnodes) admonition_node += messages if 'class' in options: classes = options['class'] else: classes = ['admonition-' + nodes.make_id(title_text)] admonition_node['classes'] += classes state.nested_parse(content, content_offset, admonition_node) return [admonition_node]
def run(self): set_classes(self.options) self.assert_has_content() text = "\n".join(self.content) admonition_node = self.node_class(text, **self.options) self.add_name(admonition_node) if self.node_class is nodes.admonition: title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.title(title_text, "", *textnodes) title.source, title.line = self.state_machine.get_source_and_line( self.lineno ) admonition_node += title admonition_node += messages if not "classes" in self.options: admonition_node["classes"] += [ "admonition-" + nodes.make_id(title_text) ] self.state.nested_parse(self.content, self.content_offset, admonition_node) return [admonition_node]
def make_class_section(tree,parent_name): """Return a docutils tree constructed from this Class sub-tree """ tree_name = "%s.%s"%(parent_name,tree.name) title = "Class %s"%(tree_name) # @@@ Same considerations on id/name as above section = nodes.section(CLASS="class",id=nodes.make_id(title), name=nodes.fully_normalize_name(title)) title = nodes.title(text=title) section.append(title) # Assume that the docstring must be the first child if len(tree.children) > 0 and \ isinstance(tree.children[0],Docstring): section.append(make_docstring(tree.children[0])) # @@@ Don't forget that we want base classes to be named at # some point return section
def handle_signature(self, sig, signode): sigid = nodes.make_id(sig) if self.parse_node: return self.parse_node(self.env, sigid, signode) else: signode.clear() signode += addnodes.desc_name(sigid, sig) name = sig # For tags, we extract just the tag name n = re.match('<([^ >/]*)', name) if n: name = n.group(1) # For attributes, we extract the attribute n = re.match('([^=]*)="([^"]*)"', name) if n: name = "%s-%s" % (n.group(1), n.group(2)) return name