def run(self): """ Restructured text extension for including inline JSAV content on module pages """ self.options['exer_name'] = self.arguments[0] self.options['type'] = self.arguments[1] self.options['odsa_path'] = os.path.relpath(conf.odsa_path,conf.ebook_path) # Set defaults for any values that aren't configured if 'required' not in self.options: self.options['required'] = False if 'points' not in self.options: self.options['points'] = 0 if 'threshold' not in self.options: self.options['threshold'] = 1.0 if 'long_name' not in self.options: self.options['long_name'] = self.options['exer_name'] if 'align' not in self.options: self.options['align'] = 'center' if 'output' in self.options and self.options['output'] == "show": self.options['output_code'] = '<p class="jsavoutput jsavline"></p>' else: self.options['output_code'] = '' if self.options['type'] == "dgm": avdgm_node = av_dgm() anchor_node = av_anchor() avdgm_node['exer_name'] = self.options['exer_name'] anchor_node['ids'].append(self.options['exer_name']) avdgm_node += anchor_node if self.content: node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) caption['align']= self.options['align'] avdgm_node += caption return [avdgm_node] elif self.options['type'] == "ss" and self.content: avss_node = av_ss() avss_node['res'] = SLIDESHOW % self.options node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) caption['align']= self.options['align'] avss_node += caption return [avss_node] else: res = SLIDESHOW % self.options return [nodes.raw('', res, format='html')]
def run(self): if self.name in self.state.document.settings.dir_ignore: return [] children = [] if self.name not in self.state.document.settings.dir_notitle: children.append(nodes.strong(self.name, u"%s: " % self.name)) # keep the arguments, drop the options for a in self.arguments: if a.startswith(':') and a.endswith(':'): break children.append(nodes.emphasis(a, u"%s " % a)) if self.name in self.state.document.settings.dir_nested: if self.content: container = nodes.Element() self.state.nested_parse(self.content, self.content_offset, container) children.extend(container.children) else: content = u'\n'.join(self.content) children.append(nodes.literal_block(content, content)) node = any_directive(self.block_text, '', *children, dir_name=self.name) return [node]
def replace(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): if not isinstance(state, states.SubstitutionDef): error = state_machine.reporter.error( 'Invalid context: the "%s" directive can only be used within a ' 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] text = '\n'.join(content) element = nodes.Element(text) if text: state.nested_parse(content, content_offset, element) if len(element) != 1 or not isinstance(element[0], nodes.paragraph): messages = [] for node in element: if isinstance(node, nodes.system_message): node['backrefs'] = [] messages.append(node) error = state_machine.reporter.error( 'Error in "%s" directive: may contain a single paragraph ' 'only.' % (name), line=lineno) messages.append(error) return messages else: return element[0].children else: error = state_machine.reporter.error( 'The "%s" directive is empty; content required.' % (name), line=lineno) return [error]
def run(self): # collect everything in a list of strings content = ['.. tabs::', ''] for file in self.content: # detect file extension _, ext = os.path.splitext(file) if ext in self.exts: title = self.exts[ext]['title'] lang = self.exts[ext]['lang'] else: title = ext lang = ext # generate tabs content.append(f' .. tab:: {title}') content.append(f'') content.append(f' .. literalinclude:: {file}') content.append(f' :language: {lang}') content.append(f' :linenos:') # parse the string list node = nodes.Element() self.state.nested_parse(StringList(content), 0, node) return node.children
def run(self): if not self.content: error = self.state_machine.reporter.error( 'The "%s" directive is empty; content required.' % self.name, nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error] title, messages = self.make_title() node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) try: num_cols, col_widths = self.check_list_content(node) table_data = [[item.children for item in row_list[0]] for row_list in node[0]] header_rows = self.options.get('header-rows', 0) stub_columns = self.options.get('stub-columns', 0) self.check_table_dimensions(table_data, header_rows, stub_columns) except SystemMessagePropagation as detail: return [detail.args[0]] table_node = self.build_table_from_list(table_data, col_widths, header_rows, stub_columns) if 'align' in self.options: table_node['align'] = self.options.get('align') table_node['classes'] += self.options.get('class', []) self.set_table_width(table_node) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def run(self): required_arguments = 0 optional_arguments = 2 align = self.options.pop('align', None) capalign = self.options.pop('capalign', None) odsatable_node = odsatable() odsatable_node['align'] = align odsatable_node['capalign'] = capalign if align: odsatable_node['align'] = align if self.content: node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) caption['align'] = capalign odsatable_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): error = self.state_machine.reporter.error( 'Table caption must be a paragraph or empty comment.', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [odsatable_node, error] if len(node) > 1: odsatable_node += nodes.legend('', *node[1:]) return [odsatable_node]
def run(self): env = self.state.document.settings.env node = nodes.Element() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) entries = [] for i, child in enumerate(node): if isinstance(child, nodes.literal_block): # add a title (the language name) before each block #targetid = "configuration-block-%d" % env.new_serialno('configuration-block') #targetnode = nodes.target('', '', ids=[targetid]) #targetnode.append(child) innernode = nodes.emphasis(self.formats[child['language']], self.formats[child['language']]) para = nodes.paragraph() para += [innernode, child] entry = nodes.list_item('') entry.append(para) entries.append(entry) resultnode = configurationblock() resultnode.append(nodes.bullet_list('', *entries)) return [resultnode]
def run(self): if not isinstance(self.state, states.SubstitutionDef): raise self.error( 'Invalid context: the "%s" directive can only be used within ' 'a substitution definition.' % self.name) self.assert_has_content() text = '\n'.join(self.content) element = nodes.Element(text) self.state.nested_parse(self.content, self.content_offset, element) # element might contain [paragraph] + system_message(s) node = None messages = [] for elem in element: if not node and isinstance(elem, nodes.paragraph): node = elem elif isinstance(elem, nodes.system_message): elem['backrefs'] = [] messages.append(elem) else: return [ self.state_machine.reporter.error( 'Error in "%s" directive: may contain a single paragraph ' 'only.' % (self.name), line=self.lineno) ] if node: return messages + node.children return messages
def class_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ Set a "class" attribute on the directive content or the next element. When applied to the next element, a "pending" element is inserted, and a transform does the work later. """ try: class_value = directives.class_option(arguments[0]) 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_list = [] if content: container = nodes.Element() state.nested_parse(content, content_offset, container) for node in container: node['classes'].extend(class_value) node_list.extend(container.children) else: pending = nodes.pending(misc.ClassAttribute, { 'class': class_value, 'directive': name }, block_text) state_machine.document.note_pending(pending) node_list.append(pending) return node_list
def run(self): ans_class = 'answer' # ANSWER MODE if 'ANS' in os.environ or self.options.get('force', None): set_classes(self.options) self.assert_has_content() container = nodes.Element() self.add_name(container) self.state.nested_parse(self.content, self.content_offset, container) childs = [] + container.children for node in childs: try: node['classes'].append(ans_class) except TypeError: pass childs.extend(node.children) score = nodes.line(text="Max points: %s" % self.options.get('points', 1)) return [nodes.line(), score, nodes.line()] + container.children # EMPTY ANSWER ns = [ nodes.line(), nodes.line(text=self.options.get('text', 'Solution:')) ] ns.extend(nodes.paragraph() for x in xrange(int(self.options.get('height', 20)))) return ns
def run(self): node = nodes.Element() node.document = self.state.document jinja_context_name = self.arguments[0] template_filename = self.options.get("file") cxt = self.app.config.jinja_contexts[jinja_context_name] cxt["options"] = {"header_char": self.options.get("header_char")} if template_filename: reference_uri = directives.uri(template_filename) template_path = urllib.url2pathname(reference_uri) encoded_path = template_path.encode(sys.getfilesystemencoding()) imagerealpath = os.path.abspath(encoded_path) with open(imagerealpath) as f: tpl = Template(f.read()) else: tpl = Template("\n".join(self.content)) new_content = tpl.render(**cxt) # transform the text content into a string_list that the nested_parse # can use: new_content = StringList(new_content.split("\n")) self.state.nested_parse(new_content, self.content_offset, node, match_titles=1) return node.children
def run(self): self.assert_has_content() node = nodes.Element() # make anonymous container for text parsing self.state.nested_parse(self.content, self.content_offset, node) ddnode = self.build_ddmenu_from_list(node) self.add_name(ddnode) return [ddnode] + []
def run(self): # Load the template template_filename = self.options.get('file') if template_filename: with open(template_filename) as fp: template = fp.read() else: template = '\n'.join(self.content) # Render the template context = self.app.config.jinja_context keys = self.options.get('key', []) for key in keys: context = context[key] context['_jinja_key'] = keys template = Template(template) rst = template.render(**context, header_char=self.options.get('header_char', '=')) if 'debug' in self.options: print(rst) # Parse the generated rst node = nodes.Element() rst = StringList(rst.splitlines()) sphinx.util.nested_parse_with_titles(self.state, rst, node) return node.children
def run(self): try: data = retrieve_glue_data(self.document, self.arguments[0]) except RetrievalError as exc: return [glue_warning(str(exc), self.document, self.line)] render: Dict[str, Any] = {} for key in ("alt", "height", "width", "scale", "class"): if key in self.options: render.setdefault("image", {})[key.replace("classes", "class")] = self.options[key] paste_nodes = render_variable_output(data, self.document, self.line, self.source, render=render) # note: most of this is copied directly from sphinx.Figure # create figure node figure_node = nodes.figure("", *paste_nodes) self.set_source_info(figure_node) # add attributes figwidth = self.options.pop("figwidth", None) figclasses = self.options.pop("figclass", None) align = self.options.pop("align", None) if figwidth is not None: figure_node["width"] = figwidth if figclasses: figure_node["classes"] += figclasses if align: figure_node["align"] = align # add target self.add_name(figure_node) # create the caption and legend if self.content: node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, "", *first_node.children) caption.source = first_node.source caption.line = first_node.line figure_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): error = glue_warning( "Figure caption must be a paragraph or empty comment.", self.document, self.lineno, ) return [figure_node, error] if len(node) > 1: figure_node += nodes.legend("", *node[1:]) return [figure_node]
def generateTrackNodes(self): self.track_nodes = [] if 'track' in self.options: track_node = self.parse_track(self.options['track']) track_node.default = True self.track_nodes.append(track_node) # parse directive body ## create anonymous container for parsing node = nodes.Element() ## take indented block, parse it and put the output into node self.state.nested_parse(self.content, self.content_offset, node) ## If appropriate input has been given node should now be a list-like ## object of the following form: ## [Element[bullet_list[list_item[paragraph[Text]]]]] # or [Element[bullet_list[list_item[paragraph[reference[Text]][Text]]]]] # if filename is a url if self.check_for_list(node): for list_item in node[0]: text = '' for n in list_item[0]: if isinstance(n, nodes.Text): text += n elif isinstance(n, nodes.reference): text += n[0] self.track_nodes.append(self.parse_track(text)) if len(self.track_nodes) > 0: self.add_name(self.track_nodes) else: del self.track_nodes
def run(self): figclasses = self.options.pop('figclass', None) (image_node, ) = Image.run(self) if isinstance(image_node, nodes.system_message): return [image_node] figure_node = nodes.figure('', image_node) if figclasses: figure_node['classes'] += figclasses figure_node['classes'] += ['m-figure'] if self.content: node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) caption.source = first_node.source caption.line = first_node.line figure_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): error = self.state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [figure_node, error] if len(node) > 1: figure_node += nodes.legend('', *node[1:]) return [figure_node]
def run(self): self.assert_has_content() if len(self.arguments) > 0: try: meta_format = ' '.join(self.arguments[0].lower().split()) except ValueError: raise self.error( 'Invalid meta attribute value for "%s" directive: "%s".' % (self.name, self.arguments[0])) else: meta_format = 'html' node = nodes.Element() new_line_offset, blank_finish = self.state.nested_list_parse( self.content, self.content_offset, node, initial_state='MetaBody', blank_finish=True, state_machine_kwargs=self.SMkwargs, extra_settings={'meta_format': meta_format}) if (new_line_offset - self.content_offset) != len(self.content): # incomplete parse of block? error = self.state_machine.reporter.error( 'Invalid meta directive.', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) node += error return node.children
def meta(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): node = nodes.Element() if content: new_line_offset, blank_finish = state.nested_list_parse( content, content_offset, node, initial_state='MetaBody', blank_finish=1, state_machine_kwargs=metaSMkwargs) if (new_line_offset - content_offset) != len(content): # incomplete parse of block? error = state_machine.reporter.error('Invalid meta directive.', nodes.literal_block( block_text, block_text), line=lineno) node += error else: error = state_machine.reporter.error('Empty meta directive.', nodes.literal_block( block_text, block_text), line=lineno) node += error return node.children
def run(self): self.assert_has_content() return [self.libconradmeta(self.content)] node = nodes.Element() node += nodes.raw(self.content) return [nodes.docinfo(self.content)]
def run(self): if not self.content: error = self.state_machine.reporter.error( 'The "%s" directive is empty; content required.' % self.name, nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error] title, messages = self.make_title() node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) num_cols = self.check_list_content(node) # Hardcode this: col_widths = [20, 15, 65] table_data = [[item.children for item in row_list[0]] for row_list in node[0]] header_rows = self.options.get('header-rows', 1) stub_columns = self.options.get('stub-columns', 0) self.check_table_dimensions(table_data, header_rows - 1, stub_columns) table_node = self.build_table_from_list(table_data, col_widths, header_rows, stub_columns) table_node['classes'] += self.options.get('class', ['paramstable']) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def list_table(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ Implement tables whose data is encoded as a uniform two-level bullet list. For further ideas, see http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables """ if not content: error = state_machine.reporter.error( 'The "%s" directive is empty; content required.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] title, messages = make_title(arguments, state, lineno) node = nodes.Element() # anonymous container for parsing state.nested_parse(content, content_offset, node) try: num_cols, col_widths = check_list_content(node, name, options, content, lineno, block_text, state_machine) table_data = [[item.children for item in row_list[0]] for row_list in node[0]] header_rows = options.get('header-rows', 0) # default 0 stub_columns = options.get('stub-columns', 0) # default 0 check_table_dimensions(table_data, header_rows, stub_columns, name, lineno, block_text, state_machine) except SystemMessagePropagation, detail: return [detail.args[0]]
def run(self): ncolumns = self.options.get("columns", 2) node = nodes.Element() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) if len(node.children) != 1 or not isinstance(node.children[0], nodes.bullet_list): return [ self.state.document.reporter.warning( ".. hlist content is not a list", line=self.lineno) ] fulllist = node.children[0] # create a hlist node where the items are distributed npercol, nmore = divmod(len(fulllist), ncolumns) index = 0 table = nodes.table() tg = nodes.tgroup() table += tg row = nodes.row() tbody = nodes.tbody() for column in range(ncolumns): endindex = index + (column < nmore and (npercol + 1) or npercol) colspec = nodes.colspec() colspec.attributes["stub"] = 0 colspec.attributes["colwidth"] = 100.0 / ncolumns col = nodes.entry() col += nodes.bullet_list() col[0] += fulllist.children[index:endindex] index = endindex tg += colspec row += col tbody += row tg += tbody table["classes"].append("hlist") return [table]
def run(self): label = self.options.get('label', None) spec = self.options.get('spec', None) caption = self.options.get('caption', None) alt = self.options.get('alt', None) nofig = 'nofig' in self.options figtable_node = figtable('', ids=[label] if label is not None else []) figtable_node['nofig'] = nofig if spec is not None: table_spec_node = addnodes.tabular_col_spec() table_spec_node['spec'] = spec figtable_node.append(table_spec_node) node = nodes.Element() self.state.nested_parse(self.content, self.content_offset, node) tablenode = node[0] if alt is not None: tablenode['alt'] = alt figtable_node.append(tablenode) if caption is not None: caption_node = nodes.caption('', '', nodes.Text(caption)) figtable_node.append(caption_node) if label is not None: targetnode = nodes.target('', '', ids=[label]) figtable_node.append(targetnode) return [figtable_node]
def run(self): if not isinstance(self.state, states.SubstitutionDef): raise self.error( 'Invalid context: the "%s" directive can only be used within ' "a substitution definition." % self.name ) substitution_definition = self.state_machine.node if "trim" in self.options: substitution_definition.attributes["ltrim"] = 1 substitution_definition.attributes["rtrim"] = 1 if "ltrim" in self.options: substitution_definition.attributes["ltrim"] = 1 if "rtrim" in self.options: substitution_definition.attributes["rtrim"] = 1 codes = self.comment_pattern.split(self.arguments[0])[0].split() element = nodes.Element() for code in codes: try: decoded = directives.unicode_code(code) except ValueError as error: raise self.error( u"Invalid character code: %s\n%s" % (code, ErrorString(error)) ) element += nodes.Text(decoded) return element.children
def run(self): task = getattr(tasks, 'task_%s' % (self.arguments[0], )) prompt = self.options.get('prompt', '$') commands = task() lines = ['.. prompt:: bash %s' % (prompt, ), ''] for command in commands: try: handler = HANDLERS[type(command)] except KeyError: raise self.error("task: %s not supported" % (type(command).__name__, )) lines += [' %s' % (line, ) for line in handler(command)] # The following three lines record (some?) of the dependencies of the # directive, so automatic regeneration happens. Specifically, it # records this file, and the file where the task is declared. task_file = getsourcefile(task) tasks_file = getsourcefile(tasks) self.state.document.settings.record_dependencies.add(task_file) self.state.document.settings.record_dependencies.add(tasks_file) self.state.document.settings.record_dependencies.add(__file__) node = nodes.Element() text = StringList(lines) self.state.nested_parse(text, self.content_offset, node) return node.children
def run(self): collections = sphinxcontrib.collections.collections.COLLECTIONS search_cols = [x.strip() for x in self.arguments[0].split(',')] found = False for search_col in search_cols: if search_col == '': continue for collection in collections: if collection.name.upper() == search_col.upper() and collection.executed: found = True break if found: break collection_node = nodes.container() if found: rst = ViewList() for line in self.content: rst.append(line, self.docname, self.lineno) node_collection_content = nodes.Element() node_collection_content.document = self.state.document nested_parse_with_titles(self.state, rst, node_collection_content) collection_node += node_collection_content.children return [collection_node]
def run(self): env = self.state.document.settings.env node = nodes.Element() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) images = [] caption_and_legend = [] for child in node: if isinstance(child, (nodes.target, nodes.image, nodes.figure)): images.append(child) else: caption_and_legend.append(child) items = [] row_item_count = min( len(images), self.options.get('rowitems', DEFAULT_ROW_ITEM_COUNT)) labels = self.options.get('labels', []) for img, label in itertools.zip_longest(images, labels): item_node = multifigure_item('', img) item_node['item-width'] = 100 // row_item_count if label is not None: item_node['label'] = label items.append(item_node) caption, legend = caption_and_legend[0], caption_and_legend[1:] resultnode = nodes.figure('', multifigure_content('', *items)) resultnode['labels'] = labels resultnode.append(nodes.caption(caption.rawsource, '', *caption)) if legend: resultnode.append(nodes.legend('', *legend)) return [resultnode]
def run(self): tag = self.arguments[0] path = self.arguments[1] url = 'https://raw.githubusercontent.com/walmartlabs/clojure-game-geek/' + tag + '/' + path content = [".. remoteinclude:: " + url ] for k, v in self.options.iteritems(): if v is None: content += [' :' + k + ':'] else: content += [' :' + k + ': ' + v] if not(self.options.has_key('language')): content += [' :language: clojure'] if not(self.options.has_key('caption')): content += [' :caption: ' + path] vl = ViewList(content, source='') node = nodes.Element() self.state.nested_parse(vl, self.content_offset, node) return node.children
def run(self): label = self.options.get('label', None) width = self.options.get('width', None) alt = self.options.get('alt', None) node = subfigend('', ids=[label] if label is not None else []) if width is not None: node['width'] = width if alt is not None: node['alt'] = alt if self.content: anon = nodes.Element() self.state.nested_parse(self.content, self.content_offset, anon) first_node = anon[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) node += caption if label is not None: targetnode = nodes.target('', '', ids=[label]) node.append(targetnode) return [node]
def unicode_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): r""" Convert Unicode character codes (numbers) to characters. Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``, ``x``, ``\x``, ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style numeric character entities (e.g. ``☮``). Text following ".." is a comment and is ignored. Spaces are ignored, and any other text remains as-is. """ if not isinstance(state, states.SubstitutionDef): error = state_machine.reporter.error( 'Invalid context: the "%s" directive can only be used within a ' 'substitution definition.' % (name), nodes.literal_block(block_text, block_text), line=lineno) return [error] substitution_definition = state_machine.node if options.has_key('trim'): substitution_definition.attributes['ltrim'] = 1 substitution_definition.attributes['rtrim'] = 1 if options.has_key('ltrim'): substitution_definition.attributes['ltrim'] = 1 if options.has_key('rtrim'): substitution_definition.attributes['rtrim'] = 1 codes = unicode_comment_pattern.split(arguments[0])[0].split() element = nodes.Element() for code in codes: try: decoded = directives.unicode_code(code) except ValueError, err: error = state_machine.reporter.error( 'Invalid character code: %s\n%s: %s' % (code, err.__class__.__name__, err), nodes.literal_block(block_text, block_text), line=lineno) return [error] element += nodes.Text(decoded)