43
44
class TexinfoTranslator(nodes.NodeVisitor):
45
# Sphinx and texinfo doesn't use the same names for the section levels,
46
# since this can be confusing, here are the correspondances (sphinx ->
50
# section -> subsection
51
# subsection -> subsubsection
52
# Additionally, sphinx defines subsubsections and paragraphs
53
46
section_names = ['chapter', 'section', 'subsection', 'subsubsection']
54
47
"""texinfo section names differ from the sphinx ones.
60
53
section -> subsection
61
54
subsection -> subsubsection
63
Additionally, sphinx defines subsubsections and paragraphs.
56
Additionally, sphinx defines subsubsections and paragraphs which are
57
handled as @heading (unnumbered).
66
60
def __init__(self, document, builder):
67
61
nodes.NodeVisitor.__init__(self, document)
69
62
# toctree uses some nodes for different purposes (namely:
70
63
# compact_paragraph, bullet_list, reference, list_item) that needs to
71
64
# know when they are proessing a toctree. The following attributes take
88
81
# The whole document
90
83
def visit_document(self, node):
91
# The debug killer trick
93
#sys.stderr.write(node.pformat())
94
set_item_list_collector(node, 'chunk')
86
sys.stdout.write(node.pformat().encode('utf8'))
87
set_item_list_collector(node, 'text')
96
89
def depart_document(self, node):
97
self.body = ''.join(node['chunk'])
90
self.body = ''.join(node['text'])
101
94
def visit_section(self, node):
102
95
self.section_level += 1
103
set_item_list_collector(node, 'chunk')
96
set_item_list_collector(node, 'text')
105
98
def depart_section(self, node):
109
102
# Just use @heading, it's not numbered anyway
110
103
section_name = 'heading'
111
104
section_cmd = '@%s %s\n' % (section_name, node['title'])
112
text = ''.join(node['chunk'])
113
node.parent.collect_chunk(section_cmd + text)
105
text = ''.join(node['text'])
106
node.parent.collect_text(section_cmd + text)
114
107
self.section_level -= 1
116
109
def visit_topic(self, node):
126
119
# End the paragraph with a new line (or '' depending on the parent) and
127
120
# leave a blank line after it.
128
121
text = ''.join(node['text']) + self.paragraph_sep * 2
129
node.parent.collect_chunk(text)
122
node.parent.collect_text(text)
131
124
def visit_compact_paragraph(self, node):
132
125
set_item_list_collector(node, 'text')
138
131
def depart_compact_paragraph(self, node):
139
132
if node.has_key('toctree'):
140
node.parent.collect_chunk('@menu\n')
141
node.parent.collect_chunk(''.join(node['text']))
142
node.parent.collect_chunk('@end menu\n')
133
node.parent.collect_text('@menu\n')
134
node.parent.collect_text(''.join(node['text']))
135
node.parent.collect_text('@end menu\n')
143
136
self.in_toctree = False
144
137
elif self.in_toctree:
145
138
# * FIRST-ENTRY-NAME:(FILENAME)NODENAME. DESCRIPTION
152
145
# XXX: What if :maxdepth: is not 1 ?
153
146
text = '* %s: (%s)%s. %s\n' % (entry_name, file_name,
154
147
node_name, description)
155
node.parent.collect_chunk(text)
148
node.parent.collect_text(text)
157
150
# End the paragraph with a new line (or '' depending on the parent)
158
151
# and leave a blank line after it.
159
152
text = ''.join(node['text']) + self.paragraph_sep * 2
160
node.parent.collect_chunk(text)
153
node.parent.collect_text(text)
162
155
def visit_literal_block(self, node):
163
156
set_item_collector(node, 'text')
165
158
def depart_literal_block(self, node):
166
159
text = '@samp{%s}' % ''.join(node['text']) + self.paragraph_sep * 2
167
node.parent.collect_chunk(text)
160
node.parent.collect_text(text)
169
162
def visit_block_quote(self, node):
170
set_item_list_collector(node, 'chunk')
163
set_item_list_collector(node, 'text')
172
165
def depart_block_quote(self, node):
173
node.parent.collect_chunk('@example\n')
174
node.parent.collect_chunk(''.join(node['chunk']))
175
node.parent.collect_chunk('@end example\n\n')
166
node.parent.collect_text('@example\n')
167
node.parent.collect_text(''.join(node['text']))
168
node.parent.collect_text('@end example\n\n')
177
170
def visit_note(self, node):
171
raise nodes.SkipNode # Not implemented yet
180
173
def depart_warning(self, node):
183
176
def visit_warning(self, node):
177
raise nodes.SkipNode # Not implemented yet
186
179
def depart_note(self, node):
189
182
def visit_footnote(self, node):
183
raise nodes.SkipNode # Not implemented yet
192
185
def depart_footnote(self, node):
195
188
def visit_comment(self, node):
189
raise nodes.SkipNode # Not implemented yet
269
262
if self.in_toctree:
270
263
self._decorate_list(node['list_item'], node.parent.collect_text)
272
self._decorate_list(node['list_item'], node.parent.collect_chunk,
265
self._decorate_list(node['list_item'], node.parent.collect_text,
274
267
# FIXME: Should respect the 'bullet' attribute
275
268
'@itemize @bullet\n', '@end itemize\n')
278
271
set_item_list_collector(node, 'list_item')
280
273
def depart_enumerated_list(self, node):
281
self._decorate_list(node['list_item'], node.parent.collect_chunk,
274
self._decorate_list(node['list_item'], node.parent.collect_text,
283
276
'@enumerate\n', '@end enumerate\n')
285
278
def visit_definition_list(self, node):
279
raise nodes.SkipNode # Not implemented yet
288
281
def depart_definition_list(self, node):
282
raise nodes.SkipNode # Not implemented yet
291
284
def visit_definition_list_item(self, node):
285
raise nodes.SkipNode # Not implemented yet
294
287
def depart_definition_list_item(self, node):
297
290
def visit_term(self, node):
291
raise nodes.SkipNode # Not implemented yet
300
293
def depart_term(self, node):
303
296
def visit_definition(self, node):
297
raise nodes.SkipNode # Not implemented yet
306
299
def depart_definition(self, node):
309
302
def visit_field_list(self, node):
303
raise nodes.SkipNode # Not implemented yet
311
305
def depart_field_list(self, node):
314
308
def visit_field(self, node):
309
raise nodes.SkipNode # Not implemented yet
316
311
def depart_field(self, node):
319
314
def visit_field_name(self, node):
315
raise nodes.SkipNode # Not implemented yet
322
317
def depart_field_name(self, node):
325
320
def visit_field_body(self, node):
321
raise nodes.SkipNode # Not implemented yet
328
323
def depart_field_body(self, node):
331
326
def visit_list_item(self, node):
332
set_item_list_collector(node, 'chunk')
327
set_item_list_collector(node, 'text')
334
329
def depart_list_item(self, node):
335
text = ''.join(node['chunk'])
330
text = ''.join(node['text'])
336
331
node.parent.collect_list_item(text)
338
333
def visit_option_list(self, node):
334
raise nodes.SkipNode # Not implemented yet
341
336
def depart_option_list(self, node):
380
375
set_item_collector(node, 'table')
382
377
def depart_table(self, node):
383
node.parent.collect_chunk(node['table'])
378
node.parent.collect_text(node['table'])
385
380
def visit_tgroup(self, node):
386
381
set_item_list_collector(node, 'colspec')
394
389
'{%s}', '@multitable ', '\n')
395
390
# The '@headitem xxx @tab yyy...' line
396
391
head_entries = node['head_entries']
397
self._decorate_list(head_entries[1:], header.append,
398
' @tab %s', '@headitem %s' % head_entries[0], '\n')
392
if head_entries is not None:
393
# Not all tables define titles for the columns... rest parser bug ?
395
self._decorate_list(head_entries[1:], header.append,
397
'@headitem %s' % head_entries[0], '\n')
399
398
header = ''.join(header)
400
399
# The '@item xxx\n @tab yyy\n ...' lines
401
400
body_rows = node['body_rows']
431
430
node.parent.collect_row(node['entry'])
433
432
def visit_entry(self, node):
434
set_item_list_collector(node, 'chunk')
433
set_item_list_collector(node, 'text')
435
434
node['par_sep_orig'] = self.paragraph_sep
436
435
self.paragraph_sep = ''
438
437
def depart_entry(self, node):
439
node.parent.collect_entry(''.join(node['chunk']))
438
node.parent.collect_entry(''.join(node['text']))
440
439
self.paragraph_sep = node['par_sep_orig']
449
448
set_item_collector(node, 'text')
451
450
def depart_reference(self, node):
452
node.parent.collect_reference((node.get('anchorname', ''),
453
node.get('refuri', ''),
454
''.join(node['text']),
451
collect = getattr(node.parent, 'collect_reference', None)
452
if collect is not None:
453
# FIXME: this handle only the toctree references so far.
454
collect((node.get('anchorname', ''),
455
node.get('refuri', ''),
456
''.join(node['text']),
457
459
def visit_footnote_reference(self, node):
460
raise nodes.SkipNode # Not implemented yet
460
462
def visit_citation_reference(self, node):
463
raise nodes.SkipNode # Not implemented yet
463
465
def visit_title_reference(self, node):
466
raise nodes.SkipNode # Not implemented yet
466
468
def depart_title_reference(self, node):
469
471
def visit_target(self, node):
472
raise nodes.SkipNode # Not implemented yet
472
474
def depart_target(self, node):
475
477
def visit_image(self, node):
476
self.add_text(_('[image]'))
478
raise nodes.SkipNode # Not implemented yet
479
480
# Helpers to collect data in parent node