def parse(value): output = None meta = {'value': value, 'cmd': None, 'in': None, 'out': None, 'img': None} try: meta['tag'] = value[0][1][0] except IndexError: return None if meta['tag'] != MARKDOWN_TAG_NAME: return None meta['body'] = os.linesep.join(value[1].strip().split(os.linesep)) for param in value[0][2]: if len(param) != 2 or not param[0] in meta: return None meta[param[0]] = param[1].strip() if meta['out'] != 'text' and meta['out'] != 'image': return None if meta['in'] == 'script': output = toScript(meta) elif meta['in'] == 'shell': output = toShell(meta) else: return None [[ident, classes, keyvals], code] = value if meta['out'] == 'text': return CodeBlock([ident, classes, keyvals], output) imgPath = None if meta['img'] is None: imgPath = toImageFromText(meta, output) else: imgPath = toImage(meta) if not imgPath is None: imgPath = adjustImagePath(imgPath) if imgPath is None: return None return [Para([Image([ident, classes, keyvals], [], [imgPath, "fig:"])])]
def addCodeClass(key, value, _, meta): if key == 'CodeBlock': [[ident, classes, keyvals], code] = value if "python" in classes: classes.remove("python") classes.append("code") return CodeBlock([ident, classes, keyvals], code)
def sage_output_format(text): return CodeBlock([u'', [u'json', u'output'], []], json.dumps([{ 'name': 'stdout', 'output_type': 'stream', 'text': text }]))
def include_code(key, value, format, _): if key == 'CodeBlock': [[ident, classes, keyvals], code] = value if "include-code" in classes: rv = [] for l in code.splitlines(): l = l.strip() (filename, ext) = os.path.splitext(l) ext = ext.replace(".", "") # Overide the file extension if we are given # a language keyval (givenExt, value) = get_value(keyvals, u"language") if str(givenExt) != "None": ext = str(givenExt) if os.path.isfile(l): with open(l, "r") as f: contents = f.read() rv.append(CodeBlock(["", [ext], []], contents)) else: sys.stderr.write("WARNING: Can't read file '" + l + "'. Skipping.") return rv
def yml_to_yaml(key, val, fmt, meta): if key == 'CodeBlock': [[indent, classes, keyvals], code] = val if len(classes) > 0: if classes[0] == u'yml': classes[0] = u'yaml' val = [[indent, classes, keyvals], code] return CodeBlock(val[0], val[1])
def plain_output(text: str, pandoc_format: str = "markdown", pandoc_extra_args: list = None, pandoc: bool = False) -> list: if pandoc: return tokenize_block(text, pandoc_format, pandoc_extra_args) else: return [Div(['', ['output'], []], [CodeBlock(['', [], []], text)])]
def gitdiff(key, value, format, meta): if key == "CodeBlock": [[ident, classes, keyvals], contents] = value if "git-diff" in classes: folder = "." commra = "" obj = "" objdiv = "" options = "" # its a diff - view if not "diff" in classes: classes.append("diff") for el in keyvals: if "commit-range" in el: commra = el[1] if "dir" in el: folder = el[1] if "objects" in el or "object" in el: objdiv = "--" obj = "%s %s" % (obj, el[1]) if "diffoptions" == el[0]: options = el[1] command_string = "git -C %s diff %s %s %s %s" % ( folder, options, commra, objdiv, obj) out = "" try: l = list(filter(None, command_string.split(" "))) out = subprocess.check_output(l) except subprocess.CalledProcessError as err: return None if out != None or out != "": out = out.decode("utf-8") return [ CodeBlock([ident, classes, keyvals], out), CodeBlock([ident, classes, keyvals], contents) ] else: return None
def code_include(key, value, format, meta): if key == 'CodeBlock': [[ident, classes, namevals], code] = value if code.startswith('!!include='): source_file = code.split('=')[1] with open(source_file, 'rb') as content_file: content = content_file.read() content.decode('utf-8') return CodeBlock([ident, classes, namevals], content)
def sage_output_format(text): return CodeBlock([u'', [u'json', u'output'], []], json.dumps([{ 'data': { 'text/plain': text }, 'execution_count': 1, 'metadata': {}, 'output_type': 'execute_result' }]))
def process(value, format): [[ident, classes, keyvals], code] = value if "graphviz" in classes: caption, typef, keyvals = get_caption(keyvals) filetype = get_extension(format, "png", html="png", latex="pdf") dest = get_filename4code("graphviz", code, filetype) if not os.path.isfile(dest): import pygraphviz g = pygraphviz.AGraph(string=code) g.layout() g.draw(dest) print1('INFO', 'Created image ' + dest + '\n') return Para([Image([ident, [], keyvals], caption, [dest, typef])]) elif "standalone" in classes: caption, typef, keyvals = get_caption(keyvals) filetype = get_extension(format, "png", html="png", latex="pdf") dest = get_filename4code("standalone", code, filetype) if not os.path.isfile(dest): success = gen_standalone(code, dest) if not success: return Para( [Str(">>> Error: This image could not be generated.")]) return Para([Image([ident, [], keyvals], caption, [dest, typef])]) elif "include" in classes: caption, typef, keyvals = get_caption(keyvals) keyvalDict = dict(keyvals) listing = '' with open(keyvalDict['src'], 'r') as f: listing = f.read() lang = keyvalDict.get('lang', 'python') code = 'Failed to find any listing.' if 'start' in keyvalDict: # Assume that both start and end are line numbers. start = int(keyvalDict['start']) end = int(keyvalDict['end']) code = '\n'.join(listing.split('\n')[start:end]) elif 'pat' in keyvalDict: pat = r'%s' % keyvalDict['pat'] print1(pat) m = re.search(pat, listing, re.DOTALL) if m: code = m.group(0) else: code = "Pattern '%s' not found in '%s'" % (pat, keyvalDict['src']) else: code = 'No listing found.' return CodeBlock([ident, [], keyvals], code)
def ignore(key, value, _, meta): if key == 'CodeBlock': [[ident, classes, keyvals], code] = value if "ignore" in classes: return Null() # return Null block return CodeBlock(*value) if key == 'Image': [ident, classes, keyvals], caption, [dest, typef] = value if "ignore" in classes: return Str("") # return empty string. Cannot return Block here. return Image(*value)
def includes(key, value, format_, meta): ''' If a CodeBlock has the attribute "include", replace the contents of the CodeBlock with the contents of the file given. ''' if key == 'CodeBlock': [id_, classes, namevals], contents = value for i in namevals: key, val = i if key == "include": with open(val, 'r') as f: data = f.read() return CodeBlock([id_, classes, namevals], data)
def listing(key, value, format, meta): #eprint("Key: " + key) if key == 'CodeBlock': (caption, _) = get_value(value[0][2], 'caption') if caption is None: return block = CodeBlock(value[0], value[1]) # we only need to add the caption, label is handled by Pandoc return \ [ Plain([latex(r'\begin{listing}' + '\n' + \ r'\caption{' + caption + '}')]) \ , block \ , Plain([latex(r'\end{listing}')]) \ ]
def caps(key, value, format, meta): if key == "CodeBlock": properties = value[0] attributes = properties[2] # this signifies python codeblock if ['frame', 'leftline'] in attributes: # set 'python' class properties[1] = ['python'] else: # set 'terminal' class properties[1] = ['terminal'] # unset attrs properties[2] = [] value[0] = properties #log(str(value)) return CodeBlock(*value)
def caps(key, value, format, meta): if key == 'CodeBlock': [[ident, classes, kvs], contents] = value if "include" in classes: blocks = [] for file in filter(None, map(str.strip, contents.split("\n"))): try: with open(file) as f: data = f.read() except: data = f"Could not read '{file}'" try: obj = json.loads( subprocess.check_output(["pandoc", file, "-t", "json"])) except subprocess.CalledProcessError: blocks.append(f"Could not process file '{file}") else: blocks.extend(obj["blocks"]) return blocks return CodeBlock([ident, classes, kvs], contents)
def include_examples(key, value, format, meta): """ Replace code block sections with the code from a file. The filename doesn't use the extension in the include string, although the file must be a python file, with the .py extension. Code blocks look like: ~~~~ {include="filename"} ~~~~ """ # pandoc encounters a CodeBlock in the markdown file. if key == 'CodeBlock': # Unpack the values in the CodeBlock. # 'classes' is the name of the programming language. # 'namevals' is a list of the nameval and its value. # 'code' is content inside the CodeBlock. [[ident, classes, namevals], code] = value # Since all CodeBlocks contain python code, we won't define the class # in the markdown as {.python ...}, instead we set the classes here. classes = ['python'] # Find the file, and place its contents into a CodeBlock element. for nameval in namevals: # Check the nameval of the CodeBlock, which looks like, # include="filename" if nameval[0] == 'include': # Get content from the file, or log a message of the file that # cannot be found. content = _get_file_content(nameval[1]) if content is not None: # Return the CodeBlock with the new content. return CodeBlock([ident, classes, namevals], content) else: # Emit message. [Check correctness of file and path names.] logging.error("ERROR cant find file: {}".format( nameval[1]))
def process_codeblock( self, value: Tuple[Tuple[str, List[str], Dict[str, str]], str], output_format: str, meta: Dict[str, str]) -> Any: # pylint: disable=unused-argument """Fenced blocks are code blocks.""" [[ident, classes, keyvals], code] = value for graphviz_class in ["dot", "neato", "twopi", "circo", "fdp"]: if graphviz_class in classes: caption, typef, keyvals = get_caption(keyvals) if output_format in PANDOC_HTML_FORMATS: _, relpath = self.generate_file( graphviz_class, code, "svg") image_ref = self.temp_link + relpath else: image_ref, _ = self.generate_file( graphviz_class, code, "png") return Para( [Image([ident, [], keyvals], caption, [image_ref, typef])]) if "graphviz" in classes: new_classes = [ "dot" if cls == "graphviz" else cls for cls in classes] return CodeBlock([ident, new_classes, keyvals], code) return None
def code(key, value, format, meta): # pylint: disable=unused-argument,redefined-builtin """Handle python/console code blocks.""" if key == "CodeBlock": properties = value[0] attributes = properties[2] # this signifies python codeblock if ['frame', 'leftline'] in attributes: # set 'python' class properties[1] = ['python'] else: # set class # - for markdown: use 'terminal' # - for rst: use 'console' properties[1] = ['console'] # unset attrs properties[2] = [] value[0] = properties #log(str(value)) return CodeBlock(*value)
def getcode(key,value,format,_): if key == 'CodeBlock' or key == 'RawBlock': mm,t = value return CodeBlock(mm,t) elif key in ['Para','OrderedList','Header']: return Para([Space()])
def insertfile(key, value, fmt, meta): if key == 'CodeBlock': [[ident, classes, kvs], code] = value kv = {key: value for key, value in kvs} if "include" in kv: if "git" in kv: repo = git.Repo(os.path.abspath(kv["include"]), search_parent_directories=True) gitpath = repo.working_tree_dir filepath = os.path.abspath(kv["include"]) relpath = os.path.relpath(filepath, gitpath) try: contents = repo.git.show(":".join([kv["git"], relpath])) lines = contents.splitlines(True) except git.exc.GitCommandError: eprint("cannot include file:", "git tag error", kv["git"], "for file:", kv["include"]) return None elif os.path.isfile(kv["include"]): lines = [line for line in open(kv["include"])] else: eprint("cannot include file:", "file not found:", kv["include"]) return None start = 0 stop = len(lines) if "start" in kv: start = int(kv["start"]) - 1 if "match" in kv: eprint("use of *match* is deprecated, use *start* instead") patt = re.compile(kv["match"]) for l in range(start, stop): if patt.search(lines[l]): start = l break if "lines" in kv: nr_lines = int(kv["lines"]) if nr_lines >= 0 and start + nr_lines < stop: stop = start + nr_lines if "pars" in kv: eprint( "use of *pars* is deprecated, use *stop* or *lines* instead" ) nr_pars = int(kv["pars"]) between_pars = False for l in range(start, stop): if lines[l].isspace(): if not between_pars: between_pars = True nr_pars -= 1 if nr_pars <= 0: stop = l break else: between_pars = False if "stop" in kv: stop = int(kv["stop"]) # now select lines data = "".join(lines[start:stop]) if "dedent" in kv and kv["dedent"] == "y": data = dedent(data) return CodeBlock([ident, classes, kvs], data) return None
def plain_output(text): block = Div(['', ['output'], []], [CodeBlock(['', [], []], text)]) return block
def python_input_format(text): return CodeBlock([u'', [u'rython', u'input'], []], text)
def pre(key, value, fmt, meta): if key == 'CodeBlock': [[ident,classes,keyvals], code] = value return [CodeBlock([ident, classes, keyvals], c) for c in code.split('\n')]