Created
February 14, 2021 13:57
-
-
Save wgroeneveld/9dbeb0d0b60c6cb5d8dfe9b938c5e94e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Pandoc filter using panflute: scientific 2column mode fixes | |
This filter does the following: | |
1) fixes longtables -> tabular | |
It's intended use is for scientific papers that require 2 columns in the template layotu. | |
""" | |
from panflute import * | |
MAX_LBL_LENGTH = 20 | |
def labelify(cap, type): | |
maxlength = len(cap) if len(cap) < MAX_LBL_LENGTH else MAX_LBL_LENGTH | |
return type + ':' + cap[0:maxlength].replace(' ', '_').replace('\\', '_') | |
def raw(txt): | |
return RawBlock(txt, 'tex') | |
""" | |
source MD: | |
blaaleft blaricht | |
---------- ----------- | |
iets 9 | |
nog iets 10 | |
Table: Demonstration of simple table syntax. | |
without filter: | |
\begin{longtable}[]{@{}lr@{}} | |
\caption{Demonstration of simple table syntax.}\tabularnewline | |
\toprule | |
blaaleft & blaricht\tabularnewline | |
\midrule | |
\endfirsthead | |
\toprule | |
blaaleft & blaricht\tabularnewline | |
\midrule | |
\endhead | |
iets & 9\tabularnewline | |
nog iets & 10\tabularnewline | |
\bottomrule | |
\end{longtable} | |
with filter: | |
\begin{table}[h!] | |
\centering | |
\caption{Demonstration of simple table syntax.\label{table:Demonstration_of_sim}} | |
\begin{tabular}{l r} | |
\hline | |
blaaleft & blaricht\\ [0.5ex] | |
\hline | |
\hline | |
iets & 9\tabularnewline | |
nog iets & 10\tabularnewline | |
\hline\end{tabular} | |
\end{table} | |
""" | |
def replace_longtables_with_tabular(elem, doc): | |
# TODO still broken, & does not get passed on? | |
def items(): | |
result = '' | |
for row in elem.content: | |
txt = '' | |
for cell in row.content: | |
txt += stringify(cell).replace('_', '\\_') + ' & ' | |
result += txt[0:-3] + '\\tabularnewline\n' | |
return result | |
def caption(): | |
cap = stringify(*elem.caption.content) | |
return '\\caption{' + cap + '\\label{' + labelify(cap, 'table') + '}}\n' | |
def tabular(): | |
aligns = { | |
"AlignDefault": 'l', | |
"AlignLeft": 'l', | |
"AlignCenter": 'c', | |
"AlignRight": 'r', | |
} | |
tab = '\\begin{tabular}{' | |
for aligngroup in elem.colspec: | |
# WHY? panflute 2 -- :param colspec: list of (alignment, colwidth) tuples; one for each column | |
align = aligngroup[0] | |
tab += aligns[align] + ' ' | |
return tab[0:-1] + '}\n' | |
def headers(): | |
result = '\\hline\n' | |
for cell in elem.head.content: | |
result += stringify(cell) + ' & ' | |
return result[0:-3] + '\\\\ [0.5ex]\n\\hline\n\\hline\n' | |
return [raw('\\begin{table}[h!]\n\\centering\n' + | |
caption() + | |
tabular() + | |
headers() + | |
items() + | |
'\\hline' + '\\end{tabular}\n\\end{table}')] | |
def prepare(doc): | |
pass | |
def action(elem, doc): | |
if doc.format != 'latex': | |
return None | |
if isinstance(elem, Table): | |
return replace_longtables_with_tabular(elem, doc) | |
return None | |
def finalize(doc): | |
pass | |
# keep this structure: see http://scorreia.com/software/panflute/guide.html | |
# enabled filter using YAML config, panflute-filters=[x] | |
def main(doc=None): | |
return run_filter(action, | |
prepare=prepare, | |
finalize=finalize, | |
doc=doc) | |
if __name__ == '__main__': | |
main() |
I updated this to enable citations and cross references to tables
import sys
from panflute import *
def replace_longtables_with_tabular(elem, doc):
try:
def get_text(item):
if isinstance(item, Str):
return item.text.replace('_', r'\_')
elif isinstance(item, Plain):
return ''.join([get_text(i) for i in item.content])
elif isinstance(item, ListContainer):
return ''.join([get_text(i) for i in item])
elif isinstance(item, Code):
return '\\verb|' + (item.text) + '|'
elif isinstance(item, RawInline):
return item.text
elif isinstance(item, Cite):
return ''.join(stringify(elem) for elem in item.content)
elif str(item) == 'Space':
return ' '
else:
return str(item)
def caption():
if elem.caption and elem.caption.content:
return '\\caption{' + get_text(elem.caption.content) + '}\n' + \
'\\label{tbl:' + get_text(elem.caption.content).replace(' ', r'-').translate(str.maketrans("", "", "();,.")) + '}\n'
return ''
def tabular():
return '\\begin{tabular}{' + 'l' * elem.cols + '}\n\\hline\n'
def headers():
if elem.head and elem.head.content:
return ' & '.join([get_text(cell.content) for cell in elem.head.content[0].content]) + '\\\\\n\\hline\n'
return ''
def items():
rows = []
for body in elem.content:
for row in body.content:
rows.append(' & '.join([get_text(cell.content) for cell in row.content]) + '\\\\')
return '\n'.join(rows) + '\n'
result = '\\begin{table*}[t]\n\\centering\n' + \
caption() + \
tabular() + \
headers() + \
items() + \
'\\hline\n\\end{tabular}\n\\end{table*}'
print("Table processed successfully", file=sys.stderr)
return RawBlock(result, 'latex')
except Exception as e:
print(f"Error processing table: {str(e)}", file=sys.stderr)
return elem
def prepare(doc):
pass
def action(elem, doc):
if doc.format != 'latex':
return None
if isinstance(elem, Table):
print("Table found!", file=sys.stderr)
return replace_longtables_with_tabular(elem, doc)
return None
def finalize(doc):
pass
# keep this structure: see http://scorreia.com/software/panflute/guide.html
def main(doc=None):
return run_filter(action,
prepare=prepare,
finalize=finalize,
doc=doc)
if __name__ == '__main__':
main()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it works for me now