This repository has been archived by the owner on Nov 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpandocLatex.py
146 lines (121 loc) · 4.53 KB
/
pandocLatex.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/python
import subprocess as sp
import re #regexpr
import fileinput
import itertools as it
#import pandocfilters as pf
# Line object for parsing a file line by line
# Allows changing the line (i.e. removing, filtering, using regular expressions)
# or to add some lines
class lineObj(object):
__slots__ = ('lno', 'linecount','line')
def __init__(self, lno, linecount, line):
self.lno = lno
self.linecount = linecount
self.line = line
def __repr__(self):
return ("Line:\t%d/%d, \"%s\"" % (self.lno,self.linecount,self.line))
# Takes a list of generators as defined below and passes all lines through the
# generator list
def applyOnFile(inputgenlist, fname):
count = sum( (1 for line in open(fname).readlines( )) )
# Prepare file input
# Wrap each line in a lineObj with linenumber and linecount
def finputgenerator(finput):
for (ln,lc,l) in zip(range(1,count+1),it.repeat(count,count),finput):
yield lineObj(ln,lc,l)
# Intermediate generator that is executed after each generator
def flowController(filter):
lastl = 0
incr = 0
for lobj in filter:
# Check whether a line has been added
# If yes, increase line number and total linecount
if(lobj.lno==lastl):
incr += 1
lastl =lobj.lno
lobj.lno += incr
lobj.linecount += incr
yield lobj
# Open file
finput =fileinput.input(fname,inplace=True)
# Prepare lines...
processor = finputgenerator(finput)
# Consecutively bind of all generators
for gen in inputgenlist:
processor = gen(flowController(processor))
# Now pass each line through list of generators
for lobj in processor:
if(lobj.line!=None):
print(lobj.line,end='')
finput.close()
def centerFigureFilter(inputgen):
for lobj in inputgen:
yield lobj
if(lobj.line):
if(lobj.line.startswith("\\begin{figure}") ):
#append on next line
lobj.line = "\\centering"
yield lobj
def adjustBeamerFootnote(inputgen):
for lobj in inputgen:
if(lobj.line!=None):
lobj.line=re.sub(r'\\footnote<[^>]*>',
r'\\footnote',lobj.line)
#yield (ln,lc,l)
yield lobj
# Adjust longtables using regex to remove @{} in table formatting
# I.e \begin{longtable}[c]{@{}lrc@{}}
# to \begin{longtable}[c]{lrc}
def adjustLongtableFilter(inputgen):
#for (ln,lc,l) in inputgen:
for lobj in inputgen:
if(lobj.line!=None):
lobj.line=re.sub(r'(\\begin){longtable}(\[\w*\]){@{}([lrc]*)@{}}',
r'\1{longtable}\2{\3}',lobj.line)
#yield (ln,lc,l)
yield lobj
# editor: https://regex101.com
def adjustFigureCaption(inputgen):
#for (ln,lc,l) in inputgen:
ltmp = ""
for lobj in inputgen:
if((lobj.line!=None)):
if(lobj.line.startswith("\\caption")):
#ltmp += lobj.line.rstrip('\n')
ltmp += lobj.line
lobj.line = ""
elif(ltmp!=""):
lobj.line = ltmp + lobj.line
ltmp = ""
# re.DOTALL makes . also match new line \n
lobj.line=re.sub(r'(\\caption){{\[}{\[}(.+?(?={\]}{\]})){\]}{\]}',
r'\1[\2]{',lobj.line,flags=re.DOTALL)
lobj.line=re.sub(r'(\\caption){(\\label{.+?}){\[}{\[}(.+?(?={\]}{\]})){\]}{\]}',
r'\1[\3]{\2',lobj.line,flags=re.DOTALL)
yield lobj
# Command Object
class cmdObj(object):
__slots__ = ('cmd', 'shellOutput','before','after','pushDir')
def __init__(self, cmd, shellOutput=True,before=[],after=[],pushDir=""):
self.cmd = cmd
self.shellOutput = shellOutput
self.before = before
self.after = after
self.pushDir = pushDir
def __repr__(self):
return ("Cmd:\t%s, ShellOutput:\t%s" % (self.cmd,self.shellOutput))
# Process a list of commands
def processCommands(cmdObjs):
def __processFunccalls__(calls):
for (func, args, kwargs) in calls:
func(*args,**kwargs)
for cmdObj in cmdObjs:
rcmd = cmdObj.cmd
if(cmdObj.pushDir!=""):
rcmd = "pushd " + cmdObj.pushDir + " && pwd && " + cmdObj.cmd + " && popd"
__processFunccalls__(cmdObj.before)
if(cmdObj.shellOutput):
print(rcmd)
sp.call(rcmd,shell=cmdObj.shellOutput)
__processFunccalls__(cmdObj.after)