3
import docutils.core as dc
4
import docutils.writers
5
from docutils import nodes
7
from docutils.writers.latex2e import (Writer, LaTeXTranslator,
10
from rstmath import mathEnv
13
from options import options
15
PreambleCmds.float_settings = '''
16
\\usepackage[font={small,it},labelfont=bf]{caption}
20
class Translator(LaTeXTranslator):
21
def __init__(self, *args, **kwargs):
22
LaTeXTranslator.__init__(self, *args, **kwargs)
24
# Handle author declarations
29
author_institutions = []
34
abstract_in_progress = False
35
non_breaking_paragraph = False
37
def visit_docinfo(self, node):
40
def depart_docinfo(self, node):
43
def visit_author(self, node):
44
self.author_names.append(self.encode(node.astext()))
47
def depart_author(self, node):
50
def visit_classifier(self, node):
53
def depart_classifier(self, node):
56
def visit_field_name(self, node):
57
self.current_field = node.astext()
60
def visit_field_body(self, node):
61
text = self.encode(node.astext())
63
if self.current_field == 'email':
64
self.author_emails.append(text)
65
elif self.current_field == 'institution':
66
self.author_institutions.append(text)
68
self.current_field = ''
72
def depart_field_body(self, node):
75
def depart_document(self, node):
76
LaTeXTranslator.depart_document(self, node)
78
title = self.paper_title
79
authors = ', '.join(self.author_names)
82
The corresponding author is with %s, e-mail: \protect\href{%s}{%s}.
83
''' % (self.author_institutions[0], 'mailto:' + self.author_emails[0],
84
self.author_emails[0])]
86
author_notes = ''.join('\\thanks{%s}' % n for n in author_notes)
88
title_template = '\\title{%s}\\author{%s%s}\\maketitle'
89
title_template = title_template % (title,
94
\renewcommand{\leftmark}{%s}
95
\renewcommand{\rightmark}{%s}
96
''' % (options['proceedings_title'], title.upper())
97
title_template += marks
99
self.body_pre_docinfo = [title_template]
101
def end_open_abstract(self, node):
102
if 'abstract' not in node['classes'] and self.abstract_in_progress:
103
self.out.append('\\end{abstract}')
104
self.abstract_in_progress = False
106
def visit_title(self, node):
107
self.end_open_abstract(node)
109
if self.section_level == 1:
112
warnings.warn(RuntimeWarning("Title set twice--ignored. "
113
"Could be due to ReST"
116
self.paper_title = self.encode(node.astext())
119
elif node.astext() == 'References':
122
LaTeXTranslator.visit_title(self, node)
124
def visit_paragraph(self, node):
125
self.end_open_abstract(node)
127
if 'abstract' in node['classes'] and not self.abstract_in_progress:
128
self.out.append('\\begin{abstract}')
129
self.abstract_in_progress = True
131
elif 'keywords' in node['classes']:
132
self.out.append('\\begin{IEEEkeywords}')
134
elif self.non_breaking_paragraph:
135
self.non_breaking_paragraph = False
138
self.out.append('\n\n')
140
def depart_paragraph(self, node):
141
if 'keywords' in node['classes']:
142
self.out.append('\\end{IEEEkeywords}')
144
def visit_figure(self, node):
145
self.requirements['float_settings'] = PreambleCmds.float_settings
146
if 'classes' in node.attributes:
147
placements = ''.join(node.attributes['classes'])
148
self.out.append('\\begin{figure}[%s]'%placements)
150
self.out.append('\\begin{figure}')
152
self.out += ['\n'] + self.ids_to_labels(node)
154
def visit_image(self, node):
155
attrs = node.attributes
157
# Only add \columnwidth if scale or width have not been specified.
158
if 'scale' not in node.attributes and 'width' not in node.attributes:
159
node.attributes['width'] = '\columnwidth'
161
node.attributes['align'] = 'left'
163
LaTeXTranslator.visit_image(self, node)
165
def visit_footnote(self, node):
166
# Work-around for a bug in docutils where
167
# "%" is prepended to footnote text
168
LaTeXTranslator.visit_footnote(self, node)
169
self.out[-1] = self.out[1].strip('%')
171
self.non_breaking_paragraph = True
173
def visit_table(self, node):
174
self.out.append(r'\begin{table}')
175
LaTeXTranslator.visit_table(self, node)
177
def depart_table(self, node):
178
LaTeXTranslator.depart_table(self, node)
180
self.out.append(r'\caption{%s}' % ''.join(self.table_caption))
181
self.table_caption = []
183
self.out.append(r'\end{table}')
184
self.active_table.set('preamble written', 1)
186
def visit_thead(self, node):
187
# Store table caption locally and then remove it
188
# from the table so that docutils doesn't render it
189
# (in the wrong place)
190
self.table_caption = self.active_table.caption
191
self.active_table.caption = []
193
LaTeXTranslator.visit_thead(self, node)
195
def depart_thead(self, node):
196
LaTeXTranslator.depart_thead(self, node)
198
def visit_literal_block(self, node):
199
self.non_breaking_paragraph = True
201
if 'language' in node.attributes:
203
from pygments import highlight
204
from pygments.lexers import PythonLexer, get_lexer_by_name
205
from pygments.formatters import LatexFormatter
207
extra_opts = 'fontsize=\\footnotesize'
209
linenos = node.attributes.get('linenos', False)
210
linenostart = node.attributes.get('linenostart', 1)
212
extra_opts += ',xleftmargin=2.25mm,numbersep=3pt'
214
lexer = get_lexer_by_name(node.attributes['language'])
215
tex = highlight(node.astext(), lexer,
216
LatexFormatter(linenos=linenos,
217
linenostart=linenostart,
218
verboptions=extra_opts))
223
LaTeXTranslator.visit_literal_block(self, node)
225
def depart_literal_block(self, node):
226
LaTeXTranslator.depart_literal_block(self, node)
229
# Math directives from rstex
231
def visit_InlineMath(self, node):
232
self.requirements['amsmath'] = r'\usepackage{amsmath}'
233
self.body.append('$' + node['latex'] + '$')
236
def visit_PartMath(self, node):
237
self.requirements['amsmath'] = r'\usepackage{amsmath}'
238
self.body.append(mathEnv(node['latex'], node['label'], node['type']))
239
self.non_breaking_paragraph = True
242
def visit_PartLaTeX(self, node):
243
if node["usepackage"]:
244
for package in node["usepackage"]:
245
self.requirements[package] = r'\usepackage{%s}' % package
246
self.body.append("\n" + node['latex'] + "\n")
251
writer.translator_class = Translator