Skip to content

Instantly share code, notes, and snippets.

@guyromm
Last active November 16, 2016 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guyromm/f811592cd3208a3fabbd120f721d952c to your computer and use it in GitHub Desktop.
Save guyromm/f811592cd3208a3fabbd120f721d952c to your computer and use it in GitHub Desktop.
org-mode <-> termsql (https://github.com/tobimensch/termsql) adapter
#!/usr/bin/env python
import re,sys
import csv
"""
we've got two modes of operation:
# extract a table from within an 'hours' heading, directly feedable into termsql
# echoing to stdout valid termsql input
cat table.org | tsorg.py 'hours' | termsql -r5 -0 -1 'select * from tbl'
# extract a table from a default-formatted termsql output (https://github.com/tobimensch/termsql)
# with the -0 and -1 flags, echoing to stdout a valid org-mode table.
cat table.csv | tsorg.py
"""
def parse_org(stdin,section_filter,delimiter="\t",whitespaces=False,header_separator=False,rjust=False):
in_header = was_in_section = in_section=False
if section_filter:
# seek & skip header
for ln in stdin:
l = ln.strip()
snres = re.compile('^([\*]+) (.+)').search(l)
if snres: section_name = snres.group(2)
was_in_section = snres and snres.group(2)==section_filter and True or was_in_section
in_section=was_in_section and l.startswith('|') and True or False
if not (in_section and section_name==section_filter): continue #not our section
break #got to the joovce!
in_ = [ln for ln in stdin]
if in_[0].startswith('|---'): del in_[0] #hackitty
if in_[-1].startswith('|---'): del in_[-1] #hackitty
del in_[1]# get rid of table header line
mins,out,headers,cnt = parse_ts(in_,delimiter=delimiter,doprint=False,input_delimiter='|',line_trim_s=1,line_trim_to=-1,do_strip=True)
print_op(mins,out,headers,cnt,delimiter=delimiter,header_separator=header_separator,rjust=rjust)
def print_op(mins,out,headers,cnt,delimiter='|',header_separator=True,rjust=True):
def pr(r):
if rjust:
arr = [r[i].rjust(mins[i]) for i in range(len(r))]
else:
arr = r
print delimiter+(delimiter.join(arr))+delimiter
pr(headers)
if header_separator: print delimiter+('-'*(sum([v+1 for v in mins.values()])-1))+delimiter
for r in out: pr(r)
def parse_ts(stdin,delimiter,doprint=True,input_delimiter=',',line_trim_s=0,line_trim_to=None,do_strip=False):
cnt=0
mins={}
out=[]
reader = csv.reader(stdin,delimiter=input_delimiter)
for ln in reader:
r= ln
r = r[line_trim_s:line_trim_to]
if do_strip: r = [el.strip() for el in r]
cnt+=1
if cnt==1:
headers =r
else:
out.append(r)
for i in range(len(r)):
if i not in mins: mins[i]=0
if mins[i]<len(r[i]): mins[i]=len(r[i])
if not doprint: return (mins,out,headers,cnt)
print_op(mins,out,headers,cnt,delimiter='|')
if __name__=='__main__':
section_filter = len(sys.argv)>1 and not sys.argv[1].startswith('--') and sys.argv[1] or None
args = dict([a[2:].split('=') for a in sys.argv if a.startswith('--')])
whitespaces = bool(args.get('whitespaces',False))
header_separator = bool(args.get('header-separator',False))
rjust=bool(args.get('rjust',False))
delimiter = args.get('delimiter',"\t")
parse_org(sys.stdin,section_filter,delimiter=delimiter,whitespaces=whitespaces,header_separator=header_separator,rjust=rjust)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment