def run(self): """ Parse a tabs directive """ self.assert_has_content() env = self.state.document.settings.env node = nodes.container() node['classes'] = ['sphinx-tabs'] tabs_node = nodes.container() tabs_node.tagname = 'div' classes = 'ui top attached tabular menu sphinx-menu' tabs_node['classes'] = classes.split(' ') env.temp_data['tab_ids'] = [] env.temp_data['tab_titles'] = [] env.temp_data['is_first_tab'] = True self.state.nested_parse(self.content, self.content_offset, node) tab_titles = env.temp_data['tab_titles'] for idx, [data_tab, tab_name] in enumerate(tab_titles): tab = nodes.container() tab.tagname = 'a' tab['classes'] = ['item'] if idx > 0 else ['active', 'item'] tab['classes'].append(data_tab) tab += tab_name tabs_node += tab node.children.insert(0, tabs_node) return [node]
def run(self): # FIXME: URL? uri = self.arguments[0] self.document = self.state_machine.document filename = self.download_image(uri) basename = self.uri_filename(filename) type = self.guess_type(filename) new_url = self.options.get('uploaded') if not new_url: new_url = self.upload_file(filename) document = self.document app = document.settings.application if not getattr(app, 'preview', None): app.save_directive_info(document, 'upload', uri, 'uploaded', new_url) node = nodes.container(classes=['wp-caption', 'alignleft']) size = self.file_size(filename) type = self.guess_type(filename) reference = nodes.reference(refuri=new_url) reference += nodes.Text(basename) para = nodes.paragraph() para.extend([nodes.Text("Uploaded: "), reference, nodes.Text(" ({type}, {size})".format(name=filename, type=type, size=size))]) node += para return [node, nodes.container(classes=['clear'])]
def run(self): # First argument is the name of the glyph panel_name = 'panel-{}'.format(self.custom_class) # get the label title title_text = self.options.get('title', self.custom_class.title()) # get the label content text = '\n'.join(self.content) # Create the panel element panel_element = nodes.container() panel_element['classes'] += ['panel', panel_name] # Create the panel headings heading_element = nodes.container(title_text) title_nodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.paragraph(title_text, '', *title_nodes) heading_element.append(title) heading_element['classes'] += ['panel-heading'] # Create a new container element (div) body_element = nodes.container(text) # Update its content self.state.nested_parse(self.content, self.content_offset, body_element) # Set its custom bootstrap classes body_element['classes'] += ['panel-body'] # add the heading and body to the panel panel_element.append(heading_element) panel_element.append(body_element) # Return the panel element return [panel_element]
def _get_custom_content(self): """Load custom content for each section and for program options""" content = nodes.container() self.state.nested_parse(self.content, self.content_offset, content) sections = {} options = {} if len(content) and isinstance(content[0], nodes.definition_list): for item in content[0]: term = None classifiers = [] definition = None for element in item.children: if isinstance(element, nodes.term): if element.children: term = str(element[0]).lower() elif isinstance(element, nodes.classifier): if element.children: classifiers.append(str(element[0]).lower()) elif isinstance(element, nodes.definition): if element.children: definition = nodes.container('', *element.children) if term in ['synopsis', 'description', 'options', 'option']: action = [c[1:] for c in classifiers if c and c[0] == '@'] action = action[0] if action else 'append' opts = [c for c in classifiers if c and c[0] != '@'] if definition: if term != 'option': sections[term] = dict(action=action, content=definition) else: for opt in opts: options[opt] = dict(action=action, content=definition) return sections, options
def _build_program_options(self, parser, custom_content): """ Build list of program options :param parser: pre-configured ArgumentParser instance :param custom_content: custom content for options :return: node forming program options """ result = nodes.container() if self.ignore_option_groups: actions = parser._get_positional_actions() + parser._get_optional_actions() actions = [a for a in actions if a.help is not SUPPRESS] for action in actions: cc = [v for k, v in custom_content.items() if k in action.option_strings] result.append(self._build_option(parser, action, cc[0] if cc else None)) else: for group in parser._action_groups: actions = [a for a in group._group_actions if a.help is not SUPPRESS] if actions: title = nodes.title(text=group.title.capitalize()) options = nodes.container() for action in actions: cc = [v for k, v in custom_content.items() if k in action.option_strings] options.append(self._build_option(parser, action, cc[0] if cc else None)) result.append(nodes.section('', title, options, ids=[group.title.lower()])) return result
def run(self): self.assert_has_content() node = nodes.container() name = self.arguments[0] # TODO: maybe use sphinx/docutils node instead of aplus_node for the link link = aplus_nodes.html(u'a', { u'href':u'#' + name, u'data-toggle':u'collapse'}) label = 'Show/Hide' if 'label' in self.options: label = self.options['label'] # Container for the hidden content classes = ['collapse'] if 'visible' in self.options: classes.append('in') collapsible = nodes.container('\n'.join(self.content)) collapsible['classes'].extend(classes) self.options['name'] = name self.add_name(collapsible) link.append(nodes.Text(label)) node.append(link) node.append(collapsible) self.state.nested_parse(self.content, self.content_offset, collapsible) return [node]
def run(self): document = self.state.document env = document.settings.env series = env.temp_data[SERIES_KEY] app = env.app if not document.settings.file_insertion_enabled: msg = "File insertion disabled" app.warn(msg) error = nodes.error('', nodes.inline(text=msg)) error.lineno = self.lineno return [error] patch = next(series, None) if patch is None: msg = "No patch left in queue %s" % series.path app.warn(msg) warning = nodes.warning('', nodes.inline(text=msg)) warning.lineno = self.lineno return [warning] if 'hidden' in self.options: return [] doc_dir = os.path.dirname(env.doc2path(env.docname)) patch_root = nodes.container(classes=['pq-patch']) for fname, path, hunks in patch: patch_root.append(nodes.emphasis(text=fname)) relative_path = os.path.relpath(path, doc_dir) try: lang = pygments.lexers.guess_lexer_for_filename( fname, open(path, 'rb').read()).aliases[0] except pygments.util.ClassNotFound: lang = 'guess' patchlines = [] section = nodes.container(classes=['pq-section']) for hunk in hunks: patchlines.extend(line.rstrip('\n') for line in hunk.hunk) section.extend(self.run_hunk(hunk, relative_path, lang=lang)) patch_root.append(section) patch_root.append( nodes.container( '', *self.run_diff(patchlines), classes=['pq-diff'])) patch_root.append( nodes.container( '', *self.run_content(relative_path, lang=lang), classes=['pq-file'])) undepend(env, relative_path) return [patch_root]
def run(self): try: lines = self.parse_lit(self.parse_file(self.arguments[0])) except IOError as exc: document = self.state.document return [document.reporter.warning(str(exc), line=self.lineno)] node = nodes.container() node['classes'] = ['lit-container'] node.document = self.state.document enum = nodes.enumerated_list() enum['classes'] = ['lit-docs'] node.append(enum) # make first list item list_item = nodes.list_item() list_item['classes'] = ['lit-item'] for is_doc, line in lines: if is_doc and line == ['']: continue section = nodes.section() if is_doc: section['classes'] = ['lit-annotation'] nested_parse_with_titles(self.state, ViewList(line), section) else: section['classes'] = ['lit-content'] code = '\n'.join(line) literal = nodes.literal_block(code, code) literal['language'] = 'yaml' set_source_info(self, literal) section.append(literal) list_item.append(section) # If we have a pair of annotation/content items, append the list # item and create a new list item if len(list_item.children) == 2: enum.append(list_item) list_item = nodes.list_item() list_item['classes'] = ['lit-item'] # Non-semantic div for styling bg = nodes.container() bg['classes'] = ['lit-background'] node.append(bg) return [node]
def make_process_node(self, process): """Fill the content of process definiton node. :param dict process: process data as given from yaml.load function :return: process node """ name = process['name'] slug = process['slug'] typ = process['type'] version = process['version'] description = process.get('description', '') source_uri = process['source_uri'] inputs = process.get('input', []) outputs = process.get('output', []) # Make process name a section title: section = nodes.section(ids=['process-' + slug]) section += nodes.title(name, name) # Make process header: section += self.make_process_header(slug, typ, version, source_uri, description, inputs) # Make inputs section: container_node = nodes.container(classes=['toggle']) container_header = nodes.paragraph(classes=['header']) container_header += nodes.strong(text='Input arguments') container_node += container_header container_body = nodes.container() for field_schema, _, path in iterate_schema({}, inputs, ''): container_body += nodes.strong(text=path) container_body += self.make_properties_list(field_schema) container_node += container_body section += container_node # Make outputs section: container_node = nodes.container(classes=['toggle']) container_header = nodes.paragraph(classes=['header']) container_header += nodes.strong(text='Output results') container_node += container_header container_body = nodes.container() for field_schema, _, path in iterate_schema({}, outputs, ''): container_body += nodes.strong(text=path) container_body += self.make_properties_list(field_schema) container_node += container_body section += container_node return [section, addnodes.index(entries=[('single', name, 'process-' + slug, '', None)])]
def run(self): indexnode, node = super(DjangoAdminModel, self).run() sig = self.arguments[0] lst = [] if not 'noautodoc' in self.options: exclude = [ a.strip() for a in self.options.get('exclude', '').split(',') ] app_label, model_name = sig.split('.') for name, opts in model_attributes(app_label, model_name).items(): if name in exclude: continue lst.append(".. djangoadmin:attribute:: %s.%s" % (sig, name)) lst.append('') lst.append(" %s" % unicode(opts['description'])) lst.append('') text = '\n'.join(lst) new_doc = new_document('temp-string', self.state.document.settings) parser = Parser() parser.parse(text, new_doc) container = nodes.container() container.extend(new_doc.children) node[1].extend(container) return [indexnode, node]
def run(self): # Uses a ‘container’ instead of a ‘literal_block’ to disable # Pygments-based post-processing (we could also set rawsource to '') content = '\n'.join(self.content) node = nodes.inline(content, '', *highlight_using_coqdoc(content)) wrapper = nodes.container(content, node, classes=['coqdoc', 'literal-block']) return [wrapper]
def run(self): nodelist = [] if len (self.arguments) >= 1: nodelist.append (nodes.title ('', self.arguments[0])) literal = nodes.literal_block ('', '\n'.join (self.content)) literal['classes'].append ('example-source') nodelist.append (literal) if 'norender' not in self.options: container = nodes.container () container['classes'].append ('example-rendered') self.state.nested_parse (self.content, self.content_offset, container) nodelist.append (container) topic = nodes.topic ('', *nodelist) topic['classes'] += ['example'] topic['classes'] += self.options.get ('class', []) topic['float'] = self.options.get ('float', ('here', 'top', 'bottom', 'page')) Example.example_count += 1 target = lox_target (topic, 'example-%d' % Example.example_count) self.state_machine.document.note_implicit_target (target, target) return [topic]
def run(self): """ Parse a tab directive """ self.assert_has_content() args = self.content[0].strip().split() self.content.trim_start(2) lang = args[0] tab_name = ' '.join(args[1:]) if len(args) > 1 else LEXER_MAP[lang] for idx, line in enumerate(self.content.data): self.content.data[idx] = ' ' + line tab_args = { 'tab_id': base64.b64encode( tab_name.encode('utf-8')).decode('utf-8'), 'classes': ['code-tab'], } new_content = [ '.. tab:: {}'.format(json.dumps(tab_args)), ' {}'.format(tab_name), '', ' .. code-block:: {}'.format(lang), '', ] for idx, line in enumerate(new_content): self.content.data.insert(idx, line) self.content.items.insert(idx, (None, idx)) node = nodes.container() self.state.nested_parse(self.content, self.content_offset, node) return node.children
def run(self): """ Parse a tab directive """ self.assert_has_content() group_name = self.content[0] self.content.trim_start(2) for idx, line in enumerate(self.content.data): self.content.data[idx] = ' ' + line tab_args = { 'tab_id': base64.b64encode( group_name.encode('utf-8')).decode('utf-8') } new_content = [ '.. tab:: {}'.format(json.dumps(tab_args)), ' {}'.format(group_name), '', ] for idx, line in enumerate(new_content): self.content.data.insert(idx, line) self.content.items.insert(idx, (None, idx)) node = nodes.container() self.state.nested_parse(self.content, self.content_offset, node) return node.children
def run(self): data_type = self.arguments[0] condition = None if "required" in self.options: if self.options["required"] is True: condition = "required" elif self.options["required"] is False: condition = "optional" container = nodes.container() if condition is not None: container["classes"].extend([self.name, condition]) data_type_line = nodes.line(text=data_type) if self.is_primitive_type(data_type): data_type_line["classes"].extend([self.name, "datatype", "primitive"]) else: data_type_line["classes"].extend([self.name, "datatype"]) if condition is not None: condition_line = nodes.line(text=condition) condition_line["classes"].extend([self.name, "condition"]) container += [data_type_line, condition_line] else: container += [data_type_line] return [container]
def create_cross_table(self, app, docname, node, matrix, options): table = nodes.table() table["classes"].append("traceables-crosstable") tgroup = nodes.tgroup(cols=len(matrix.secondaries), colwidths="auto") table += tgroup # Add column specifications. tgroup += nodes.colspec(colwidth=1) for column in matrix.secondaries: tgroup += nodes.colspec(colwidth=1) # Add heading row. thead = nodes.thead() tgroup += thead row = nodes.row() thead += row entry = nodes.entry() row += entry for secondary in matrix.secondaries: entry = nodes.entry() row += entry container = nodes.container() entry += container inline = nodes.inline() container += inline paragraph = nodes.paragraph() inline += paragraph paragraph += secondary.make_reference_node(app.builder, docname) # Add table body. tbody = nodes.tbody() tgroup += tbody for primary in matrix.primaries: row = nodes.row() tbody += row entry = nodes.entry() row += entry paragraph = nodes.paragraph() entry += paragraph paragraph += primary.make_reference_node(app.builder, docname) for is_related in matrix.get_boolean_row(primary): entry = nodes.entry() row += entry if is_related: checkmark = traceable_checkmark() entry += checkmark checkmark += nodes.inline(u"\u2714", u"\u2714") else: continue container = traceable_matrix_crosstable() container += table container["traceables-matrix"] = matrix # backward = matrix.backward_relationship.capitalize() # forward = matrix.forward_relationship.capitalize() # container["relationships"] = (forward, backward) # container["boolean_matrix"] = 0#boolean_matrix # container["secondaries"] = matrix.secondaries return container
def run(self): self.assert_has_content() text = '\n'.join(self.content) node = nodes.container(text) width = self.options.get('width', 1) size = self.options.get('size', 'md') node['classes'] += ["col-%s-%d" % (size, width)] offset = self.options.get('offset', 0) if offset > 0: node['classes'] += ["col-%s-offset-%d" % (size, offset)] push = self.options.get('push', 0) if push > 0: node['classes'] += ["col-%s-push-%d" % (size, push)] pull = self.options.get('pull', 0) if pull > 0: node['classes'] += ["col-%s-pull-%d" % (size, pull)] node['classes'] += self.options.get('class', []) self.add_name(node) self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): self.assert_has_content() content = ''.join(self.content).strip() icon_classes = self.options.get('icon-classes', '') icon_classes = icon_classes.split(' ') container_classes = self.options.get('box-classes', '') container_classes = container_classes.split(' ') icons = span(classes=icon_classes) node = nodes.container(classes=container_classes) node.children.append(icons) parsed, _messages = self.state.inline_text( content, self.content_offset ) parsed_ = parsed[0] for p in parsed[1:]: parsed_.children.append(p) cp = compact_paragraph('', '', parsed_) node.children.append(cp) return [node]
def run(self): self.assert_has_content() # Build Container Node talentNode = nodes.container(classes=['talent-container']) if self.options.get('type'): talentNode['classes'].append(self.options['type']) else: talentNode['classes'].append('talent') # Generate Title Node titleNode = nodes.paragraph(text=self.options['name'], classes=['title']) # Generate Requirements & Tags reqs = '[' + format_dict(self.options['reqs']) + ']' if self.options.get('reqs') else '' tags = '(' + format_list(self.options['tags']) + ')' if self.options.get('tags') else '' specs = ' '.join([reqs, tags]) specsNode = nodes.paragraph(text=specs, classes=['specs']) contentNode = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, contentNode) talentNode += [titleNode, specsNode, contentNode] return [talentNode]
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): from hashlib import md5 # now we get the content text = '\n'.join(self.content) # get container element container_element = nodes.container() container_element['classes'] += ['media'] container_element["ids"] += [self.arguments[0].lower()] # get image element logo_url = '' if 'logo' in self.options: logo_url = self.options['logo'] if 'gravatar' in self.options: gravatar_email = self.options['gravatar'].strip().encode('utf-8') logo_url = 'https://www.gravatar.com/avatar/' + md5(gravatar_email).hexdigest() image_element = nodes.image(logo_url, alt=self.options['nick'], width="80px", **self.options) image_element['uri'] = logo_url image_element["classes"] += ['media-object'] image_container = nodes.container() image_container["classes"] += ['media-left'] image_container.append(image_element) title_text = self.options['nick'] heading_element = nodes.container(title_text) title_nodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.paragraph(title_text, '', *title_nodes) heading_element.append(title) heading_element['classes'] += ['media-heading'] # get body element body_container = nodes.container() body_element = nodes.container(text) self.state.nested_parse(self.content, self.content_offset, body_element) body_container.append(heading_element) body_container.append(body_element) body_container['classes'] += ['media-body'] container_element.append(image_container) container_element.append(body_container) return [container_element, ]
def apply(self): boxes=[] for target in self.document.traverse(boxright): target.insert(0, nodes.Text("[[boxright] ")) target.append(nodes.Text("]")) boxes.append(target) for box in boxes: box.replace_self( nodes.container('', *box.children) )
def run(self): self.assert_has_content() text = "\n".join(self.content) node = nodes.container(text) node["classes"].append("example-code") self.add_name(node) self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): self.assert_has_content() text = '\n'.join(self.content) node = nodes.container(text) node['classes'].append('fold-out') self.add_name(node) self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): self.assert_has_content() text = "\n".join(self.content) node = nodes.container(text, **self.options) node["classes"] = ["lead"] node["classes"] += self.options.get("class", []) self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): container = nodes.container(classes=['thumbtoc_container']) for entry in self.content: name, ref, img_url = entry.split('|') subcontainer = nodes.container(classes=['thumbtoc_item']) img_ref = nodes.reference(refuri=ref) image = nodes.image(uri=img_url, alt=name, refuri=ref, target=ref) img_ref += image textpar_node = nodes.paragraph(classes=["thumbtoc_text"]) link = nodes.reference('', name, refuri=ref) textpar_node.append(link) subcontainer += [img_ref, textpar_node] container += subcontainer return [container]
def run(self): self.assert_has_content() text = '\n'.join(self.content) node = nodes.container(text, **self.options) node['classes'] = ['lead'] node['classes'] += self.options.get('class', []) self.state.nested_parse(self.content, self.content_offset, node) return [node]
def _rest2node(self, rest, container=None): vl = ViewList(prepare_docstring(rest)) if container is None: node = nodes.container() else: node = container() nested_parse_with_titles(self.state, vl, node) return node
def run(self): """ Parse a tabs directive """ self.assert_has_content() env = self.state.document.settings.env node = nodes.container() node['classes'] = ['sphinx-tabs'] if 'next_tabs_id' not in env.temp_data: env.temp_data['next_tabs_id'] = 0 if 'tabs_stack' not in env.temp_data: env.temp_data['tabs_stack'] = [] tabs_id = env.temp_data['next_tabs_id'] tabs_key = 'tabs_%d' % tabs_id env.temp_data['next_tabs_id'] += 1 env.temp_data['tabs_stack'].append(tabs_id) env.temp_data[tabs_key] = {} env.temp_data[tabs_key]['tab_ids'] = [] env.temp_data[tabs_key]['tab_titles'] = [] env.temp_data[tabs_key]['is_first_tab'] = True self.state.nested_parse(self.content, self.content_offset, node) if env.app.builder.name in get_compatible_builders(env.app): tabs_node = nodes.container() tabs_node.tagname = 'div' classes = 'ui top attached tabular menu sphinx-menu' tabs_node['classes'] = classes.split(' ') tab_titles = env.temp_data[tabs_key]['tab_titles'] for idx, [data_tab, tab_name] in enumerate(tab_titles): tab = nodes.container() tab.tagname = 'a' tab['classes'] = ['item'] if idx > 0 else ['active', 'item'] tab['classes'].append(data_tab) tab += tab_name tabs_node += tab node.children.insert(0, tabs_node) env.temp_data['tabs_stack'].pop() return [node]
def run(self): classes = self.options.get('class', []) classes.insert(0, 'clear') self.options['class'] = classes set_classes(self.options) container = nodes.container(classes=classes) return [container]
def _build_option_description(self, fmt, action, custom_content): """ Build description of program option :param fmt: HelpFormatter to use :param action: source Action :param custom_content: custom content for option :return: node forming option description """ action.help = self._decorate_references(action.help) help = fmt._expand_help(action) result = nodes.container() self.state.nested_parse(StringList([help]), 0, result) if custom_content: if custom_content['action'] == 'append': result.extend(custom_content['content'].children) elif custom_content['action'] == 'prepend': result[0:0] = custom_content['content'].children elif custom_content['action'] == 'replace': result[:] = custom_content['content'] return result
def container_wrapper(directive, literal_node, caption): # type: (SphinxDirective, nodes.Node, str) -> nodes.container container_node = nodes.container("", literal_block=True, classes=["literal-block-wrapper"]) parsed = nodes.Element() directive.state.nested_parse(StringList([caption], source=""), directive.content_offset, parsed) if isinstance(parsed[0], nodes.system_message): msg = "Invalid caption: %s" % parsed[0].astext() raise ValueError(msg) elif isinstance(parsed[0], nodes.Element): caption_node = nodes.caption(parsed[0].rawsource, "", *parsed[0].children) caption_node.source = literal_node.source caption_node.line = literal_node.line container_node += caption_node container_node += literal_node return container_node else: raise RuntimeError # never reached
def run(self): details = {} if 'depth' in self.options: details['toc_depth'] = self.options['depth'] container = nodes.container() if self.arguments: container += nodes.inline('', self.arguments[0]) self.state.nested_parse(self.content, self.content_offset, container) container['classes'] += self.options.get('class', []) if container.astext(): details['content'] = container else: details['content'] = None # flag: supress toc entry pending = nodes.pending(parts.TocEntryTransform, details) self.state_machine.document.note_pending(pending) return [pending]
def run(self, source): set_classes(self.options) # If this is the first real node inside a graph figure, put the SVG # directly inside parent = self.state.parent if _is_graph_figure(parent): svg = dot2svg.dot2svg( source, attribs=' class="{}"'.format( ' '.join(['m-graph'] + self.options.get('classes', [])))) node = nodes.raw('', svg, format='html') return [node] # Otherwise wrap it in a <div class="m-graph"> svg = dot2svg.dot2svg(source) container = nodes.container(**self.options) container['classes'] = ['m-graph'] + container['classes'] node = nodes.raw('', svg, format='html') container.append(node) return [container]
def container_wrapper(directive: SphinxDirective, literal_node: Node, caption: str) -> nodes.container: # NOQA container_node = nodes.container('', literal_block=True, classes=['literal-block-wrapper']) parsed = nodes.Element() directive.state.nested_parse(StringList([caption], source=''), directive.content_offset, parsed) if isinstance(parsed[0], nodes.system_message): msg = __('Invalid caption: %s' % parsed[0].astext()) raise ValueError(msg) elif isinstance(parsed[0], nodes.Element): caption_node = nodes.caption(parsed[0].rawsource, '', *parsed[0].children) caption_node.source = literal_node.source caption_node.line = literal_node.line container_node += caption_node container_node += literal_node return container_node else: raise RuntimeError # never reached
def run(self): # default classes classes = { "container_classes": ["mb-3"], "title_classes": [], "body_classes": [], } # add classes from options for element in ["container", "title", "body"]: if element not in self.options: continue value = self.options.get(element).strip() if value.startswith("+"): classes.setdefault(element + "_classes", []).extend(value[1:].split()) else: classes[element + "_classes"] = value.split() # add animation classes if ("animate" in self.options and self.options["animate"] not in classes["container_classes"]): classes["container_classes"].append(self.options["animate"]) container = nodes.container("", marker_color=self.options.get( "marker-color", "currentColor"), opened="open" in self.options, type="dropdown", has_title=len(self.arguments) > 0, **classes) if self.arguments: textnodes, messages = self.state.inline_text( self.arguments[0], self.lineno) container += nodes.paragraph(self.arguments[0], "", *textnodes) container += messages self.state.nested_parse(self.content, self.content_offset, container) self.add_name(container) return [container]
def run(self): link = self.arguments[0] embed_type = "Card" if "/c/" in link else "Board" container = nodes.container() html = f""" <blockquote class="trello-{embed_type.lower()}-compact"> <a href="{link}">Trello {embed_type}</a> </blockquote>""" html_node = nodes.raw(text=html, format="html") only_pdf = addnodes.only(expr="latex") # We need to provide a node for nested parsing. And another node for populating the parsed node. only_pdf_paragraph = nodes.inline() self.state.nested_parse( nodes.inline(text=f"`Trello {embed_type} <{link}>`_"), 0, only_pdf_paragraph) only_pdf += only_pdf_paragraph container += html_node container += only_pdf return container.children
def build_ddmenu_from_list(self, node): if len(node) != 1 or not isinstance(node[0], (nodes.bullet_list, nodes.enumerated_list)): self.severe("Error while processing ddlist directive") ddnode = ddlist() for id, item in enumerate(node[0]): new_item = ddlistitem() title = item.children.pop(0) title_ref = nodes.reference('', '', internal=False, refuri='#node%d' % id, classes=['dropdown-list-item-url', 'dropdown-close'], ids=['node%d' % id]) title_ref += title content = nodes.container('', classes=['dropdown-list-item-content']) content += item.children new_item += [title_ref, content] # print(type(title_ref.parent), title_ref.parent) ddnode += new_item return ddnode
def _build_option(self, parser, action, custom_content): """ Build single program option :param parser: pre-configured ArgumentParser instance :param action: source Action :param custom_content: custom content for options :return: node forming program option """ def get_id(progname, name): id = 'cmdoption-{}'.format(progname) if not name.startswith('-'): id += '-arg-' id += name return id fmt = parser._get_formatter() result = nodes.container() signature = addnodes.desc_signature(ids=[], allnames=[], first=False) self.state.document.note_explicit_target(signature) description = self._build_option_description(fmt, action, custom_content) content = addnodes.desc_content('', description) result.append(addnodes.desc('', signature, content, objtype='option')) progname = self._get_program_name(parser) synopses = [] for option in self._get_option_group(fmt, action): signature['ids'].append(get_id(progname, option['name'])) signature['allnames'].append(option['name']) signature.append(addnodes.desc_name(text=option['name'])) if 'args' in option: signature.append(addnodes.desc_addname(text=option['args'])) signature.append(addnodes.desc_addname(text=', ')) synopses.append(option['synopsis']) signature.pop() index = self._build_option_index(progname, signature['ids'], signature['allnames'], synopses) result.append(index) return result
def run(self): # gives you access to the options of the directive options = self.options cid = nodes.make_id("card-{}".format(options['title'])) classes = ['mx-card'] if options.get('is_head', 'False').lower() == 'true': classes.append('head-card') container = nodes.container(ids=[cid], classes=classes) container += nodes.inline('', options['title'], classes=['mx-card-title']) link = options.get('link') if link: container += nodes.inline('', link, classes=['mx-card-link']) para = nodes.paragraph(classes=['mx-card-text']) self.state.nested_parse(self.content, self.content_offset, para) container += para # we return the result return [container]
def _build_program_synopsis(self, parser): """ Build program synopsis :param parser: pre-configured ArgumentParser instance :return: node forming program synopsis """ fmt = parser._get_formatter() groups = [] for action in parser._get_optional_actions() + parser._get_positional_actions(): if action.help is SUPPRESS: continue in_group = False for group in parser._mutually_exclusive_groups: if action in group._group_actions: in_group = True if action == group._group_actions[0]: groups.append(dict(actions=group._group_actions, required=group.required)) if not in_group: groups.append(dict(actions=[action], required=action.required)) synopsis = ['\\ :program:`{}`\\ '.format(parser.prog)] for group in groups: usages = [] for action in group['actions']: option = self._get_option_group(fmt, action)[0] if option.get('optional') and len(group['actions']) == 1: group['required'] = False usage = '\\ :option:`{}`\\ '.format(option['synopsis']) usages.append(usage) if not group['required']: synopsis.append('[{}]'.format(' | '.join(usages))) elif len(group['actions']) > 1: synopsis.append('({})'.format(' | '.join(usages))) else: synopsis.append('{}'.format(usages[0])) synopsis = self._format_synopsis(synopsis) paragraph = nodes.paragraph() self.state.nested_parse(StringList(synopsis), 0, paragraph) return nodes.container('', paragraph)
def run(self): block_type = self.name container = nodes.container() self.state.nested_parse(self.content, self.content_offset, container) # Calling a method by string. block_node = getattr(nodes, block_type)() for node in container: node_copy = node if node_copy.asdom().tagName == "comment": continue if node_copy.asdom().tagName == "only": if not self.env.app.tags.eval_condition( node_copy.attributes["expr"]): continue for inner_node in node_copy: if inner_node.asdom().tagName == block_type: node_copy = inner_node break # Copy elements over. block_node += node_copy[:] return [block_node]
def glyph_role(name, rawtext, text, lineno, inliner, options={}, content=[]): """ This function defines a glyph inline role that show a glyph icon from the twitter bootstrap framework *Usage:* :glyph:`<glyph_name>` *Example:* Love this music :glyph:`music` :) Can be subclassed to include a target *Example:* .. role:: story_time_glyph(glyph) :target: http://www.youtube.com/watch?v=5g8ykQLYnX0 :class: small text-info Love this music :story_time_glyph:`music` :) """ target = options.get('target', None) glyph_name = 'glyphicon-{}'.format(text) if target: target = utils.unescape(target) new_element = nodes.reference(rawtext, ' ', refuri=target) else: new_element = nodes.container() classes = options.setdefault('class', []) classes += ['glyphicon', glyph_name] for custom_class in classes: new_element.set_class(custom_class) return [new_element], []
def get_image_element(self): # Get the image url image_url = self.arguments[0] image_reference = rst.directives.uri(image_url) self.options['uri'] = image_reference reference_node = None messages = [] if 'target' in self.options: block = rst.states.escape2null( self.options['target']).splitlines() block = [line for line in block] target_type, data = self.state.parse_target( block, self.block_text, self.lineno) if target_type == 'refuri': container_node = nodes.reference(refuri=data) elif target_type == 'refname': container_node = nodes.reference( refname=fully_normalize_name(data), name=whitespace_normalize_name(data)) container_node.indirect_reference_name = data self.state.document.note_refname(container_node) else: # malformed target messages.append(data) # data is a system message del self.options['target'] else: container_node = nodes.container() # get image position position = self.options.get('position', 'left') position_class = 'pull-{}'.format(position) container_node.set_class(position_class) image_node = nodes.image(self.block_text, **self.options) image_node['classes'] += ['media-object'] container_node.append(image_node) return container_node
def nodes_for_class(self, name, item, children): """ Determine nodes for a class @param name: name of the class @param item: The class itself @param children: A list of (name, item, children) for all logicallynested classes """ container = nodes.container(classes=["nose_kls"]) para = nodes.paragraph(classes=["kls_title"]) name = testName(item) para += nodes.Text(name) container.append(para) subnodes = self.nodes_for_module(item) if not subnodes and not children: # Probably not a test class return [] container.extend(subnodes) for child in children: container.extend(self.nodes_for_class(*child)) return [container]
def include_source(self, item): """Return nodes representing the original source code of the item""" func = item if hasattr(item, 'im_func'): func = item.im_func try: func.func_code except: from pdb import set_trace set_trace() code = func.func_code filename = code.co_filename first_line = code.co_firstlineno num_lines = inspect.getsource(item).strip().count('\n') last_line = first_line + num_lines info = nodes.container(classes=["hidden_info"]) info.extend( self.literalinclude('/%s' % filename, first_line, last_line)) return info
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 run_mixin(self, inner): """Insert correct nodes for code tabs.""" # tab title is the second arg title = self.arguments.pop() # tab_ids start from 1, so increment at start self.env.tab_group_tab_id += 1 # build the tab_id group_name = self.env.tab_group_name tab_id_int = self.env.tab_group_tab_id tab_id = "%s_%s" % (group_name, tab_id_int) node = nodes.container() node["classes"].append("superfences-content") self.add_name(node) # include the node for the actual code node += inner # create the input node for the tab inp = tab_node(ids=[tab_id]) inp.tagname = "input" inp["attrs"] = {"type": "radio", "name": group_name} if self.env.tab_group_tab_id == 1: inp["attrs"]["checked"] = "checked" # create the label lab = tab_node() lab.tagname = "label" lab["attrs"] = {"for": tab_id} # add text to the label txt = nodes.Text(title) lab += txt return [inp, lab, node]
def _build_markup(self, commits): parent = nodes.container() list_node = nodes.bullet_list() for commit in commits: # Construct a backlink to BitBucket url = f"https://github.com/pencil-code/pencil-code/commit/{commit.hexsha}" ref = nodes.emphasis( "", "", nodes.reference("", commit.hexsha[:self.default_sha_length], refuri=url), ) # Other commit details date_str = datetime.fromtimestamp(commit.authored_date) item = nodes.list_item() par = nodes.paragraph() par += [nodes.inline(text=commit.message)] author = six.text_type(commit.author) par += [ nodes.inline(text=" by ", classes=["gray"]), nodes.emphasis(text=author, classes=["gray"]), ] par += [ nodes.inline(text=" at ", classes=["gray"]), nodes.emphasis(text=str(date_str), classes=["gray"]), ] par += nodes.inline(text=", ") par += ref item.append(par) list_node.append(item) parent.update_basic_atts({"classes": ["collapsable"]}) parent.append(list_node) return [parent]
def run(self): """ Parse a tab directive """ self.assert_has_content() args = self.content[0].strip().split() self.content.trim_start(2) lang = args[0] tab_name = ' '.join(args[1:]) if len(args) > 1 else LEXER_MAP[lang] for idx, line in enumerate(self.content.data): self.content.data[idx] = ' ' + line tab_args = { 'tab_id': base64.b64encode(tab_name.encode('utf-8')).decode('utf-8'), 'classes': ['code-tab'], } new_content = [ '.. tab:: {}'.format(json.dumps(tab_args)), ' {}'.format(tab_name), '', ' .. code-block:: {}'.format(lang), ] if 'linenos' in self.options: new_content.append(' :linenos:') new_content.append('') for idx, line in enumerate(new_content): self.content.data.insert(idx, line) self.content.items.insert(idx, (None, idx)) node = nodes.container() self.state.nested_parse(self.content, self.content_offset, node) return node.children
def run(self): """Parse a compare-tabs directive.""" self.assert_has_content() group_name = self.content[0] tabs = [] for idx, line in enumerate(self.content.data): tabs.append(line.split()) new_content = ['.. tabs::'] for tabsplit in tabs: language = tabsplit[0] name = tabsplit[1] filepath = tabsplit[2] lines_raw = tabsplit[3:] lines = str.join( ',', str.join(' ', lines_raw).replace(',', ' ').split()) new_content.extend([ ' .. tab:: {}'.format(name), ' ', ' .. literalinclude:: {}'.format(filepath), ' :dedent: {}'.format(self.DEDENT[language]), ' :language: {}'.format(language), ' :lines: {}'.format(lines), ' ', ]) for idx, line in enumerate(new_content): self.content.data.insert(idx, line) self.content.items.insert(idx, (None, idx)) node = nodes.container() self.state.nested_parse(self.content[:-1 * len(tabs)], self.content_offset, node) return node.children
def container(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): text = '\n'.join(content) if not text: error = state_machine.reporter.error( 'The "%s" directive is empty; content required.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] try: if arguments: classes = directives.class_option(arguments[0]) else: classes = [] except ValueError: 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] node = nodes.container(text) node['classes'].extend(classes) state.nested_parse(content, content_offset, node) return [node]
def insert_all_toctrees(tree, env, traversed): tree = tree.deepcopy() for toctreenode in tree.traverse(addnodes.toctree): nodeid = 'docx_expanded_toctree%d' % id(toctreenode) newnodes = nodes.container(ids=[nodeid]) toctreenode['docx_expanded_toctree_refid'] = nodeid includefiles = toctreenode['includefiles'] for includefile in includefiles: if includefile in traversed: continue try: traversed.append(includefile) subtree = insert_all_toctrees(env.get_doctree(includefile), env, traversed) except Exception: continue start_of_file = addnodes.start_of_file(docname=includefile) start_of_file.children = subtree.children newnodes.append(start_of_file) parent = toctreenode.parent index = parent.index(toctreenode) parent.insert(index + 1, newnodes) return tree
def container_wrapper(directive: SphinxDirective, literal_node: Node, caption: str) -> nodes.container: """We need the container to have class highlight.""" container_node = nodes.container("", literal_block=True, language=literal_node["language"], classes=["highlight"]) parsed = nodes.Element() directive.state.nested_parse(StringList([caption], source=""), directive.content_offset, parsed) if isinstance(parsed[0], nodes.system_message): msg = __("Invalid caption: %s" % parsed[0].astext()) raise ValueError(msg) elif isinstance(parsed[0], nodes.Element): caption_node = nodes.caption(parsed[0].rawsource, "", *parsed[0].children) caption_node.source = literal_node.source caption_node.line = literal_node.line container_node += caption_node container_node += literal_node return container_node else: raise RuntimeError # never reached
def run(self): set_classes(self.options) self.assert_has_content() # join lines, separate blocks content = '\n'.join(self.content).split('\n\n') _nodes = [] for block in content: if not block: continue out = latex2svg.latex2svg("$$" + block + "$$", params=latex2svg_params) container = nodes.container(**self.options) container['classes'] += ['m-math'] node = nodes.raw(self.block_text, _patch(block, out, ''), format='html') node.line = self.content_offset + 1 self.add_name(node) container.append(node) _nodes.append(container) return _nodes
def run(self): # Create and error-check the range. try: _range = range(*[int(arg) for arg in self.arguments]) except Exception as e: raise self.error("Invalid arguments to range: {}".format(e)) # Run the for loop over all this directive's content. Docutils expects a StringList, so use that. loop_content = StringList() for loop_index in _range: # Loop over each line of the content, only replacing lines in the content of this directive. for source, offset, value in self.content.xitems(): loop_content.append( value.format(loop_index, *self.arguments), source, offset ) # Add an additional newline between loop iterations. loop_content.append("\n", "for-loop", 0) # Parse the resulting content and return it. node = nodes.container() self.state.nested_parse(loop_content, self.content_offset, node) return [node]
def add_navigation(self, previous, next): navigation = nodes.container() navigation['classes'] += ['navigation'] paragraph = nodes.paragraph() navigation += paragraph if previous: inline = nodes.inline() inline['classes'] += ['previous'] inline += nodes.Text('Previous: ') inline += previous.create_short_reference() paragraph += inline if next: inline = nodes.inline() inline['classes'] += ['next'] inline += nodes.Text('Next: ') inline += next.create_short_reference() paragraph += inline breadcrumbs = self.create_short_breadcrumbs() if breadcrumbs: inline = nodes.inline() inline['classes'] += ['breadcrumbs'] for breadcrumb in breadcrumbs: inline += breadcrumb inline += nodes.Text(u' \u00bb ') inline += nodes.Text(shorten(self.title)) paragraph += inline header = navigation.deepcopy() header['classes'] += ['navigation-header'] self.document.insert(0, header) footer = navigation.deepcopy() footer['classes'] += ['navigation-footer'] self.document += footer
def photogroup_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): # figure out what this is doing. references = map(lambda x: x.strip(), content) if not references: return [] pnode = nodes.container(classes=['photogroup']) for reference in references: if reference.find(' ') != -1: error = state_machine.reporter.error( 'Photogroup URI contains whitespace.', '', nodes.literal_block(block_text, block_text), line=lineno) return [error] options['uri'] = reference options['photo'] = '1' image_node = nodes.image(block_text, **options) pnode.append(image_node) return [pnode]
def run(self) -> List[nodes.Node]: self.assert_has_content() text = "\n".join(self.content) admonition_node = self.node_class(text, **self.options) # type: ignore admonition_node["classes"] += self.options.get("class", []) title_text = self.get_title() 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 self.add_name(admonition_node) body = nodes.container(text) body["classes"] += ["admonition-body"] self.state.nested_parse(self.content, self.content_offset, body) admonition_node += body admonition_node += messages return [admonition_node]
def run(self): try: code = inspect.cleandoc( """ def usermethod(): {} """ ).format("\n ".join(self.content)) exec(code) result = locals()["usermethod"]() if result is None: raise Exception( "Return value needed! The body of your `.. exec::` is used as a " "function call that must return a value." ) para = nodes.container() # tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) lines = statemachine.StringList(result.split("\n")) self.state.nested_parse(lines, self.content_offset, para) return [para] except Exception as e: docname = self.state.document.settings.env.docname return [ nodes.error( None, nodes.paragraph( text="Unable to execute python code at {}:{} ... {}".format( docname, self.lineno, datetime.datetime.now() ) ), nodes.paragraph(text=str(e)), nodes.literal_block(text=str(code)), ) ]