def mermaid_to_svg(elem, doc): """ Convert a mermaid snippet to svg """ if isinstance(elem, CodeBlock) and 'mermaid' in elem.classes: code = elem.text filename = md5(code) target = IMAGE_DIR + '/' + filename + '.svg' tmpfn = IMAGE_DIR + '/' + filename if os.path.isfile(target): return Para( Image(Str(''), url=target, title='', attributes={'width': '100%'})) try: os.mkdir(IMAGE_DIR) sys.stderr.write('Created directory ' + IMAGE_DIR + '\n') except OSError: pass with open(tmpfn, 'wb') as tmpfn_f: tmpfn_f.write(code.encode('utf-8')) cmd_line = ['mmdc', '--disable-sandbox', '-i', tmpfn, '-o', target] sys.stderr.write("Running %s\n" % " ".join(cmd_line)) try: p = subprocess.Popen(cmd_line, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: raise RuntimeError('command %r cannot be run (needed for mermaid ' 'output), check the cmd_line setting' % cmd_line) stdout, stderr = p.communicate() if p.returncode != 0: raise RuntimeError('Mermaid exited with error:\n[stderr]\n%s\n' '[stdout]\n%s' % (stderr, stdout)) if not os.path.isfile(target): raise RuntimeError( 'Mermaid did not produce an output file:\n[stderr]\n%s\n' '[stdout]\n%s' % (stderr, stdout)) sys.stderr.write('Created image ' + target + '\n') return Para( Image(Str(''), url=target, title='', attributes={'width': '100%'}))
def gabc(elem, doc): """Handle gabc file inclusion and gabc code block.""" if type(elem) == Code and "gabc" in elem.classes: if doc.format == "latex": if elem.identifier == "": label = "" else: label = '\\label{' + elem.identifier + '}' return latex("\n\\smallskip\n{%\n" + latexsnippet('\\gregorioscore{' + elem.text + '}', elem.attributes) + "%\n}" + label) else: infile = elem.text + ('.gabc' if '.gabc' not in elem.text else '') with open(infile, 'r') as doc: code = doc.read().split('%%\n')[1] return Image( png(elem.text, latexsnippet('\\gregorioscore', elem.attributes))) elif type(elem) == CodeBlock and "gabc" in elem.classes: if doc.format == "latex": if elem.identifier == "": label = "" else: label = '\\label{' + elem.identifier + '}' return latexblock("\n\\smallskip\n{%\n" + latexsnippet('\\gabcsnippet{' + elem.text + '}', elem.attributes) + "%\n}" + label) else: return Para( Image(url=png(elem.text, latexsnippet('\\gabcsnippet', elem.attributes))))
def lily(elem, doc): if type(elem) == Code and 'ly' in elem.classes: staffsize = int(elem.attributes.get('staffsize', '20')) if doc.format == "latex": if elem.identifier == "": label = "" else: label = '\\label{' + elem.identifier + '}' return latex( '\\includely[staffsize=%s]{%s}' % (staffsize, contents) + label ) else: infile = contents + ( '.ly' if '.ly' not in contents else '' ) with open(infile, 'r') as doc: code = doc.read() return Image(url=png(code, staffsize)) if type(elem) == CodeBlock and 'ly' in elem.classes: staffsize = int(elem.attributes.get('staffsize', '20')) if doc.format == "latex": if elem.identifier == "": label = "" else: label = '\\label{' + elem.identifier + '}' return latexblock( '\\lily[staffsize=%s]{%s}' % (staffsize, code) + label ) else: return Para(Image(url=png(code, staffsize)))
def references(): defns = [] for elem in self.links.values(): defns.append( DefinitionItem( [de_code(item, Strong) for item in elem.content], [Definition(Para(Str(elem.url)))], ), ) return DefinitionList(*defns)
def action(elem, doc): if isinstance(elem, CodeBlock): name = get_name(elem) if name is None: return if doc.code_count[name] == 0: label = Span(Emph(Str(f"«{name}»="))) doc.code_count[name] += 1 else: label = Span(Emph(Str(f"«{name}»+"))) return Div(Para(label), elem, classes=["annotated-code"])
def stringify(elem, newlines=True): """ Return the raw text version of an element (and its children elements). Example: >>> e1 = Emph(Str('Hello'), Space, Str('world!')) >>> e2 = Strong(Str('Bye!')) >>> para = Para(e1, Space, e2) >>> stringify(para) 'Hello world! Bye!\n\n' :param newlines: add a new line after a paragraph (default True) """ if isinstance(elem, ListContainer): elem = Para(*elem) return pf.stringify(elem, newlines)
def abc(elem, doc): if type(elem) == CodeBlock and 'abc' in elem.classes: code = elem.text outfile = os.path.join(imagedir, sha1(code)) filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'png') src = outfile + '.' + filetype if not os.path.isfile(src): try: os.mkdir(imagedir) sys.stderr.write('Created directory ' + imagedir + '\n') except OSError: pass abc2eps(code.encode("utf-8"), filetype, outfile) sys.stderr.write('Created image ' + src + '\n') return Para(Image(url=src))
def tikz(elem, doc): if type(elem) == RawBlock and elem.format == "latex": code = elem.text if re.match("\\\\begin{tikzpicture}", code): outfile = imagedir + '/' + sha1(code) filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'png') src = outfile + '.' + filetype if not os.path.isfile(src): try: os.mkdir(imagedir) sys.stderr.write('Created directory ' + imagedir + '\n') except OSError: pass tikz2image(code, filetype, outfile) sys.stderr.write('Created image ' + src + '\n') return Para(Image(url=src))
def generate(self): credentials = self.get_credentials() http = credentials.authorize(httplib2.Http()) data = None if self.config['type'] == 'spreadsheets': template = LATEX_JINJA_ENV.get_template('./gdrive-table.tex') discoveryUrl = 'https://sheets.googleapis.com/$discovery/rest?version=v4' service = discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=discoveryUrl) result = service.spreadsheets().values().get( spreadsheetId=self.config['doc_id'], range=self.config['range']).execute() data = result.get('values', []) output_latex = template.render(data=data, **self.config) return RawBlock(text=output_latex, format="latex") if self.config['type'] == 'drawings': service = discovery.build('drive', 'v3', http=http) results = service.files().get( fileId=self.config['doc_id'], fields='modifiedTime,name').execute() request = service.files().export_media( fileId=self.config['doc_id'], mimeType='application/pdf') file_name = 'gdrive-data/' + self.config['doc_id'] + '.pdf' print(request, file=sys.stderr) with open(file_name, 'wb') as fh: downloader = MediaIoBaseDownload(fh, request) done = False while done is False: status, done = downloader.next_chunk() print(status, done, file=sys.stderr) print("Download %d%%." % int(status.progress() * 100), file=sys.stderr) return Para( Image(Str(''), url=file_name, title=self.config.get('title', ''), attributes={'width': '100%'})) return data
def graphviz(elem, doc): if type(elem) == CodeBlock and 'graphviz' in elem.classes: code = elem.text caption = "caption" G = pygraphviz.AGraph(string=code) G.layout() filename = sha1(code) filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'png') alt = Str(caption) src = imagedir + '/' + filename + '.' + filetype if not os.path.isfile(src): try: os.mkdir(imagedir) sys.stderr.write('Created directory ' + imagedir + '\n') except OSError: pass G.draw(src) sys.stderr.write('Created image ' + src + '\n') return Para(Image(alt, url=source, title=''))
def stripped_quote(elem, _doc): if isinstance(elem, BlockQuote): child_elems = [RawInline(">"), Space()] after_paragraph = False def append(child, _doc): nonlocal child_elems nonlocal after_paragraph if isinstance(child, Inline): if after_paragraph: child_elems += [SoftBreak(), RawInline(">")] * 2 + [ Space() ] child_elems.append(child) if isinstance(child, SoftBreak): child_elems += [RawInline(">"), Space()] after_paragraph = isinstance(child, Para) elem.walk(append) return Para(*child_elems)
def alerts_to_text(elem, _): """ Apply the translations, see module doc """ if not isinstance(elem, Para): return if not isinstance(elem.content[0], Str): return if not isinstance(elem.content[-1], Str): return match1 = re.match(r':::(info|warning|danger|success)', elem.content[0].text) match2 = re.match(r':::', elem.content[-1].text) if match1 and match2: return Para( RawInline('\\begin{infobox' + match1.group(1).title() + '}', format='latex'), *elem.content[2:-2], RawInline('\\end{infobox' + match1.group(1).title() + '}', format='latex'))
def links_to_footnotes(elem, doc): """ Will shift a header level from the filter-header-shift metadata value (which must exist) """ if doc.format != 'latex': return if isinstance(elem, Link): if elem.url.startswith('#'): return if elem.url.startswith('mailto:'): return if elem.url == stringify(elem): return return [ elem, Note( Para(RawInline(stringify(elem), format='tex'), Str(':'), Space(), Link(Str(elem.url), title=elem.title, url=elem.url))) ]
def graphviz(elem, doc): """ Generate a graphviz pdf/png from raw code with a graphviz class """ if isinstance(elem, CodeBlock) and 'graphviz' in elem.classes: code = elem.text graph = pygraphviz.AGraph(string=code) title = graph.graph_attr.pop('label', '') # graph.graph_attr.update(margin=0) graph.layout() filename = md5(code) filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'pdf') src = IMAGE_DIR + '/' + filename + '.' + filetype if not os.path.isfile(src): try: os.mkdir(IMAGE_DIR) sys.stderr.write('Created directory ' + IMAGE_DIR + '\n') except OSError: pass graph.draw(src, prog='dot') sys.stderr.write('Created image ' + src + '\n') return Para(Image(Str(''), url=src, title=title, attributes={'width': '100%'}))
def test_span(self): doc = Doc( Para( Span(classes=["tip", "listing"]), Span(classes=["tip"]), Span(classes=["warning"]), Span(classes=["v5.0"]), Span( attributes={ "latex-tip-icon": "warning", "latex-tip-position": "right", "latex-tip-size": 24, }), ), metadata=self.metadata(), format="latex", ) pandoc_latex_tip.main(doc) self.assertEqual(doc.content[0].content[1].format, "tex") self.assertEqual(doc.content[0].content[3].format, "tex") self.assertEqual(doc.content[0].content[5].format, "tex") self.assertEqual(doc.content[0].content[7].format, "tex") self.assertEqual(doc.content[0].content[9].format, "tex")
def plantuml(elem, doc): if type(elem) == CodeBlock and 'plantuml' in elem.classes: if 'caption' in elem.attributes: caption = [Str(elem.attributes['caption'])] typef = 'fig:' else: caption = [] typef = '' filetype = {'html': 'svg', 'latex': 'eps'}.get(doc.format, 'png') src = os.path.join(imagedir, filename + '.uml') dest = os.path.join(imagedir, filename + '.' + filetype) if not os.path.isfile(dest): try: os.mkdir(imagedir) sys.stderr.write('Created directory ' + imagedir + '\n') except OSError: pass txt = code.encode("utf-8") if not txt.startswith("@start"): txt = "@startuml\n" + txt + "\n@enduml\n" with open(src, "w") as f: f.write(txt) call(["java", "-jar", "plantuml.jar", "-t" + filetype, src]) sys.stderr.write('Created image ' + dest + '\n') return Para( Image(*caption, identifier=elem.identifier, attributes=elem.attributes, url=dest, title=typef))
def test_code(self): doc = Doc( Para( Code("", classes=["tip", "listing"]), Code("", classes=["tip"]), Code("", classes=["warning"]), Code( "", attributes={ "latex-tip-icon": "warning", "latex-tip-position": "right", "latex-tip-size": 24, }, ), ), metadata=self.metadata(), format="latex", api_version=(1, 17, 2), ) pandoc_latex_tip.main(doc) self.assertEqual(doc.content[0].content[1].format, "tex") self.assertEqual(doc.content[0].content[3].format, "tex") self.assertEqual(doc.content[0].content[5].format, "tex") self.assertEqual(doc.content[0].content[7].format, "tex")
def caps(elem, doc): data = getJson('data.json') if isinstance(elem, pf.RawBlock) and (elem.format == 'html'): if elem.text == "<!-- feedback -->": feedback = data[data['subject']+str(data['questionNumber'])] body = [] i=0 for item in feedback: cells = [str(i+1),item] cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells] row = pf.TableRow(*cells) body.append(pf.TableBody(row)) i=i+1 cells = ['Nr.','Empfehlung'] cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells] row = pf.TableRow(*cells) head = pf.TableHead(row) width = [0.1,0.7] alignment = ['AlignDefault'] * len(width) caption = 'Empfehlungen' caption = pf.Caption(Para(Str(caption))) return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption)) if elem.text == "<!-- textelementen -->": subject = data[data['subject']+str(data['questionNumber'])+'_cna'] body = [] i=0 for item in subject: cells = [item[0], item[1]] cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells] row = pf.TableRow(*cells) body.append(pf.TableBody(row)) i=i+1 cells = ['Abschnitt','Schlusselwörter'] cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells] row = pf.TableRow(*cells) head = pf.TableHead(row) width = [0.16,0.7] alignment = ['AlignDefault'] * len(width) caption = 'Textelementen' caption = pf.Caption(Para(Str(caption))) return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption)) if elem.text == "<!-- unterschied -->": expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword'] student = data[data['subject']+str(data['questionNumber'])+'_keyword'] sorted_expert = sorted(expert, key = lambda k:k['degree']) sorted_student = sorted(student, key = lambda k:k['degree']) unterschied = [] for e in expert: unterschied.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")") for e in expert: inside = True for s in student: if e['displayName'] == s['displayName']: inside= False break if not inside: unterschied.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")") break string ='' if len(unterschied) == 1: string+= str(unterschied[0]) elif len(unterschied)>1: string = unterschied[0] for index in range(1, len(unterschied)-1): string +=', '+ str(unterschied[index]) body = [] cells = [string] cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells] row = pf.TableRow(*cells) body.append(pf.TableBody(row)) width = [0.8] alignment = ['AlignDefault'] * len(width) caption = 'Textelementen' caption = pf.Caption(Para(Str(caption))) return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption)) if elem.text == "- gemeinsam -": expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword'] student = data[data['subject']+str(data['questionNumber'])+'_keyword'] sorted_expert = sorted(expert, key = lambda k:k['degree']) sorted_student = sorted(student, key = lambda k:k['degree']) gemeinsam = [] for e in expert: for s in student: if e['displayName'] == s['displayName']: gemeinsam.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")") break else: continue break string ='' gemeinsam = [x["displayName"]+"("+str(round(float(x["degree"])*100, 2))+")" for x in expert+student if (any(e['displayName'])==x['displayName'] for e in expert) and (any(s['displayName'])==x['displayName'] for s in student)] if len(gemeinsam) == 1: string+= gemeinsam[0] elif len(gemeinsam)>1: string = gemeinsam[0] for index in range(1, len(gemeinsam)-1): string +=', '+ gemeinsam[index] return string if type(elem) == Str: if elem.text == "-topicName-": subject = data['subject'] +" Frage nummer " + str(data['questionNumber']) elem.text = subject return elem if elem.text == "-textelementen-": subject = data[data['subject']+str(data['questionNumber'])+'_cna'] subject = subject.replace("_", " ") elem.text = subject return elem if elem.text == "-question_number-": feedback = str(data['questionNumber']) elem.text = feedback return elem if elem.text == "-gemeinsam-": expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword'] student = data[data['subject']+str(data['questionNumber'])+'_keyword'] sorted_expert = reversed(sorted(expert, key = lambda k:k['degree'])) sorted_student = reversed(sorted(student, key = lambda k:k['degree'])) string ='' list_of_all_values = [value for elem in sorted_student for value in elem.values()] gemeinsam = [x["displayName"] for x in sorted_expert if x['displayName'] in list_of_all_values] if len(gemeinsam) == 1: string+= gemeinsam[0] elif len(gemeinsam)>1: string = gemeinsam[0] for index in range(1, len(gemeinsam)-1): string +=', '+ gemeinsam[index] elem.text = string return elem if elem.text == "-unterschied1-": expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword'] student = data[data['subject']+str(data['questionNumber'])+'_keyword'] sorted_expert = reversed(sorted(expert, key = lambda k:k['degree'])) sorted_student = reversed(sorted(student, key = lambda k:k['degree'])) string ='' list_of_all_values = [value for elem in sorted_student for value in elem.values()] gemeinsam = [x["displayName"] for x in sorted_expert if x['displayName'] not in list_of_all_values] if len(gemeinsam) == 1: string+= gemeinsam[0] elif len(gemeinsam)>1: string = gemeinsam[0] for index in range(1, len(gemeinsam)-1): string +=', '+ gemeinsam[index] elem.text = string return elem if elem.text == "-unterschied2-": expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword'] student = data[data['subject']+str(data['questionNumber'])+'_keyword'] sorted_expert = reversed(sorted(expert, key = lambda k:k['degree'])) sorted_student = reversed(sorted(student, key = lambda k:k['degree'])) string ='' list_of_all_values = [value for elem in sorted_expert for value in elem.values()] gemeinsam = [x["displayName"] for x in sorted_student if x['displayName'] not in list_of_all_values] if len(gemeinsam) == 1: string+= gemeinsam[0] elif len(gemeinsam)>1: string = gemeinsam[0] for index in range(1, len(gemeinsam)-1): string +=', '+ gemeinsam[index] elem.text = string return elem if elem.text == "-expert-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_expert_keyword.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_expert_keyword.png'): return None return Image(alt, url=src, title='') if elem.text == "-student-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_keyword.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_keyword.png'): return None return Image(alt, url=src, title='') if elem.text == "-content-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content.png'): return None return Image(alt, url=src, title='') if elem.text == "-heat-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content_heat.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content_heat.png'): return None return Image(alt, url=src, title='') if elem.text == "-topic-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_topic.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_topic.png'): return None return Image(alt, url=src, title='') if elem.text == "-argument-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_argument.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_argument.png'): return None return Image(alt, url=src, title='') if elem.text == "-wordtovec-": caption = "caption" src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_word2vec.png' alt = Str(caption) if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_word2vec.png'): return None return Image(alt, url=src, title='')
def plantuml(elem, doc): if type(elem) == CodeBlock and 'plantuml' in elem.classes: filename = sha1(elem.text) filetype = {'html': 'svg', 'latex': 'eps'}.get(doc.format, 'png') src = os.path.join(IMAGEDIR, filename + '.uml') dest = os.path.join(IMAGEDIR, filename + '.' + filetype) dest_dir = pathlib.Path(IMAGEDIR) if not os.path.isfile(dest): try: os.mkdir(IMAGEDIR) sys.stderr.write('Created directory ' + IMAGEDIR + '\n') except OSError: pass txt = elem.text if not txt.startswith("@start"): txt = "@startuml\n" + txt + "\n@enduml\n" with open(src, "w", encoding=DEFAULT_CODE, errors='ignore') as f: f.write(txt) args = ["java"] args.extend(["-Dfile.encoding=UTF-8"]) args.extend(get_include_path_arg(get_include_path( elem.attributes))) args.extend(["-jar", get_plantuml_jar()]) args.extend(["-charset", "UTF-8"]) args.append("-t" + filetype) args.append(src) call(args) #sys.stderr.write('Created image ' + dest + '\n') dest_files = sorted(dest_dir.glob(filename + '*.' + filetype)) parts = [] for i, image in enumerate(dest_files): rel = image.relative_to(dest_dir) sys.stderr.write('Created image {} - {}\n'.format( i + 1, os.path.join(dest_dir.name, rel))) dest_image = str(image) basename = image.with_suffix('').name suffix = basename[len(filename):] head = get_header(elem.attributes, suffix) if head: parts.append(head) caption, typef = get_caption_attribute(elem.attributes, suffix) if i == 0: im = Image(*caption, identifier=elem.identifier, attributes=elem.attributes, url=dest_image, title=typef) identities.add(elem.identifier) else: ident = SPLIT_DIAGRAM_NAME_FORMAT.format( elem.identifier, suffix) new_ident = make_new_ident(ident) identities.add(new_ident) im = Image(*caption, identifier=new_ident, attributes=elem.attributes, url=dest_image, title=typef) parts.append(Para(im)) return parts elif hasattr(elem, "identifier"): if elem.identifier: identities.add(elem.identifier)
def tobullet(item): ans = [Para(Strong(*item.term))] for definition in item.definitions: for block in definition.content: ans.append(block) return ListItem(*ans)