Skip to content

Instantly share code, notes, and snippets.

@wgroeneveld
Created February 14, 2021 13:57
Show Gist options
  • Save wgroeneveld/9dbeb0d0b60c6cb5d8dfe9b938c5e94e to your computer and use it in GitHub Desktop.
Save wgroeneveld/9dbeb0d0b60c6cb5d8dfe9b938c5e94e to your computer and use it in GitHub Desktop.
"""
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()
@Atticuszz
Copy link

import sys

from panflute import *

def replace_longtables_with_tabular(elem, doc):
    try:
        def get_text(item):
            if isinstance(item, Str):
                return item.text
            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])
            else:
                return str(item)

        def caption():
            if elem.caption and elem.caption.content:
                return '\\caption{' + get_text(elem.caption.content) + '}\n' + \
                    '\\label{table:' + (elem.identifier or '') + '}\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()

it works for me now

::: {.table}
| Methods    | Avg. | R0   | R1   | R2   | Of0  | Of1  | Of2  | Of3  | Of4  |
| ---------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| DROID-SLAM | 0.38 | 0.53 | 0.38 | 0.45 | 0.35 | 0.24 | 0.36 | 0.33 | 0.43 |
| SplaTAM    | 0.36 | 0.31 | 0.40 | 0.29 | 0.47 | 0.27 | 0.29 | 0.32 | 0.55 |

: Your table caption
:::

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment