def finalize(doc): c1 = pf.TableCell(pf.Plain(pf.Str("Element"))) c2 = pf.TableCell(pf.Plain(pf.Str("Frequency"))) header = pf.TableRow(c1, c2) rows = [] for tag in doc.counter: c1 = pf.TableCell(pf.Plain(pf.Str(tag))) c2 = pf.TableCell(pf.Plain(pf.Str(str(doc.counter[tag])))) rows.append(pf.TableRow(c1, c2)) table = pf.Table(*rows, header=header) doc.content = [table] # bugbug?
def action(elem, doc): # Parse git links in a plain text line or a text paragraph if isinstance(elem, (pf.Para, pf.Plain)): newelem = elem.__class__() if getgitlink(elem, newelem) == '': return newelem else: return elem # Parse git links in a table row: fix problem where git links formatted # like [[text|link]] are spread over two table cells elif isinstance(elem, pf.TableRow): newelem = pf.TableRow() newcell = pf.TableCell() linkstr = '' for cell in elem.content: if len(newcell.content) == 0: newcell.content.append(cell.content[0].__class__()) if len(linkstr) > 0: linkstr += '|' linkstr = getgitlink(cell.content[0], newcell.content[0], linkstr) if not linkstr: newelem.content.append(newcell) newcell = pf.TableCell() return newelem
def parse_table_list(markdown, table_list): """read table in list and return panflute table format """ def markdown_to_table_cell(string): return panflute.TableCell(*panflute.convert_text(string)) def plain_to_table_cell(string): return panflute.TableCell(panflute.Plain(panflute.Str(string))) to_table_cell = markdown_to_table_cell if markdown else plain_to_table_cell return [panflute.TableRow(*map(to_table_cell, row)) for row in table_list]
def fenced_action(options, data, element, doc): # We'll only run this for CodeBlock elements of class 'csv' title = options.get('title', 'Untitled Table') title = [pf.Str(title)] has_header = options.get('has-header', False) with io.StringIO(data) as f: reader = csv.reader(f) body = [] for row in reader: cells = [pf.TableCell(pf.Plain(pf.Str(x))) for x in row] body.append(pf.TableRow(*cells)) header = body.pop(0) if has_header else None table = pf.Table(*body, header=header, caption=title) return table
def test_all(): x=pf.Para(pf.Str("a")) y=pf.Para(pf.Str("b")) c1=pf.TableCell(x) c2=pf.TableCell(y) row=pf.TableRow(c1,c2) t1 = pf.Table(row) t2 = pf.Table(row, header=row) print(t1.header) print(t2.header) with io.StringIO() as f: pf.dump(pf.Doc(t1), f) print(f.getvalue()) with io.StringIO() as f: pf.dump(pf.Doc(t2), f) print(f.getvalue())
def proc_csv_table(elm, doc): if type(elm) == pf.CodeBlock and 'csv-table' in elm.classes: sys.stderr.write('csv-table #' + elm.identifier + '\n') attr = elm.attributes caption = attr.get('caption', None) if 'caption' in attr: del attr['caption'] alignment = attr.get('alignment', None) if 'alignment' in attr: del attr['alignment'] width = attr.get('width', None) if 'width' in attr: del attr['width'] with io.StringIO(elm.text.replace('\r\n', '\n')) as dat: reader = csv.reader(dat, dialect=csv.excel, strict=True) body = [] for row in reader: cells = [pf.TableCell(pf.Plain(pf.Str(x))) for x in row] body.append(pf.TableRow(*cells)) if 'header' in attr: header = body.pop(0) del attr['header'] else: header = None return pf.Div( # content pf.Table(*body, header=header, caption=caption, alignment=alignment, width=width), identifier=elm.identifier, classes=elm.classes, attributes=attr)
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 cmptable(table, doc): """ Comparison Tables: Code blocks are the first-class entities that get added to the table. Each code block is pushed onto the current row. A horizontal rule (`---`) is used to move to the next row. In the first row, the last header (if any) leading upto the i'th code block is the header for the i'th column of the table. The last block quote (if any) is used as the caption. # Example ::: cmptable > compare inspect of unconstrained and constrained types ### Before ```cpp std::visit([&](auto&& x) { strm << "got auto: " << x; }, v); ``` ### After ```cpp inspect (v) { <auto> x: strm << "got auto: " << x; } ``` --- ```cpp std::visit([&](auto&& x) { using X = std::remove_cvref_t<decltype(x)>; if constexpr (C1<X>()) { strm << "got C1: " << x; } else if constexpr (C2<X>()) { strm << "got C2: " << x; } }, v); ``` ```cpp inspect (v) { <C1> c1: strm << "got C1: " << c1; <C2> c2: strm << "got C2: " << c2; } ``` ::: # Generates Table: compare inspect of unconstrained and constrained types +------------------------------------------------+---------------------------------------------+ | __Before__ | __After__ | +================================================+=============================================+ | ```cpp | ```cpp | | std::visit([&](auto&& x) { | inspect (v) { | | strm << "got auto: " << x; | <auto> x: strm << "got auto: " << x; | | }, v); | } | | | ``` | +------------------------------------------------+---------------------------------------------+ | std::visit([&](auto&& x) { | ```cpp | | using X = std::remove_cvref_t<decltype(x)>; | inspect (v) { | | if constexpr (C1<X>()) { | <C1> c1: strm << "got C1: " << c1; | | strm << "got C1: " << x; | <C2> c2: strm << "got C2: " << c2; | | } else if constexpr (C2<X>()) { | } | | strm << "got C2: " << x; | ``` | | } | | | }, v); | | +------------------------------------------------+---------------------------------------------+ """ if not isinstance(table, pf.Div): return None if not any(cls in table.classes for cls in ['cmptable', 'tonytable']): return None rows = [] kwargs = {} headers = [] widths = [] examples = [] header = pf.Null() caption = None width = 0 first_row = True table.content.append(pf.HorizontalRule()) def warn(elem): pf.debug('mpark/wg21:', type(elem), pf.stringify(elem, newlines=False), 'in a comparison table is ignored') for elem in table.content: if isinstance(elem, pf.Header): if not isinstance(header, pf.Null): warn(header) if first_row: header = pf.Plain(*elem.content) width = float(elem.attributes['width']) if 'width' in elem.attributes else 0 else: warn(elem) elif isinstance(elem, pf.BlockQuote): if caption is not None: warn(caption) caption = elem elif isinstance(elem, pf.CodeBlock): if first_row: headers.append(header) widths.append(width) header = pf.Null() width = 0 examples.append(elem) elif isinstance(elem, pf.HorizontalRule) and examples: first_row = False rows.append(pf.TableRow(*[pf.TableCell(example) for example in examples])) examples = [] else: warn(elem) if not all(isinstance(header, pf.Null) for header in headers): kwargs['header'] = pf.TableRow(*[pf.TableCell(header) for header in headers]) if caption is not None: kwargs['caption'] = caption.content[0].content kwargs['width'] = widths return pf.Table(*rows, **kwargs)
def action(element, doc): """ return None -> element unchanged return [] -> delete element """ if not isinstance(element, pf.Div): return None if not "divtable" in element.classes: return None rows = [] headers = [] header_found = False widths = [] aligns = [] caption = None for tbl_el in element.content: if isinstance(tbl_el, pf.Div) and "thead" in tbl_el.classes: headers = [] assert isinstance( tbl_el.content[0], pf.Para), "the table header div must contain a paragraph" for head_el in tbl_el.content[0].content: if isinstance(head_el, pf.Span): if list(head_el.content): header_found = True headers.append(pf.TableCell(pf.Plain(*head_el.content))) if "width" in head_el.attributes: widths.append(float(head_el.attributes["width"])) else: widths.append(0) if "align" in head_el.attributes: align = str(head_el.attributes["align"]).capitalize() assert align in [ "Left", "Right", "Center", "Default" ], "table alignment must be one of left, right, center or default" aligns.append("Align" + align) else: aligns.append("AlignDefault") elif isinstance(tbl_el, pf.Div) and "tcaption" in tbl_el.classes: assert isinstance( tbl_el.content[0], pf.Para), "the table caption div must contain a paragraph" caption = list(tbl_el.content[0].content) elif isinstance(tbl_el, pf.Div) and "trow" in tbl_el.classes: row = [] for row_el in tbl_el.content: if isinstance(row_el, pf.Div) and "tcell" in row_el.classes: col = [] for col_el in row_el.content: col.append(col_el) row.append(pf.TableCell(*col)) rows.append(pf.TableRow(*row)) else: pass kwargs = {} if header_found: kwargs["header"] = pf.TableRow(*headers) if widths: kwargs["width"] = widths if aligns: kwargs["alignment"] = aligns if not caption is None: kwargs["caption"] = caption return pf.Table(*rows, **kwargs)
def convert(self): doc = panflute.Doc( api_version=(1, 17, 5), metadata={ 'pagetitle': self.title, }, ) doc.content.append(panflute.Header(panflute.Str(self.title))) lists = {} tables = {} table_rows = {} table_cells = {} for chunk in self._attr_chunks(): self.logger.debug(chunk) container = panflute.Para() cdiv = panflute.Div(container) # Handle lists if 'list_class' in chunk[0]['attrs']: lc = chunk[0]['attrs']['list_class'] check_state = None if lc in ['checked', 'unchecked']: check_state = lc lc = 'checklist' ld = chunk[0]['attrs']['list_depth'] # prune any lists that are lower than us, they're finished for i in list(lists.keys()): if i > ld: lists.pop(i) # non-homogenous list types can be immediately adjacent without # ending up merged if ld in lists and lists[ld]['class'] != lc: lists.pop(ld) # checklists are a special case, they can't contain other lists if lc != 'checklist' and lists and lists[1][ 'class'] == 'checklist': lists = {} # make sure any intermediate lists were created, including # the top level because boxnotes for i in range(1, ld + 1): if i not in lists: lists[i] = self._list(lc, i) if i != ld: lists[i]['pf'].content.append(panflute.ListItem()) lp = lists[i]['pf'] if lc == 'checklist': lp = panflute.Div(lp, classes=['checklist']) if i == 1: doc.content.append(lp) else: lists[i - 1]['pf'].content[-1].content.append(lp) # set the container for the other subchunks container = panflute.Plain() cdiv.content = [container] cdiv.classes.append(lc) if check_state: cdiv.classes.append(check_state) lists[ld]['pf'].content.append(panflute.ListItem(cdiv)) if check_state == 'checked': container.content.append(panflute.Str(CHECKED)) elif check_state == 'unchecked': container.content.append(panflute.Str(UNCHECKED)) elif 'table_id' in chunk[-1]['attrs']: table_id = chunk[-1]['attrs']['table_id'] row_id = chunk[-1]['attrs']['table_row'] cell_id = row_id + chunk[-1]['attrs']['table_col'] if table_id not in tables: # There's some magic in the constructor for panflute tables # that isn't exposed in any other way, so we can't create # the table until we've finished populating the rows. # Instead, use a placeholder div to locate it within the # document. tables[table_id] = { 'div': panflute.Div(), 'rows': [], } doc.content.append(tables[table_id]['div']) if row_id not in table_rows: table_rows[row_id] = panflute.TableRow() tables[table_id]['rows'].append(table_rows[row_id]) if cell_id not in table_cells: cdiv = panflute.Div(panflute.Plain()) table_cells[cell_id] = panflute.TableCell(cdiv) table_rows[row_id].content.append(table_cells[cell_id]) container = table_cells[cell_id].content[0].content[0] else: lists = {} doc.content.append(cdiv) if 'align' in chunk[0]['attrs']: cdiv.attributes['style'] = 'text-align: ' + chunk[0]['attrs'][ 'align'] + ';' for subchunk in chunk: if subchunk['newlines'] > 1: # we've had an extra linebreak, no more adding on to lists lists = {} # don't do anything with markers if subchunk['text'] == '*' and 'lmkr' in subchunk['attrs']: continue scont = container if 'href' in subchunk['attrs']: scont = panflute.Link(url=subchunk['attrs']['href']) container.content.append(scont) if 'image' in subchunk['attrs']: scont.content.append( panflute.Image( url=self._image(subchunk['attrs']['author'], subchunk['attrs']['image']))) continue span = panflute.Span() lines = subchunk['text'].splitlines() while lines: subtext = lines.pop(0) span.content.append(panflute.Str(subtext)) if lines: span.content.append(panflute.LineBreak()) if 'font' in subchunk['attrs']: color = subchunk['attrs']['font'].get('color', '000000') size = subchunk['attrs']['font'].get('size', 'medium') span.classes.append('font-size-' + size) span.classes.append('font-color-' + color) # I don't actually know what the possible colors are and I # don't feel like finding out, so just inject it as an # inline style. if color != '000000': span.attributes['style'] = 'color: #' + color + ';' if subchunk['attrs'].get('underline'): span.classes.append('underline') if subchunk['attrs'].get('bold'): span = panflute.Strong(span) if subchunk['attrs'].get('italic'): span = panflute.Emph(span) if subchunk['attrs'].get('strikethrough'): span = panflute.Strikeout(span) scont.content.append(span) # Actually create the tables for x in tables: tables[x]['div'].content.append(panflute.Table(*tables[x]['rows'])) with io.StringIO() as f: panflute.dump(doc, f) return f.getvalue()
def build_row(elems): return pf.TableRow(*[pf.TableCell(elem) for elem in elems])
def columns(elem, doc): ## Desactivar para pandoc nuevo if type( elem ) == pf.Div and 'columns' in elem.classes and not doc.pandoc_columns: ## Eliminar de elem.classes if doc.disable_columns: elem.classes.remove('columns') doc.column_count = 0 doc.prev_column = None #pf.debug("Entra") ## Process column attributes if "width" in elem.attributes: doc.columns_width = Dimension(elem.attributes["width"]) else: doc.columns_width = Dimension("600px") if "colsep" in elem.attributes: doc.columns_sep = Dimension(elem.attributes["colsep"]) else: doc.columns_sep = Dimension("0pt") to_patch = doc.columns_to_patch ## Keep track of object doc.columns_to_patch = [] ## Clean columns to patch if doc.format == 'beamer': left = pf.RawBlock('\\begin{columns}', format='latex') right = pf.RawBlock('\\end{columns}', format='latex') if doc.columns_sep.width != 0: rep_text = '\\hspace{' + doc.columns_sep.to_latex() + '}' else: rep_text = '% no sep' for col in to_patch: col.text = col.text.replace("COLSEP", rep_text) elem.content = [left] + list(elem.content) + [right] return elem elif html_format(doc.format): elem.attributes[ "style"] = "style=width:" + doc.columns_width.to_html( ) + ";margin:0 auto;line-break-after: always;" #elem.content = list(elem.content) + [pf.RawBlock('<br/>', format='html')] if doc.columns_sep.width != 0: rep_text = doc.columns_sep.to_html() else: rep_text = '2px' #Patch column HTML attributes for col in to_patch: col.attributes["style"] = col.attributes["style"].replace( "COLSEP", rep_text) return [ elem, pf.RawBlock('<br style=\"clear:both\"/>', format='html') ] elif doc.format == 'latex': left = pf.RawBlock('\\begin{center}', format='latex') right = pf.RawBlock('\\end{center}', format='latex') if doc.columns_sep.width != 0: rep_text = '\\hspace{' + doc.columns_sep.to_latex() + '}%\n' else: rep_text = '' for col in to_patch: col.text = col.text.replace("COLSEP", rep_text) elem.content = [left] + list(elem.content) + [right] return elif doc.format == 'docx': row = pf.TableRow() for col in to_patch: row.content.append(col) rows = [row] return pf.Table(*rows) else: return elif type( elem ) == pf.Div and 'column' in elem.classes and not doc.pandoc_columns: ## Eliminar de elem.classes if doc.disable_columns: elem.classes.remove('column') doc.column_count = doc.column_count + 1 if "width" in elem.attributes: width = Dimension(elem.attributes["width"]) else: width = Dimension("50%") if doc.format == 'beamer': left = pf.RawBlock('\\begin{column}{' + width.to_latex() + '}', format='latex') right = pf.RawBlock('\\end{column}', format='latex') if doc.column_count > 1: rb = pf.RawBlock('COLSEP', format='latex') doc.columns_to_patch.append(rb) elem.content = [rb] + [left] + list(elem.content) + [right] else: elem.content = [left] + list(elem.content) + [right] return elem elif html_format(doc.format): if doc.column_count > 1: fval = "left" #"right" else: fval = "left" elem.attributes["style"] = "style=width:" + width.to_html( ) + ";float:" + fval + ';margin-right:COLSEP' doc.columns_to_patch.append(elem) return elif doc.format == 'latex': if doc.prev_column == None: left = pf.RawBlock('\\begin{minipage}{' + width.to_latex() + '}', format='latex') right = pf.RawBlock('\\end{minipage}', format='latex') elem.content = [left] + list(elem.content) + [right] else: closing_minipage = doc.prev_column.content[ -1] ## Last item ... closing_minipage.text = '\\end{minipage} %\nCOLSEP\\begin{minipage}{' + width.to_latex( ) + '}' right = pf.RawBlock('\\end{minipage}', format='latex') doc.columns_to_patch.append(closing_minipage) elem.content = list(elem.content) + [right] doc.prev_column = elem return elem elif doc.format == 'docx': obj = pf.TableCell(*elem.content) doc.columns_to_patch.append(obj) return elem else: return
def fenced_action(options, data, element, doc): # We'll only run this for CodeBlock elements of class 'table' caption = options.get('caption', 'Untitled Table') #caption = [pf.Str(caption)] filepath = options.get('file') has_header = options.get('header', True) width = options.get('width', 1) total_width = float(options.get('total_width', .8)) align = options.get('align', 'default') nrows = options.get('rows', 0) ncols = options.get('cols', 0) csvargs = options.get('csvargs', {}) dtargs = options.get('dtargs', {}) mediadir = doc.get_metadata('mediadir') csvargs['dialect'] = csvargs.get('dialect', "unix") csvargs['delimiter'] = csvargs.get('delimiter', "\t").encode().decode('unicode_escape') f = io.StringIO(data) if data else open(filepath) try: reader = csv.reader(f, **csvargs) body = [] for i, row in enumerate(reader): if nrows and i > nrows: continue cells = [ pf.TableCell(formatCell(x)) for k, x in enumerate(row) if not ncols or k < ncols] body.append(pf.TableRow(*cells)) finally: f.close() ncols = min(ncols, len(row)) if ncols else len(row) if has_header: header = body.pop(0) if body and len(body[0].content) == len(header.content) + 1: header.content.insert(0, pf.TableCell(pf.Plain(pf.Str('')))) elif nrows: header = None body = body[:nrows] if not isinstance(width, list): width = [width] if len(width) == 1 and ncols: width = width * ncols sumwidth = float(sum(width)) total_width = min(total_width, 1) width = [float(wid)*float(total_width)/sumwidth for wid in width] if not isinstance(align, list): align = [align] if len(align) == 1 and ncols: align = align * ncols align = ['Align' + al.capitalize() for al in align] if mediadir and filepath: # copy file to mediadir and check if file exists filepath = Path(filepath) mediadir = Path(mediadir) mediadir.mkdir(exist_ok = True, parents = True) destfile = mediadir / filepath.name destfile = _copyfile(filepath, destfile) caption = [pf.Link( pf.Str(caption), url = str(destfile.relative_to(destfile.parent.parent)), title = 'Right clink and "Save link as" to download whole table.', attributes = {'target': '_blank'})] else: caption = [pf.Str(caption)] table = pf.Table(*body, header=header, caption=caption, width=width, alignment = align) if dtargs is False: return pf.Div(table, classes = ['tablewrapper']) else: return pf.Div(table, classes = ['tablewrapper', 'datatablewrapper'], attributes = { 'data-datatable': json.dumps(dtargs) })
def r(cs): return pf.TableRow(*list(map(c, cs)))