Skip to content

Instantly share code, notes, and snippets.

@svenevs
Last active January 5, 2021 03:06
Show Gist options
  • Save svenevs/41a1a434a055adcee56bd1f0374fa254 to your computer and use it in GitHub Desktop.
Save svenevs/41a1a434a055adcee56bd1f0374fa254 to your computer and use it in GitHub Desktop.
Hack to get vertical rules in pandoc generated latex tables.
# left shebang empty for you to change. you do you
import re
import sys
import copy
########################################################################################
# #
# License: CC0 -- do whatever the hell you want with this. I hope it works for you! #
# Love, Sven. #
# #
########################################################################################
# #
# This is *NOT* a pandoc filter. This is to be used if you want to manipulate the #
# output of pandoc latex to put verticle rules in the tables. Should work with #
# python2 and python3. Your mileage may vary. #
# #
# Example usage (just copy til end of line and paste in terminal), assuming you called #
# this file tex_table_verts.py: #
# #
# echo -e '\\begin{longtable}[c]{@{}llrrllclrl@{}}\nthis line does not have table\n\\begin{longtable}[c]{@{}llllll@{}}\nno\ntable\nhere\n\\begin{longtable}[c]{@{}l@{}}' | python3 tex_table_verts.py
# #
# Basically, the design is to just take your pandoc output and pipe it to this script. #
# Something like #
# #
# pandoc -s -f markdown -t latex input.md | python tex_table_verts.py > output.tex #
# #
# Windows users? No idea if you can benefit. Sorry. #
# #
########################################################################################
# #
# We want to turn something like this: #
# #
# \begin{longtable}[c]{@{}ll@{}} #
# #
# into something like this: #
# #
# \begin{longtable}[c]{@{}|l|l|@{}} #
# #
# We make the assumption that the input format always has #
# #
# \begin{longtable}[c]{@{}ll@{}} #
# |----------------------|XX|--| #
# #
# That is, the longtable is being searched for, as well as {@{}XXXX@{}} #
# where XXXX changes depending on the table you are writing. #
# #
########################################################################################
try:
orig_input = sys.stdin.read()
# Important group being saved: the r, c, or l's for the table columns.
# vvvvvvvv
vert_re = re.compile(r'(\\begin\{longtable\}\[.*\]\{@\{\})([rcl]+)(@\{\}\})', re.MULTILINE)
# ^ not sure if pandoc changes this ever?
# We have three groups captured above:
#
# 1. \begin{longtable}[c]{@{}
# 2. [rcl]+
# 3. @{}}
#
# The below takes these three, turns group 2 into vertically separated columns, and
# then appends this to `replacements` joined with 1 and 3 so we can use `sub` below.
replacements = []
for match in vert_re.finditer(orig_input):
table_start, cols, table_end = match.groups()
# Gives you say |r|c|l|
# If you forever wanted just r|c|l without the outer ones, set vert_cols to just
# be "|".join(cols). Get creative if you don't want every inner one vertically
# separated.
vert_cols = "|{}|".format("|".join(cols))
replacements.append("{}{}{}".format(table_start, vert_cols, table_end))
# probably not necessary
output = copy.deepcopy(orig_input)
# if the above loop executed, the same regex will have the matches replaced
# according to the order we found them above
if replacements:
output = vert_re.sub(lambda cols: replacements.pop(0), output)
# Set this to True if pandoc is giving you trouble with no horizontal rules in
# tables that have multiple rows
if False:
output = re.sub(r'(\\tabularnewline)(\s+)(\\begin{minipage})', r'\1\2\\midrule\2\3', output)
# write the conversion to stdout
sys.stdout.write(output)
except Exception as e:
# you may want to change this to fail out -- if an error was caught you probably
# aren't going to actually get any valid output anyway? up to you, just figured
# i'd write something *kind of* intelligent.
sys.stderr.write(
"Critical error, printing original stdin to stdout:\n{}".format(e)
)
sys.stdout.write(orig_input)
@svenevs
Copy link
Author

svenevs commented Mar 25, 2017

Take note that the booktabs author is very clear about how they feel about vertical rules. I disagree, there are times that you want them. Like lecture slides. The point: using pandoc, you will get booktabs included by default. So you will probably want to create a custom template that changes the table behavior. Something like

$if(tables)$
% To the BookTabs author: eat my vertical lines.
% \usepackage{longtable,booktabs}
% \usepackage{caption}
\usepackage{longtable}
\def\toprule{\hline}
\def\midrule{\hline}
\def\bottomrule{\hline}
% These lines are needed to make table captions work with longtable:
\makeatletter
\def\fnum@table{\tablename~\thetable}
\makeatother
$endif$

@tur11ng
Copy link

tur11ng commented Mar 29, 2020

% To the BookTabs author: eat my vertical lines.

LOL, you made my day :P

@Faldrian
Copy link

Faldrian commented Jul 7, 2020

So I have to feed the generated latex back into pdflatex to get a pdf from it... but unfortunately SVG images are not working anymore, because pandocs magic "oh, transform SVG to PNG while rendering and feed it to pdflatex" is not used this way.
Hmh... I want tables with vertical borders so bad. :-/

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