-
Notifications
You must be signed in to change notification settings - Fork 0
/
divs-to-latex.py
executable file
·166 lines (129 loc) · 3.82 KB
/
divs-to-latex.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python3
"""
Pandoc filter for adding LaTeX environment on specific div
"""
from panflute import *
META = {}
md = """---
pandoc-latex-environment:
bashterm: [bash]
ubuntu: [ubuntu]
admonitionnote: [note]
admonitiontip : [tip]
admonitionerror: [error]
admonitionwarn: [warn]
admonitionterm: [term]
admonitionquote: [quote]
message: [message]
messagenote: [msgnote]
messagetip : [msgtip]
messageerror: [msgerror]
messagewarn: [msgwarn]
messageterm: [msgterm]
messagequote: [msgquote]
...
::: ubuntu
ubuntu div
::::::
"""
def prepare(doc):
pass
def action(elem, doc):
"""
:param elem:
:param doc:
:return:
"""
# Works only for Latex
if doc.format not in ['beamer', 'latex']:
pass
# Skip non Div elements
if not isinstance(elem, Div):
return
# getting the document metadata. First checking if META is defined
try:
META
except NameError:
META = doc.get_metadata('div-env', None)
finally:
if not META:
return
attributes = elem.attributes
#
# Checks if one of the div classes is in the metadata
# Otherwise the Div is unchanged
#
if not (len(elem.classes) and elem.classes[0] in META):
return
div = elem.classes[0]
env = META[div]
# Getting the label, which is the div id ( ::: {#div .env} )
label = ''
if elem.identifier != '':
label = '\\label{' + elem.identifier + '}'
if 'title' in attributes:
title = f"[{attributes['title']}]"
else:
title = ''
# Temporarily filling some properties in a temporary doc attribute (called div)
doc.div = (env, title, label)
# Finding the first paragraph and adding the opening environment statement
# This is required to avoid an extra line inserted after the opening
#
# Adding like this, causes this side effect
# before = Plain(RawInline(format='tex', text='\\begin{' + env + '}' + title + label))
# elem.content.insert(0,before)
elem.walk(add_before_first_paragraph, doc)
# Adding a last Plain element containing the closing statement as a RawLatex string
after = Plain(RawInline(format='tex', text='\\end{' + env + '}'))
elem.content.append(after)
def finalize(doc):
pass
def latex(txt=""):
"""
Creates an Inline Latex string
:param txt: Text to be written
:return: RawInline element
"""
return RawInline(format='tex', text=txt)
def add_before_first_paragraph(elem, doc):
"""
Gets the first paragraph of the Div and adds
a latex inline before the first paragraph
This avoids an extra newline after the environment opening,
which causes a side effect when displaying source code
:param elem:
:param doc:
:return:
"""
# Double-checking the presence of added data in "div" field
if not hasattr(doc, "div"):
return
if type(elem) == Para:
# Getting the required data
env, title, label = doc.div
before = latex('\\begin{' + env + '}' + title + label)
# before = RawInline(format='tex', text='\\begin{' + env + '}' + title + label)
elem.content.insert(0, before)
# Removing the temporary data
del doc.div
return elem
else:
pass
def main_test(doc=None):
file_name = "test.json"
file = open(file_name, "r")
run_filter(action,
prepare=prepare,
finalize=finalize,
input_stream=file,
doc=doc)
convert_text(doc, output_format="latex", standalone=True)
def main(doc=None):
return run_filter(action,
prepare=prepare,
finalize=finalize,
doc=doc)
if __name__ == '__main__':
# main_test()
main()