def render_image(src: str, smooth: bool = True) -> List[nodes.Node]: """Given the source code for an image return a doctree that when rendered by Sphinx will insert that image into a HTML page. Parameters ---------- src: The source code that produces the image. smooth: If :code:`True` (default) allow the browser to scale the image using an algorithm that smooths out the edges of the image. """ doctree = [] try: code = compile(src, "<string>", "exec") except Exception: message = nodes.Text("Unable to render image: Invalid code") err = nodes.literal_block("", traceback.format_exc()) doctree.append(nodes.error("", message, err)) return doctree environment = {} try: exec(code, environment) except Exception: message = nodes.Text("Unable to render image: Error in code") err = nodes.literal_block("", traceback.format_exc()) doctree.append(nodes.error("", message, err)) return doctree image = None for obj in environment.values(): if isinstance(obj, Image): image = obj if image is not None: context = { "data": ar.encode(image).decode("utf-8"), "rendering": "auto" if smooth else "crisp-edges", } html = IMAGE_TEMPLATE.safe_substitute(context) doctree.append(nodes.raw("", html, format="html")) return doctree
def run(self): env = self.state.document.settings.env app = env.app template_path = self.arguments[0] module_path, template_name = template_path.rsplit('.', 1) try: module = importlib.import_module(module_path) except ImportError: msg = "Unable to import Bokeh template module: %s" % module_path app.warn(msg) node = nodes.error(None, nodes.paragraph(text=msg), nodes.paragraph(text=str(sys.exc_info()[1]))) return [node] template = getattr(module, template_name, None) if template is None: msg = "Unable to find Bokeh template: %s" % template_path app.warn(msg) node = nodes.error(None, nodes.paragraph(text=msg)) return [node] template_text = open(template.filename).read() m = DOCPAT.match(template_text) if m: doc = m.group(1) else: doc = None filename = basename(template.filename) rst_text = JINJA_TEMPLATE.render( name=template_name, module=module_path, objrepr=repr(template), doc="" if doc is None else textwrap.dedent(doc), lang=filename.rsplit('.', 1)[-1], filename=filename, template_text=DOCPAT.sub("", template_text), ) result = ViewList() for line in rst_text.split("\n"): result.append(line, "<bokeh-jinja>") node = nodes.paragraph() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def run(self): # Respect the same disabling options as the ``raw`` directive if (not self.state.document.settings.raw_enabled or not self.state.document.settings.file_insertion_enabled): raise self.warning(f'"{self.name}" directive disabled.') attributes = {'format': ' '.join(self.arguments[0].lower().split())} source, lineno = self.state_machine.get_source_and_line(self.lineno) old_stdout, sys.stdout = sys.stdout, StringIO() try: # Exceute the Python code and capture its output exec('\n'.join(self.content)) text = sys.stdout.getvalue() # Wrap HTML output in a black border if requested if attributes['format'] == 'html' and 'html_border' in self.options: text = f"<div style='border:1px solid black; padding:3px'>{text}</div>" # Append the output in the same fashion as the ``raw`` directive raw_node = nodes.raw('', text, **attributes) raw_node.source, raw_node.line = source, lineno return [raw_node] except Exception as e: message = f"Unable to execute Python code at {os.path.basename(source)}:{lineno}" return [nodes.error(None, nodes.paragraph(text=message)), nodes.paragraph(text=str(e))] finally: sys.stdout = old_stdout
def run(self): oldStdout, sys.stdout = sys.stdout, StringIO() try: exec '\n'.join(self.content) return [nodes.paragraph(text = sys.stdout.getvalue())] except Exception, e: return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(self.src), self.srcline)), nodes.paragraph(text = str(e)))]
def run(self): old_stdout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) try: exec('\n'.join(self.content), globals()) text = sys.stdout.getvalue() lines = statemachine.string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception: return [ nodes.error( None, nodes.paragraph( text="Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1]))) ] finally: sys.stdout = old_stdout
def run(self): import importlib import shlex from click.testing import CliRunner arg = self.arguments[0] options = shlex.split(self.options.get('args', '')) try: modname, funcname = arg.split(':') except ValueError: raise self.error('run-click argument must be "module:function"') try: mod = importlib.import_module(modname) func = getattr(mod, funcname) runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(func, options) text = result.output if result.exit_code != 0: raise RuntimeError('Command exited with non-zero exit code; output: "%s"' % text) node = nodes.literal_block(text=text) node['language'] = 'text' return [node] except Exception: warn_text = "Error while running command %s %s" % (arg, ' '.join(map(shlex.quote, options))) warning = self.state_machine.reporter.warning(warn_text) return [warning, nodes.error(None, nodes.paragraph(text=warn_text), nodes.paragraph(text=str(sys.exc_info()[1])))]
def run(self): oldStdout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) try: exec("\n".join(self.content)) text = sys.stdout.getvalue() lines = statemachine.string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception: return [ nodes.error( None, nodes.paragraph( text="Unable to execute python " "code at {file}:{line}".format( file=os.path.basename(source), line=self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])), ) ] finally: sys.stdout = oldStdout
def run(self): # filename *or* python code content, but not both if self.arguments and self.content: raise RuntimeError("bokeh-plot:: directive can't have both args and content") env = self.state.document.settings.env app = env.app if not hasattr(env, 'bokeh_plot_tmpdir'): env.bokeh_plot_tmpdir = mkdtemp() app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) else: tmpdir = env.bokeh_plot_tmpdir if not exists(tmpdir) or not isdir(tmpdir): app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) env.bokeh_plot_tmpdir = mkdtemp() else: app.verbose("using existing temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) # TODO (bev) verify that this is always the correct thing rst_source = self.state_machine.node.document['source'] rst_dir = dirname(rst_source) rst_filename = basename(rst_source) target_id = "%s.bokeh-plot-%d" % (rst_filename, env.new_serialno('bokeh-plot')) target_node = nodes.target('', '', ids=[target_id]) result = [target_node] try: source = self._get_source() except Exception: node = nodes.error(None, nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (basename(rst_source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1]))) return [node] source_position = self.options.get('source-position', 'below') if source_position == 'above': result += self._get_source_nodes(source) node = bokeh_plot() node['target_id'] = target_id node['source'] = source node['relpath'] = relpath(rst_dir, env.srcdir) node['rst_source'] = rst_source node['rst_lineno'] = self.lineno if 'alt' in self.options: node['alt'] = self.options['alt'] if self.arguments: node['path'] = self.arguments[0] env.note_dependency(node['path']) if len(self.arguments) == 2: node['symbol'] = self.arguments[1] result += [node] if source_position == 'below': result += self._get_source_nodes(source) return result
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)), ) ]
def exec_to_state_machine(self, code, tab_width=None): oldStdout, sys.stdout = sys.stdout, StringIO() if tab_width is None: # use default if not given as an option tab_width = self.state.document.settings.tab_width # get the path to this rST source file # for inserting directly to state_machine source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: exec("\n".join(code)) # convert the multi-line string from stdout # into a list of single-line strings lines = statemachine.string2lines(sys.stdout.getvalue(), tab_width, convert_whitespace=True) # insert the list of strings at the source # of the original directive call self.state_machine.insert_input(lines, source) return [] except Exception: document = self.state.document error_src = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno) trace = "\n".join(traceback.format_exception(*sys.exc_info())) return [ nodes.error(None, nodes.paragraph(text=error_src), nodes.literal_block(text=trace)), document.reporter.error("problem executing python code\n" "-- traceback included in document"), ] finally: sys.stdout = oldStdout
def run(self): tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) try: lines = [] dest_dir = Path(source).parent for name in narratives.__all__: narrative = getattr(narratives, name) file_name = f"{narrative.name.replace(' ', '_')}.json" with open(dest_dir / file_name, "w") as n_file: n_file.write( json.dumps(narrative.json(), indent=4, sort_keys=True)) lines.extend( statemachine.string2lines( TMPL.format(source_path=file_name), tab_width, convert_whitespace=True, )) self.state_machine.insert_input(lines, source) return [] except Exception: return [ nodes.error( None, nodes.paragraph( text= f"Failed to produce ert_narratives in {basename(source)}:{self.lineno}:" ), nodes.paragraph(text=str(sys.exc_info()[1])), ) ]
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): print('Running ODFI SVG Directive') print( self.arguments) print( self.options) env = self.state.document.settings.env source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) #logger = logging.getLogger(__name__) #logger.info('Running ODFI SVG Directive') ## Get File fileName = self.arguments[0] #if not "file" in self.arguments: # return [nodes.error(None, nodes.paragraph(text = "Unable to Load SVG at %s:%d: file argument not defined" % (basename(source), self.lineno))) ] ## Get File name relative to local source #fileName = self.arguments[(self.arguments.index('file') +1)] sourceDirectory = dirname(source) sourceSVG = os.path.normpath(sourceDirectory+"/"+fileName) if os.path.exists(sourceSVG): print("SVG File is at: ",sourceSVG) else: return [nodes.error(None, nodes.paragraph(text = "Unable to Load SVG at %s:%d: file %s does not exist" % (basename(source), self.lineno,sourceSVG))) ] ## Create SVG Node targetid = "svg-%d" % env.new_serialno('svg') svgNode = svg() svgNode.source = sourceSVG ## Set Target Group Id if necessary if "gid" in self.arguments: print('Found Elementid') svgNode.groupId = self.arguments[(self.arguments.index('gid') +1)] ## Style Arguments ###################### ## Set Style if necessary if "style" in self.arguments: svgNode.style = self.arguments[(self.arguments.index('style') +1)].replace('"',"").replace("'","") if "align" in self.arguments and self.arguments[(self.arguments.index('align') +1)] == "center": svgNode.style_center = True if ":width:" in self.arguments: svgNode.style_width = self.arguments[(self.arguments.index(':width:') +1)] ## Animation Arguments ###################### return [svgNode]
def run(self): try: filename = os.path.abspath(self.options.get('filename') or omc.sendExpression("currentSimulationResult")) caption = self.options.get('caption') or "Plot generated by OpenModelica+gnuplot" if 'plotall' in self.options: variables = list(omc.sendExpression('readSimulationResultVars(%s)' % escapeString(filename))) variables.remove('time') else: variables = self.content if len(variables)>1: varstr = "{%s}" % ", ".join(variables) varstrquoted = "{%s}" % ", ".join(['"%s"'%s for s in variables]) else: varstr = variables[0] varstrquoted = '{"%s"}'%variables[0] vl = ViewList() if 'parametric' in self.options: vl.append('>>> plotParametric("%s","%s")' % (variables[0],variables[1]), "<OMC gnuplot>") elif 'plotall' in self.options: vl.append(">>> plotall()", "<OMC gnuplot>") node = docutils.nodes.paragraph() self.state.nested_parse(vl, 0, node) cb = node.children csvfile = os.path.abspath("tmp/" + self.arguments[0]) + ".csv" if filename.endswith(".csv"): shutil.copyfile(filename, csvfile) else: assert(omc.sendExpression('filterSimulationResults("%s", "%s", %s)' % (filename,csvfile,varstrquoted))) with open("tmp/%s.gnuplot" % self.arguments[0], "w") as gnuplot: gnuplot.write('set datafile separator ","\n') if 'parametric' in self.options: assert(2 == len(variables)) gnuplot.write('set parametric\n') gnuplot.write('set key off\n') gnuplot.write('set xlabel "%s"\n' % variables[0]) gnuplot.write('set ylabel "%s"\n' % variables[1]) for term in ["pdf", "svg", "png"]: gnuplot.write('set term %s\n' % term) gnuplot.write('set output "%s.%s"\n' % (os.path.abspath("source/" + self.arguments[0]), term)) gnuplot.write('plot \\\n') if 'parametric' in self.options: vs = ['"%s" using "%s":"%s" with lines' % (csvfile,variables[0],variables[1])] else: vs = ['"%s" using 1:"%s" title "%s" with lines, \\\n' % (csvfile,v,v) for v in variables] gnuplot.writelines(vs) gnuplot.write('\n') subprocess.check_call(["gnuplot", "tmp/%s.gnuplot" % self.arguments[0]]) try: vl = ViewList() for text in [".. figure :: %s.*" % self.arguments[0]] + ([" :name: %s" % self.options["name"]] if "name" in self.options else []) + ["", " %s" % caption]: vl.append(text, "<OMC gnuplot>") node = docutils.nodes.paragraph() self.state.nested_parse(vl, 0, node) fig = node.children except Exception, e: s = str(e).decode("utf8") + "\n" + traceback.format_exc().decode("utf8") print s fig = [nodes.error(None, nodes.paragraph(text = "Unable to execute gnuplot-figure directive"), nodes.paragraph(text = s))] return cb + fig
def run(self): env = self.state.document.settings.env # make sure the current document gets re-built if the config file changes env.note_dependency(env.pism_parameters["filename"]) if "prefix" in self.options: prefix = self.options["prefix"] else: prefix = "" # Store the docname corresponding to this parameter list. # It is used in resolve_config_links() to build URIs. env.pism_parameters["docname"] = env.docname if "exclude" in self.options: exclude = self.options["exclude"] else: exclude = None full_list = prefix == "" and exclude == None parameter_list = nodes.enumerated_list() parameters_found = False for name in sorted(pism_data.keys()): pattern = "^" + prefix # skip parameters that don't have the desired prefix if not re.match(pattern, name): continue if exclude and re.match(exclude, name): continue parameters_found = True item = nodes.list_item() if full_list: # only the full parameter list items become targets item += self.list_entry(name, pism_data[name]) else: item += self.compact_list_entry(name, re.sub(pattern, "", name), pism_data[name]) parameter_list += item if not parameters_found: msg = 'Error in a "{}" directive: no parameters with prefix "{}".'.format(self.name, prefix) text_error = nodes.error() text_error += nodes.Text(msg) reporter = self.state_machine.reporter system_error = reporter.error(msg, nodes.literal('', ''), line=self.lineno) return [text_error, system_error] return [parameter_list]
def html_visit_bokeh_plot(self, node): env = self.builder.env dest_dir = join(self.builder.outdir, node["relpath"]) if settings.docs_cdn() == "local": resources = Resources(mode="server", root_url="/en/latest/") else: resources = Resources(mode="cdn") try: if "path" in node: path = node["path"] filename = "bokeh-plot-%s.js" % hashlib.md5(path.encode("utf-8")).hexdigest() dest_path = join(dest_dir, filename) tmpdir = join(env.bokeh_plot_tmpdir, node["relpath"]) if not exists(tmpdir): makedirs(tmpdir) cached_path = join(tmpdir, filename) if out_of_date(path, cached_path) or not exists(cached_path + ".script"): self.builder.app.verbose("generating new plot for '%s'" % path) plot = _render_plot(node["source"], node.get("symbol")) js, script = autoload_static(plot, resources, filename) with open(cached_path, "w") as f: f.write(js) with open(cached_path + ".script", "w") as f: f.write(script) else: self.builder.app.verbose("using cached plot for '%s'" % path) script = open(cached_path + ".script", "r").read() if not exists(dest_dir): makedirs(dest_dir) copy(cached_path, dest_path) else: filename = node["target_id"] + ".js" if not exists(dest_dir): makedirs(dest_dir) dest_path = join(dest_dir, filename) plot = _render_plot(node["source"], None) js, script = autoload_static(plot, resources, filename) self.builder.app.verbose("saving inline plot at: %s" % dest_path) with open(dest_path, "w") as f: f.write(js) html = SCRIPT_TEMPLATE.render(script=script) self.body.append(html) except Exception: err_node = nodes.error( None, nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (node["rst_source"], node["rst_lineno"])), nodes.paragraph(text=str(sys.exc_info()[1])), ) node.children.append(err_node) raise nodes.SkipDeparture else: raise nodes.SkipNode
def run(self): oldStdout, sys.stdout = sys.stdout, StringIO() try: exec('\n'.join(self.content)) return [nodes.paragraph(text = sys.stdout.getvalue())] except Exception as e: return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(self.src), self.srcline)), nodes.paragraph(text = str(e)))] finally: sys.stdout = oldStdout
def run(self): oldStdout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: code = '\n'.join(self.content) exec(code) text = sys.stdout.getvalue() except Exception: return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))] finally: sys.stdout = oldStdout linespec = self.options.get('emphasize-lines') if linespec: try: nlines = len(self.content) hl_lines = [x+1 for x in parselinenos(linespec, nlines)] except ValueError as err: document = self.state.document return [document.reporter.warning(str(err), line=self.lineno)] else: hl_lines = None chevron_code = code.split('\n') chevron_code = [c for c in chevron_code if '#hide' not in c] chevron_code = '\n'.join([''.join(['>> ', line]) for line in chevron_code]) if 'dedent' in self.options: lines = code.split('\n') lines = dedent_lines(lines, self.options['dedent']) code = '\n'.join([lines]) lines = '\n'.join([chevron_code, text]) literal = nodes.literal_block(lines, lines) # literal['language'] = 'python' literal['linenos'] = 'linenos' in self.options or \ 'lineno-start' in self.options literal['classes'] += self.options.get('class', []) extra_args = literal['highlight_args'] = {} if hl_lines is not None: extra_args['hl_lines'] = hl_lines if 'lineno-start' in self.options: extra_args['linenostart'] = self.options['lineno-start'] set_source_info(self, literal) caption = self.options.get('caption') if caption: self.options.setdefault('name', nodes.fully_normalize_name(caption)) literal = container_wrapper(self, literal, caption) self.add_name(literal) return [literal]
def no_plantuml(node): """Adds a hint that plantuml is not available""" content = nodes.error() para = nodes.paragraph() text = nodes.Text("PlantUML is not available!", "PlantUML is not available!") para += text content.append(para) node.replace_self(content)
def run(self): #oldStdout, sys.stdout = sys.stdout, StringIO() erroratend = 'erroratend' in self.options or ( not 'noerror' in self.options and len(self.content) == 1) or 'hidden' in self.options try: if 'clear' in self.options: assert (omc.sendExpression('clear()')) res = [] if 'combine-lines' in self.options: old = 0 content = [] for i in self.options['combine-lines']: assert (i > old) content.append("\n".join( [str(s) for s in self.content[old:i]])) old = i else: content = [str(s) for s in self.content] for s in content: if 'ompython-output' in self.options: res.append('>>> omc.sendExpression(%s)' % escapeString(s)) else: res.append(">>> %s" % s) if s.strip().endswith(";"): assert ("" == omc.sendExpression(str(s), parsed=False).strip()) elif 'parsed' in self.options: res.append(fixPaths(omc.sendExpression(str(s)))) else: res.append( fixPaths(omc.sendExpression(str(s), parsed=False))) if not ('noerror' in self.options or erroratend): errs = fixPaths( omc.sendExpression('getErrorString()', parsed=False)) if errs != '""': res.append(errs) # res += sys.stdout.readlines() self.content = res if 'ompython-output' in self.options: self.arguments.append('python') else: self.arguments.append('modelica') return ([] if 'hidden' in self.options else super( ExecMosDirective, self).run()) + (getErrorString(self.state) if erroratend else []) except Exception as e: s = str(e) + "\n" + traceback.format_exc() print(s) return [ nodes.error( None, nodes.paragraph(text="Unable to execute Modelica code"), nodes.paragraph(text=s)) ] finally: pass # sys.stdout = oldStdout
def html_visit_bokeh_plot(self, node): env = self.builder.env dest_dir = join(self.builder.outdir, node["relpath"]) if settings.docs_cdn() == "local": resources = Resources(mode="server", root_url="/en/latest/") else: resources = Resources(mode="cdn") try: if "path" in node: path = node['path'] filename = "bokeh-plot-%s.js" % hashlib.md5( path.encode('utf-8')).hexdigest() dest_path = join(dest_dir, filename) tmpdir = join(env.bokeh_plot_tmpdir, node["relpath"]) if not exists(tmpdir): makedirs(tmpdir) cached_path = join(tmpdir, filename) if out_of_date(path, cached_path) or not exists(cached_path + ".script"): self.builder.app.verbose("generating new plot for '%s'" % path) plot = _render_plot(node['source'], node.get('symbol')) js, script = autoload_static(plot, resources, filename) with open(cached_path, "w") as f: f.write(js) with open(cached_path + ".script", "w") as f: f.write(script) else: self.builder.app.verbose("using cached plot for '%s'" % path) script = open(cached_path + ".script", "r").read() if not exists(dest_dir): makedirs(dest_dir) copy(cached_path, dest_path) else: filename = node['target_id'] + ".js" if not exists(dest_dir): makedirs(dest_dir) dest_path = join(dest_dir, filename) plot = _render_plot(node['source'], None) js, script = autoload_static(plot, resources, filename) self.builder.app.verbose("saving inline plot at: %s" % dest_path) with open(dest_path, "w") as f: f.write(js) html = SCRIPT_TEMPLATE.render(script=script) self.body.append(html) except Exception: err_node = nodes.error( None, nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (node['rst_source'], node['rst_lineno'])), nodes.paragraph(text=str(sys.exc_info()[1]))) node.children.append(err_node) raise nodes.SkipDeparture else: raise nodes.SkipNode
def run(self): NAMESPACE["DOC"] = sio = StringIO() try: exec '\n'.join(self.content) in NAMESPACE s = unicode(sio.getvalue().decode('UTF-8')) if len(s) > 0: return [nodes.literal_block(text = s)] else: return [] except Exception, e: traceback.print_exc() return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (osp.basename(self.src), self.srcline)), nodes.paragraph(text = str(e)))]
def getErrorString(state): (nm, ne, nw) = omc.sendExpression("countMessages()") s = fixPaths(omc.sendExpression("OpenModelica.Scripting.getErrorString()")) if nm == 0: return [] node = nodes.paragraph() for x in s.split("\n"): node += nodes.paragraph(text=x) if ne > 0: return [nodes.error(None, node)] elif nw > 0: return [nodes.warning(None, node)] else: return [nodes.note(None, node)]
def getErrorString(state): (nm,ne,nw) = omc.sendExpression("countMessages()") s = fixPaths(omc.sendExpression("OpenModelica.Scripting.getErrorString()")) if nm==0: return [] node = nodes.paragraph() for x in s.split("\n"): node += nodes.paragraph(text = x) if ne>0: return [nodes.error(None, node)] elif nw>0: return [nodes.warning(None, node)] else: return [nodes.note(None, node)]
def run(self): self.assert_has_content() p = subprocess.Popen(['dot', '-Tsvg'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding="utf8") p.stdin.write('\n'.join(self.content)) img = p.communicate()[0] p.stdin.close() ret = p.wait() if ret: return [nodes.error('some error occured')] else: image = img[img.find("viewBox"):] height = self.options.get("height", "100%") width = self.options.get("width", "100%") return [nodes.raw('', f"<svg class=\"dot\" height=\"{height}\" width=\"{width}\" {image}", format='html')]
def run(self): tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) old_stdout, sys.stdout = sys.stdout, StringIO() try: exec '\n'.join(self.content) text = sys.stdout.getvalue() lines = string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception as e: errmsg = 'Unable to execute python code at {}:{}'.format(os.path.basename(source), self.lineno) return [nodes.error(None, nodes.paragraph(text=errmsg), nodes.paragraph(text=str(e)))] finally: sys.stdout = old_stdout
def run(self): old_stdout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: exec('\n'.join(self.content), globals()) text = sys.stdout.getvalue() lines = statemachine.string2lines(text, tab_width, convert_whitespace = True) self.state_machine.insert_input(lines, source) return [] except Exception: return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))] finally: sys.stdout = old_stdout
def run(self): tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) old_stdout, sys.stdout = sys.stdout, StringIO() try: exec "\n".join(self.content) text = sys.stdout.getvalue() lines = string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception as e: errmsg = "Unable to execute python code at {}:{}".format(os.path.basename(source), self.lineno) return [nodes.error(None, nodes.paragraph(text=errmsg), nodes.paragraph(text=str(e)))] finally: sys.stdout = old_stdout
def html_visit_bokeh_plot(self, node): env = self.builder.env dest_dir = join(self.builder.outdir, node["relpath"]) try: if node.has_key('path'): path = node['path'] filename = "bokeh-plot-%s.js" % hashlib.md5(path.encode('utf-8')).hexdigest() dest_path = join(dest_dir, filename) tmpdir = join(env.bokeh_plot_tmpdir, node["relpath"]) if not exists(tmpdir): makedirs(tmpdir) cached_path = join(tmpdir, filename) if out_of_date(path, cached_path) or not exists(cached_path+".script"): self.builder.app.verbose("generating new plot for '%s'" % path) plot = _render_plot(node['source'], node.get('symbol')) js, script = autoload_static(plot, CDN, filename) with open(cached_path, "w") as f: f.write(js) with open(cached_path+".script", "w") as f: f.write(script) else: self.builder.app.verbose("using cached plot for '%s'" % path) script = open(cached_path+".script", "r").read() if not exists(dest_dir): makedirs(dest_dir) copy(cached_path, dest_path) else: filename = node['target_id'] + ".js" if not exists(dest_dir): makedirs(dest_dir) dest_path = join(dest_dir, filename) plot = _render_plot(node['source'], None) js, script = autoload_static(plot, CDN, filename) self.builder.app.verbose("saving inline plot at: %s" % dest_path) with open(dest_path, "w") as f: f.write(js) html = SCRIPT_TEMPLATE.render(script=script) self.body.append(html) except Exception: err_node = nodes.error(None, nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (node['rst_source'], node['rst_lineno'])), nodes.paragraph(text=str(sys.exc_info()[1]))) node.children.append(err_node) raise nodes.SkipDeparture else: raise nodes.SkipNode
def run(self): self.reporter = self.state.document.reporter api_url = self.content[0] if len(self.content) > 1: selected_tags = self.content[1:] else: selected_tags = [] try: api_desc = self.processSwaggerURL(api_url) groups = self.group_tags(api_desc) self.check_tags(selected_tags, groups.keys(), api_url) entries = [] for tag_name, methods in groups.items(): if tag_name in selected_tags or len(selected_tags) == 0: section = self.create_section(tag_name) for path, method_type, method in methods: section += self.make_method(path, method_type, method) entries.append(section) return entries except Exception as e: error_message = 'Unable to process URL: %s' % api_url print(error_message) traceback.print_exc() error = nodes.error('') para_error = nodes.paragraph() para_error += nodes.Text( error_message + '. Please check that the URL is a valid Swagger api-docs URL and it is accesible' ) para_error_detailed = nodes.paragraph() para_error_detailed = nodes.strong( 'Processing error. See console output for a more detailed error' ) error += para_error error += para_error_detailed return [error]
def run(self): #oldStdout, sys.stdout = sys.stdout, StringIO() erroratend = 'erroratend' in self.options or (not 'noerror' in self.options and len(self.content)==1) or 'hidden' in self.options try: if 'clear' in self.options: assert(omc.sendExpression('clear()')) res = [] if 'combine-lines' in self.options: old = 0 content = [] for i in self.options['combine-lines']: assert(i > old) content.append("\n".join([str(s) for s in self.content[old:i]])) old = i else: content = [str(s) for s in self.content] for s in content: if 'ompython-output' in self.options: res.append('>>> omc.sendExpression(%s)' % escapeString(s)) else: res.append(">>> %s" % s) if s.strip().endswith(";"): assert("" == omc.sendExpression(str(s), parsed=False).strip()) elif 'parsed' in self.options: res.append(fixPaths(omc.sendExpression(str(s)))) else: res.append(fixPaths(omc.sendExpression(str(s), parsed=False))) if not ('noerror' in self.options or erroratend): errs = fixPaths(omc.sendExpression('getErrorString()', parsed=False)) if errs!='""': res.append(errs) # res += sys.stdout.readlines() self.content = res if 'ompython-output' in self.options: self.arguments.append('python') else: self.arguments.append('modelica') return ([] if 'hidden' in self.options else super(ExecMosDirective, self).run()) + (getErrorString(self.state) if erroratend else []) except Exception as e: s = str(e) + "\n" + traceback.format_exc() print(s) return [nodes.error(None, nodes.paragraph(text = "Unable to execute Modelica code"), nodes.paragraph(text = s))] finally: pass # sys.stdout = oldStdout
def run(self): category = self.arguments[0] tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) try: plugin_registry = _load_all_plugins_for_category(category) config_base_class = plugin_registry.get_base_config( category=category) category_default = plugin_registry.get_default_for_category( category=category) # Find parent of config base class, as we want to document all # inherited members from all base classes up to this class (but NOT # including). base_cls = ("" if len(config_base_class.__bases__) == 0 else config_base_class.__bases__[0].__name__) lines = self._insert_category_header(tab_width, category, category_default) for config_cls in plugin_registry.get_original_configs( category).values(): lines.extend( self._insert_configs(tab_width, base_cls, config_cls)) source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) self.state_machine.insert_input(lines, source) return [] except Exception: logging.exception( "Failed to produce plugin documentation for " f"category {category} on {basename(source)}:{self.lineno}:") return [ nodes.error( None, nodes.paragraph( text= "Failed to produce plugin documentation for category " f"{category} on {basename(source)}:{self.lineno}:"), nodes.paragraph(text=str(sys.exc_info()[1])), ) ]
def run(self): pdfNode = Pdf() ## Get File, relative to current source ############### fileName = self.arguments[0] env = self.state.document.settings.env source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) sourceDirectory = dirname(source) pdfFile = os.path.normpath(sourceDirectory + "/" + fileName) ## Normalize name because of upper case issues on windows pdfFile = "%s[%s]" % (pdfFile[:-1], pdfFile[-1]) pdfFile = glob.glob(pdfFile)[0] if os.path.exists(pdfFile): print("PDF File is at: ", pdfFile) else: return [ nodes.error( None, nodes.paragraph( text= "Unable to Load PDF File at %s:%d: file %s does not exist" % (basename(source), self.lineno, pdfFile))) ] pdfNode.fileName = fileName pdfNode.file = pdfFile ## Set content pdfNode.content = self.content ## Sticky if ":sticky:" in self.arguments: pdfNode.sticky = True else: pdfNode.sticky = False return [pdfNode]
def run(self): try: methods = self.processSwaggerURL(self.content[0]) entries = [] for method in methods: for operation in method['operations']: entries += self.make_operation(method['path'], operation) return entries except: print('Unable to process URL: %s' % self.content[0]) error = nodes.error('') para = nodes.paragraph() para += nodes.Text('Unable to process URL: ') para += nodes.strong('', self.content[0]) para += nodes.Text('. Please check that the URL is a valid Swagger api-docs URL and it is accesible') error += para return [error]
def run(self): try: methods = self.processSwaggerURL(self.content[0]) entries = [] for method in methods: for operation in method['operations']: entries += self.make_operation(method['path'], operation) return entries except: print 'Unable to process URL: %s' % self.content[0] error = nodes.error('') para = nodes.paragraph() para += nodes.Text('Unable to process URL: ') para += nodes.strong('', self.content[0]) para += nodes.Text('. Please check that the URL is a valid Swagger api-docs URL and it is accesible') error += para return [error]
def run(self): try: with subprocess.Popen( self.command, stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdout=subprocess.PIPE, ) as process: deepdict = deepdict_factory(len(self.sections))() for match in self._iter_match(process.stdout): subdict = deepdict for section in self.sections: subdict = subdict[match[section]] subdict.append(match) except FileNotFoundError as exception: error = nodes.error() error.append(nodes.paragraph(text=str(exception))) return [error] return [self._render_deepdict(deepdict)]
def run(self): tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: output = [] for cmd in self.content: output.append(subprocess.check_output(cmd, shell=True)) lines = statemachine.string2lines( "\n".join([codecs.decode(elem, "utf-8") for elem in output]), tab_width, convert_whitespace=False ) self.state_machine.insert_input(lines, source) return [] except Exception: exc = sys.exc_info() return [ nodes.error( None, nodes.paragraph(text="Unable to run command at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(exc[1]) + "\n".join([] + traceback.format_tb(exc[2]))), ) ]
def run(self): """Function used when adding the directive to an index.rst.""" old_stdoutout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: exec("\n".join(self.content)) # pylint: disable=exec-used text = sys.stdout.getvalue() lines = statemachine.string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception: # pylint: disable=W0703 return [ nodes.error( None, nodes.paragraph(text=f"Unable to execute python code at {basename(source)}:{self.lineno}:"), nodes.paragraph(text=str(sys.exc_info()[1])), ) ] finally: sys.stdout = old_stdoutout
def run(self): self.assert_has_content() global nthUnnamed try: filename = self.arguments[0] except: filename = ('dot%d.png' % nthUnnamed) nthUnnamed += 1 content = '\n'.join(self.content) filetype = filename[filename.rfind('.') + 1:] args = ['dot', '-o' + filename, '-T' + filetype] dot = sp.Popen(args, 0, None, sp.PIPE) dot.stdin.write(content) dot.stdin.close() ret = dot.wait() if ret: return [nodes.error('some error occured')] else: return [ nodes.raw('', '<img src="%s" alt="%s"/>' % (filename, filename), format='html') ]
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 = [] error_node = nodes.error() for i, child in enumerate(node): if isinstance(child, nodes.literal_block): if 'language' in child: language = child['language'] else: language = env.app.config.highlight_language innernode = nodes.emphasis(self.formats[language], self.formats[language]) para = nodes.paragraph() para += [innernode, child] entry = nodes.list_item('') entry.append(para) entries.append(entry) elif isinstance(child, nodes.system_message): error_node += child.children if error_node.children: return [error_node] resultnode = configurationblock() resultnode.append(nodes.bullet_list('', *entries)) return [resultnode]
def run(self): tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) narrative_dir = os.getenv(NARRATIVE_DIR) dest_dir = Path(source).parent if not narrative_dir: return [] try: p = Path(narrative_dir).glob("*.json") files = [x for x in p if x.is_file()] if not files: return [nodes.paragraph(text="Found no narratives.")] lines = [] for file in files: shutil.copyfile(file, dest_dir / file.name) lines.extend( statemachine.string2lines( TMPL.format(source_path=file.name), tab_width, convert_whitespace=True, )) self.state_machine.insert_input(lines, source) return [] except Exception: return [ nodes.error( None, nodes.paragraph( text= f"Failed to produce ert_narratives in {basename(source)}:{self.lineno}:" ), nodes.paragraph(text=str(sys.exc_info()[1])), ) ]
def run(self): ## print('self.content = %s' % self.content) ## print('self.name = %s' % self.name) ## print('self.lineno = %s' % self.lineno) ## print('self.content_offset = %s' % self.content_offset) ## print('self.block_text = %s' % self.block_text) ## print('self.state = %s' % self.state) ## print('self.state_machine = %s' % self.state_machine) oldStdout, sys.stdout = sys.stdout, StringIO() tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) try: ## import wx ## app = wx.App(0) Should_I_Allow_Possible_Arbitrary_Code_Execution = '%s' % self.content[0].strip() in AUTHORIZED_ALLOWED_CLASSNAME_EVIL_STRINGS ## wx.MessageBox('%s' % Should_I_Allow_Possible_Arbitrary_Code_Execution, 'Should_I_Allow_Possible_Arbitrary_Code_Execution') ## wx.MessageBox('%s' % self.content[0].strip(), 'self.content') if not Should_I_Allow_Possible_Arbitrary_Code_Execution: raise Exception('UNAUTHORIZED ClassName! \n%s' % self.content) stripedContent = self.content[0].strip() if ' ' in stripedContent: raise Exception('UNAUTHORIZED ClassName! \n%s' % self.content) className = stripedContent class_ = eval(stripedContent) # Should evaluate to one of the imported Classes members = inspect.getmembers(class_, predicate=inspect.ismethod) ## newly_defined_methods = [] ## for methodName, method in members: ## method_type = magicmethod(method) ## if method_type in ('newly defined', 'overloaded') and methodName is not '__init__': ## newly_defined_methods.append(methodName) newly_defined_methods = [(':meth:`~' + methodName + '`') for methodName, method in members if magicmethod(method) in ('newly defined', 'overloaded') and methodName is not '__init__'] method_names = [methodName for methodName, method in members if magicmethod(method) in ('newly defined', 'overloaded') and methodName is not '__init__'] methods_summaryStr = '' if not newly_defined_methods: longest_string = 0 # We have an empty class or one with just __init__ if not hasattr(class_, '__init__'): return [] # Probably an empty class. Ex: DebugClass(): pass else: longest_string = len(max(newly_defined_methods, key=len)) if longest_string < len(':meth:`~__init__`'): longest_string = len(':meth:`~__init__`') tableTopBottom = '=' * longest_string sphinxIndent = ' ' * 2 methods_summaryStr += ('|methods_summary|:\n\n') methods_summaryStr += ('%s%s %s\n' % (sphinxIndent, tableTopBottom, tableTopBottom)) if hasattr(class_, '__init__'): methods_summaryStr += ('%s%s %s\n' % (sphinxIndent, ':meth:`~__init__`'.ljust(longest_string, ' '), 'Default class constructor.')) for i, strng in enumerate(newly_defined_methods): leftHalf = strng.ljust(longest_string, ' ') docStr = inspect.getdoc(eval('%s.%s' % (className, method_names[i]))) if docStr is None: rightHalf = 'None: Missing Docstring' else: docStrReplace = docStr.replace('\r\n', '\n').replace('\r', '\n') if '\n' in docStrReplace: firstLineOfdocStr = '%s' % docStrReplace[0: docStrReplace.find('\n') + 1] else: # Single liner docstring. firstLineOfdocStr = docStrReplace rightHalf = firstLineOfdocStr methods_summaryStr += ('%s%s %s\n' % (sphinxIndent, leftHalf, rightHalf)) methods_summaryStr += ('%s%s %s\n' % (sphinxIndent, tableTopBottom, tableTopBottom)) methods_summaryStr += ('\n|%s|\n' % ('_' * 74)) text = methods_summaryStr lines = statemachine.string2lines(text, tab_width, convert_whitespace=True) self.state_machine.insert_input(lines, source) return [] except Exception as exc: raise exc return [nodes.error(None, nodes.paragraph(text="UNAUTHORIZED attempt to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])))] finally: sys.stdout = oldStdout
def run(self): # filename *or* python code content, but not both if self.arguments and self.content: raise RuntimeError("bokeh-plot:: directive can't have both args and content") env = self.state.document.settings.env app = env.app if not hasattr(env, "bokeh_plot_tmpdir"): env.bokeh_plot_tmpdir = mkdtemp() app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) else: tmpdir = env.bokeh_plot_tmpdir if not exists(tmpdir) or not isdir(tmpdir): app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) env.bokeh_plot_tmpdir = mkdtemp() else: app.verbose("using existing temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir) # get the name of the source file we are currently processing rst_source = self.state_machine.document["source"] rst_dir = dirname(rst_source) rst_filename = basename(rst_source) # use the source file name to construct a friendly target_id target_id = "%s.bokeh-plot-%d" % (rst_filename, env.new_serialno("bokeh-plot")) target_node = nodes.target("", "", ids=[target_id]) result = [target_node] try: source = self._get_source() except Exception: app.warn("Unable to generate Bokeh plot at %s:%d:" % (basename(rst_source), self.lineno)), node = nodes.error( None, nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (basename(rst_source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])), ) return [node] source_position = self.options.get("source-position", "below") if source_position == "above": result += self._get_source_nodes(source) node = bokeh_plot() node["target_id"] = target_id node["source"] = source node["relpath"] = relpath(rst_dir, env.srcdir) node["rst_source"] = rst_source node["rst_lineno"] = self.lineno if "alt" in self.options: node["alt"] = self.options["alt"] if self.arguments: node["path"] = self.arguments[0] env.note_dependency(node["path"]) if len(self.arguments) == 2: node["symbol"] = self.arguments[1] result += [node] if source_position == "below": result += self._get_source_nodes(source) return result
def run(self): env = self.state.document.settings.env cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] # Pass the version string to kernel-doc, as it needs to use a different # dialect, depending what the C domain supports for each specific # Sphinx versions cmd += ['-sphinx-version', sphinx.__version__] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) # 'function' is an alias of 'identifiers' if 'functions' in self.options: self.options['identifiers'] = self.options.get('functions') # FIXME: make this nicer and more robust against errors if 'export' in self.options: cmd += ['-export'] export_file_patterns = str(self.options.get('export')).split() elif 'internal' in self.options: cmd += ['-internal'] export_file_patterns = str(self.options.get('internal')).split() elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'identifiers' in self.options: identifiers = self.options.get('identifiers').split() if identifiers: for i in identifiers: cmd += ['-function', i] else: cmd += ['-no-doc-sections'] if 'no-identifiers' in self.options: no_identifiers = self.options.get('no-identifiers').split() if no_identifiers: for i in no_identifiers: cmd += ['-nosymbol', i] for pattern in export_file_patterns: for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern): env.note_dependency(os.path.abspath(f)) cmd += ['-export-file', f] cmd += [filename] try: kernellog.verbose(env.app, 'calling kernel-doc \'%s\'' % (" ".join(cmd))) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) kernellog.warn( env.app, 'kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) return [ nodes.error(None, nodes.paragraph(text="kernel-doc missing")) ] elif env.config.kerneldoc_verbosity > 0: sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) result = ViewList() lineoffset = 0 line_regex = re.compile("^#define LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: # sphinx counts lines from 0 lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: doc = env.srcdir + "/" + env.docname + ":" + str( self.lineno) result.append(line, doc + ": " + filename, lineoffset) lineoffset += 1 node = nodes.section() self.do_parse(result, node) return node.children except Exception as e: # pylint: disable=W0703 kernellog.warn( env.app, 'kernel-doc \'%s\' processing failed with: %s' % (" ".join(cmd), str(e))) return [ nodes.error(None, nodes.paragraph(text="kernel-doc missing")) ]
def run(self): print('Running ODFI Steps Recorder Directive') print( self.arguments) print( self.options) print( self.content) env = self.state.document.settings.env source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) ## Get File, relative to current source fileName = self.arguments[0] sourceDirectory = dirname(source) stepsFile = os.path.normpath(sourceDirectory+"/"+fileName) ## Normalize name because of upper case issues on windows stepsFile = "%s[%s]" % (stepsFile[:-1], stepsFile[-1]) stepsFile = glob.glob(stepsFile)[0] if os.path.exists(stepsFile): print("Steps File is at: ",stepsFile) else: return [nodes.error(None, nodes.paragraph(text = "Unable to Load Steps File at %s:%d: file %s does not exist" % (basename(source), self.lineno,stepsFile))) ] ## Read file and split parts ################# stepsNode = StepsRecorder() stepsNode.stepsName = fileName stepsBlock = nodes.container(); ## Steps File can be a Zip File if stepsFile.endswith(".zip"): with ZipFile(stepsFile) as stepsZipFile: with stepsZipFile.open(stepsZipFile.namelist()[0]) as stepsFileEntry: stepsContent = stepsFileEntry.read().decode("cp1252").replace('\r','') #print("Steps content from zip: ",stepsContent.encode(sys.stdout.encoding, errors='replace')) else: with open(stepsFile) as f: stepsContent = f.read() ## get boundary match = re.search('boundary="([\w_=\+\.\-]+)"',stepsContent) boundary= "--"+match.group(1) print("Steps Boundary: "+boundary) ## Split parts = stepsContent.split(boundary) print("Parts: %s" % len(parts)) ## Store Each Part with name resultParts = {} for partContentIndex in range(1, len(parts)): ## Get Part content line by line, to extract parameters ## iF an empty line is encountered, it is the beginning of the content partContent = parts[partContentIndex].strip() partFileContent = "" fileName = "" contentStart = False lines = partContent.split("\n") for lineIndex in range(0, len(lines)): line = lines[lineIndex] if contentStart is True: partFileContent+=line elif line.startswith("Content-Location:"): fileName = line.strip("Content-Location:").strip() print("Part File Name: "+fileName) elif line == "": print("Found Content Start") contentStart = True # Save part file content resultParts[fileName] = partFileContent ## Make admonition ## Save result Parts to node stepsNode.resultParts = resultParts ## Read Directive Content and save Step Description for contentLine in self.content: match = re.search("([\d]+)\s+(.*)",contentLine) number = match.group(1) desc = match.group(2) print("Part desc: ",desc) resultParts[number] = desc ## Add some more options if "toc" in self.arguments: stepsNode.stepsToc = True else: stepsNode.stepsToc = False if "slideshow" in self.arguments: stepsNode.slideshow = True else: stepsNode.slideshow = False return [stepsNode]
def process_needfilters(app, doctree, fromdocname): # Replace all needlist nodes with a list of the collected needs. # Augment each need with a backlink to the original location. env = app.builder.env # NEEDFILTER for node in doctree.traverse(Needfilter): if not app.config.needs_include_needs: # Ok, this is really dirty. # If we replace a node, docutils checks, if it will not lose any attributes. # But this is here the case, because we are using the attribute "ids" of a node. # However, I do not understand, why losing an attribute is such a big deal, so we delete everything # before docutils claims about it. for att in ('ids', 'names', 'classes', 'dupnames'): node[att] = [] node.replace_self([]) continue id = node.attributes["ids"][0] current_needlist = env.need_all_needlists[id] all_needs = env.need_all_needs if current_needlist["layout"] == "list": content = [] elif current_needlist["layout"] == "diagram": content = [] try: if "sphinxcontrib.plantuml" not in app.config.extensions: raise ImportError from sphinxcontrib.plantuml import plantuml except ImportError: content = nodes.error() para = nodes.paragraph() text = nodes.Text("PlantUML is not available!", "PlantUML is not available!") para += text content.append(para) node.replace_self(content) continue plantuml_block_text = ".. plantuml::\n" \ "\n" \ " @startuml" \ " @enduml" puml_node = plantuml(plantuml_block_text, **dict()) puml_node["uml"] = "@startuml\n" puml_connections = "" elif current_needlist["layout"] == "table": content = nodes.table() tgroup = nodes.tgroup() id_colspec = nodes.colspec(colwidth=5) title_colspec = nodes.colspec(colwidth=15) type_colspec = nodes.colspec(colwidth=5) status_colspec = nodes.colspec(colwidth=5) links_colspec = nodes.colspec(colwidth=5) tags_colspec = nodes.colspec(colwidth=5) tgroup += [ id_colspec, title_colspec, type_colspec, status_colspec, links_colspec, tags_colspec ] tgroup += nodes.thead( '', nodes.row('', nodes.entry('', nodes.paragraph('', 'ID')), nodes.entry('', nodes.paragraph('', 'Title')), nodes.entry('', nodes.paragraph('', 'Type')), nodes.entry('', nodes.paragraph('', 'Status')), nodes.entry('', nodes.paragraph('', 'Links')), nodes.entry('', nodes.paragraph('', 'Tags')))) tbody = nodes.tbody() tgroup += tbody content += tgroup all_needs = list(all_needs.values()) if current_needlist["sort_by"] is not None: if current_needlist["sort_by"] == "id": all_needs = sorted(all_needs, key=lambda node: node["id"]) elif current_needlist["sort_by"] == "status": all_needs = sorted(all_needs, key=status_sorter) for need_info in all_needs: status_filter_passed = False if need_info["status"] is None or \ need_info["status"] in current_needlist["status"] or \ len(current_needlist["status"]) == 0: status_filter_passed = True tags_filter_passed = False if len(set(need_info["tags"]) & set(current_needlist["tags"])) > 0 or len( current_needlist["tags"]) == 0: tags_filter_passed = True type_filter_passed = False if need_info["type"] in current_needlist["types"] \ or need_info["type_name"] in current_needlist["types"] \ or len(current_needlist["types"]) == 0: type_filter_passed = True if current_needlist["filter"] is None: python_filter_passed = True else: python_filter_passed = False filter_context = { "tags": need_info["tags"], "status": need_info["status"], "type": need_info["type"], "id": need_info["id"], "title": need_info["title"], "links": need_info["links"], "content": need_info["content"], "search": re.search } try: # python_filter_passed = eval(current_needlist["filter"], globals(), filter_context) python_filter_passed = eval(current_needlist["filter"], None, filter_context) except Exception as e: print("Filter {0} not valid: Error: {1}".format( current_needlist["filter"], e)) if status_filter_passed and tags_filter_passed and type_filter_passed and python_filter_passed: if current_needlist["layout"] == "list": para = nodes.line() description = "%s: %s" % (need_info["id"], need_info["title"]) if current_needlist["show_status"] and need_info[ "status"] is not None: description += " (%s)" % need_info["status"] if current_needlist["show_tags"] and need_info[ "tags"] is not None: description += " [%s]" % "; ".join(need_info["tags"]) title = nodes.Text(description, description) # Create a reference if not need_info["hide"]: ref = nodes.reference('', '') ref['refdocname'] = need_info['docname'] ref['refuri'] = app.builder.get_relative_uri( fromdocname, need_info['docname']) ref['refuri'] += '#' + need_info['target_node']['refid'] ref.append(title) para += ref else: para += title content.append(para) elif current_needlist["layout"] == "table": row = nodes.row() row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "id", make_ref=True) row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "title") row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "type_name") row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "status") row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "links", ref_lookup=True) row += row_col_maker(app, fromdocname, env.need_all_needs, need_info, "tags") tbody += row elif current_needlist["layout"] == "diagram": # Link calculation # All links we can get from docutils functions will be relative. # But the generated link in the svg will be relative to the svg-file location # (e.g. server.com/docs/_images/sqwxo499cnq329439dfjne.svg) # and not to current documentation. Therefore we need to add ../ to get out of the _image folder. try: link = "../" + app.builder.get_target_uri(need_info['docname']) \ + "?highlight={0}".format(urlParse(need_info['title'])) \ + "#" \ + need_info['target_node']['refid'] \ # Gets mostly called during latex generation except NoUri: link = "" diagram_template = Template( env.config.needs_diagram_template) node_text = diagram_template.render(**need_info) puml_node[ "uml"] += '{style} "{node_text}" as {id} [[{link}]] {color}\n'.format( id=need_info["id"], node_text=node_text, link=link, color=need_info["type_color"], style=need_info["type_style"]) for link in need_info["links"]: puml_connections += '{id} --> {link}\n'.format( id=need_info["id"], link=link) if current_needlist["layout"] == "diagram": puml_node["uml"] += puml_connections # Create a legend if current_needlist["show_legend"]: puml_node["uml"] += "legend\n" puml_node["uml"] += "|= Color |= Type |\n" for need in app.config.needs_types: puml_node[ "uml"] += "|<back:{color}> {color} </back>| {name} |\n".format( color=need["color"], name=need["title"]) puml_node["uml"] += "endlegend\n" puml_node["uml"] += "@enduml" puml_node["incdir"] = os.path.dirname(current_needlist["docname"]) puml_node["filename"] = os.path.split( current_needlist["docname"])[1] # Needed for plantuml >= 0.9 content.append(puml_node) if len(content) == 0: nothing_found = "No needs passed the filters" para = nodes.line() nothing_found_node = nodes.Text(nothing_found, nothing_found) para += nothing_found_node content.append(para) if current_needlist["show_filters"]: para = nodes.paragraph() filter_text = "Used filter:" filter_text += " status(%s)" % " OR ".join( current_needlist["status"]) if len( current_needlist["status"]) > 0 else "" if len(current_needlist["status"]) > 0 and len( current_needlist["tags"]) > 0: filter_text += " AND " filter_text += " tags(%s)" % " OR ".join( current_needlist["tags"]) if len( current_needlist["tags"]) > 0 else "" if (len(current_needlist["status"]) > 0 or len(current_needlist["tags"]) > 0) and len( current_needlist["types"]) > 0: filter_text += " AND " filter_text += " types(%s)" % " OR ".join( current_needlist["types"]) if len( current_needlist["types"]) > 0 else "" filter_node = nodes.emphasis(filter_text, filter_text) para += filter_node content.append(para) node.replace_self(content)
def run(self): env = self.state.document.settings.env cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) # FIXME: make this nicer and more robust against errors if 'export' in self.options: cmd += ['-export'] export_file_patterns = str(self.options.get('export')).split() elif 'internal' in self.options: cmd += ['-internal'] export_file_patterns = str(self.options.get('internal')).split() elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: functions = self.options.get('functions').split() if functions: for f in functions: cmd += ['-function', f] else: cmd += ['-no-doc-sections'] for pattern in export_file_patterns: for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern): env.note_dependency(os.path.abspath(f)) cmd += ['-export-file', f] cmd += [filename] try: env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) return [ nodes.error(None, nodes.paragraph(text="kernel-doc missing")) ] elif env.config.kerneldoc_verbosity > 0: sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) result = ViewList() lineoffset = 0 line_regex = re.compile("^#define LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: # sphinx counts lines from 0 lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: result.append(line, filename, lineoffset) lineoffset += 1 node = nodes.section() buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter self.state.memo.reporter = AutodocReporter( result, self.state.memo.reporter) self.state.memo.title_styles, self.state.memo.section_level = [], 0 try: self.state.nested_parse(result, 0, node, match_titles=1) finally: self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf return node.children except Exception as e: # pylint: disable=W0703 env.app.warn('kernel-doc \'%s\' processing failed with: %s' % (" ".join(cmd), str(e))) return [ nodes.error(None, nodes.paragraph(text="kernel-doc missing")) ]
def run(self): # Check if file insertion is enabled if not self.state.document.settings.file_insertion_enabled: msg = ( 'File and URL access deactivated. ' 'Ignoring directive "{}".'.format(self.name) ) warning = nodes.warning( '', self.state_machine.reporter.warning( '', nodes.literal_block('', msg), line=self.lineno ) ) return [warning] # Define plantuml file name if len(self.arguments) > 0: fname = self.arguments[0] else: fname = '{:06d}'.format(self.lineno) fname = join(self.uml_out_dir, fname) # Create images output folder mkpath(abspath(dirname(fname))) # Write plantuml content uml_file = fname + '.uml' if self.content: with open(uml_file, 'wb') as fd: fd.write('@startuml\n') try: fd.write( self.state_machine.document.settings.plantuml_hdr ) fd.write('\n') except AttributeError: pass fd.write('\n'.join(self.content)) fd.write('\n@enduml\n') # Execute plantuml call # Commented because plantuml doesn't have and output flag # image_file = fname + self.uml_out_ext plantuml_cmd = 'plantuml' try: plantuml_cmd = self.state_machine.document.settings.plantuml_cmd except AttributeError: pass try: code = call(shsplit( '{} {} "{}"'.format(plantuml_cmd, self.uml_cmd_args, uml_file) )) if code != 0: raise Exception('plantuml call returned {}.'.format(code)) except: msg = format_exc() error = nodes.error( '', self.state_machine.reporter.error( '', nodes.literal_block('', msg), line=self.lineno ) ) return [error] # Default to align center if not 'align' in self.options: self.options['align'] = 'center' # Run Image directive self.arguments = [fname + self.uml_emb_ext] return Image.run(self)
def run(self): # Execute sanity checks warnings = self._directive_checks() if warnings: return warnings # Fetch builder and environment objects env = self.state_machine.document.settings.env builder = env.app.builder # Determine document directory document_dir = dirname(env.doc2path(env.docname)) # Load content to render if not self.arguments: content = '\n'.join(self.content) else: # Source file should be relative to document, or absolute to # configuration directory. srcfile = self.arguments[0] if isabs(srcfile): srcpath = join(env.app.confdir, relpath(srcfile, start='/')) else: srcpath = join(document_dir, srcfile) if not isfile(srcpath): warning = self.state_machine.reporter.warning( '{} directive cannot find file {}'.format( self._get_directive_name(), srcfile ), line=self.lineno ) return [warning] with open(srcpath, 'rb') as fd: content = fd.read().decode('utf-8') # Execute plantweb call try: output, frmt, engine, sha = render( content, engine=self._get_engine_name() ) except Exception: msg = format_exc() error = nodes.error( '', self.state_machine.reporter.error( '', nodes.literal_block('', msg), line=self.lineno ) ) return [error] # Determine filename filename = '{}.{}'.format(sha, frmt) imgpath = join(builder.outdir, builder.imagedir, 'plantweb') # Create images output folder log.debug('imgpath set to {}'.format(imgpath)) mkpath(imgpath) # Write content filepath = join(imgpath, filename) with open(filepath, 'wb') as fd: fd.write(output) log.debug('Wrote image file {}'.format(filepath)) # Default to align center if 'align' not in self.options: self.options['align'] = 'center' # Determine relative path to image from source document directory filepath_relative = relpath(filepath, document_dir) log.debug('Image relative path {}'.format(filepath_relative)) # Run Image directive self.arguments = [filepath_relative] return Image.run(self)
def run(self): env = self.state.document.settings.env cmd = [env.config.kerneldoc_bin, "-rst", "-enable-lineno"] filename = env.config.kerneldoc_srctree + "/" + self.arguments[0] export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get("tab-width", self.state.document.settings.tab_width) # FIXME: make this nicer and more robust against errors if "export" in self.options: cmd += ["-export"] export_file_patterns = str(self.options.get("export")).split() elif "internal" in self.options: cmd += ["-internal"] export_file_patterns = str(self.options.get("internal")).split() elif "doc" in self.options: cmd += ["-function", str(self.options.get("doc"))] elif "functions" in self.options: for f in str(self.options.get("functions")).split(): cmd += ["-function", f] for pattern in export_file_patterns: for f in glob.glob(env.config.kerneldoc_srctree + "/" + pattern): env.note_dependency(os.path.abspath(f)) cmd += ["-export-file", f] cmd += [filename] try: env.app.verbose("calling kernel-doc '%s'" % (" ".join(cmd))) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = p.communicate() # python2 needs conversion to unicode. # python3 with universal_newlines=True returns strings. if sys.version_info.major < 3: out, err = unicode(out, "utf-8"), unicode(err, "utf-8") if p.returncode != 0: sys.stderr.write(err) env.app.warn("kernel-doc '%s' failed with return code %d" % (" ".join(cmd), p.returncode)) return [nodes.error(None, nodes.paragraph(text="kernel-doc missing"))] elif env.config.kerneldoc_verbosity > 0: sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) result = ViewList() lineoffset = 0 line_regex = re.compile("^#define LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: # sphinx counts lines from 0 lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: result.append(line, filename, lineoffset) lineoffset += 1 node = nodes.section() buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter) self.state.memo.title_styles, self.state.memo.section_level = [], 0 try: self.state.nested_parse(result, 0, node, match_titles=1) finally: self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf return node.children except Exception as e: # pylint: disable=W0703 env.app.warn("kernel-doc '%s' processing failed with: %s" % (" ".join(cmd), str(e))) return [nodes.error(None, nodes.paragraph(text="kernel-doc missing"))]
def run(self): env = self.state.document.settings.env cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) # FIXME: make this nicer and more robust against errors if 'export' in self.options: cmd += ['-export'] export_file_patterns = str(self.options.get('export')).split() elif 'internal' in self.options: cmd += ['-internal'] export_file_patterns = str(self.options.get('internal')).split() elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: functions = self.options.get('functions').split() if functions: for f in functions: cmd += ['-function', f] else: cmd += ['-no-doc-sections'] for pattern in export_file_patterns: for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern): env.note_dependency(os.path.abspath(f)) cmd += ['-export-file', f] cmd += [filename] try: env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] elif env.config.kerneldoc_verbosity > 0: sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) result = ViewList() lineoffset = 0; line_regex = re.compile("^#define LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: # sphinx counts lines from 0 lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: result.append(line, filename, lineoffset) lineoffset += 1 node = nodes.section() buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter) self.state.memo.title_styles, self.state.memo.section_level = [], 0 try: self.state.nested_parse(result, 0, node, match_titles=1) finally: self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf return node.children except Exception as e: # pylint: disable=W0703 env.app.warn('kernel-doc \'%s\' processing failed with: %s' % (" ".join(cmd), str(e))) return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
def run(self): oldStdout, sys.stdout = sys.stdout, StringIO() source = self.state_machine.input_lines.source( self.lineno - self.state_machine.input_offset - 1) try: table = nodes.table() tgroup = nodes.tgroup(cols=2) table += tgroup tgroup += nodes.colspec(colwidth=25, classes=['key']) tgroup += nodes.colspec(colwidth=8, classes=['value']) thead = nodes.thead() tgroup += thead # Add headers row = nodes.row() thead += row entry = nodes.entry() row += entry node = nodes.paragraph(text='Key') entry += node entry = nodes.entry() row += entry node = nodes.paragraph(text='Value') entry += node # Add body tbody = nodes.tbody() tgroup += tbody row = nodes.row() tbody += row for key in ot.ResourceMap.GetKeys(): row = nodes.row() tbody += row entry = nodes.entry() row += entry node = nodes.paragraph(text=key) entry += node entry = nodes.entry() row += entry value = ot.ResourceMap.Get(key) if not len(value): value = ' '.__repr__() if '\t' in value: value = value.replace('\t', '\\t') node = nodes.paragraph(text=value) entry += node return [table] except Exception: return [nodes.error(None, nodes.paragraph(text="Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text=str(sys.exc_info()[1])))] finally: sys.stdout = oldStdout