~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/doc_generate/writers/texinfo.py

  • Committer: Vincent Ladeuil
  • Date: 2010-05-08 08:19:38 UTC
  • mto: (5355.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5356.
  • Revision ID: v.ladeuil+lp@free.fr-20100508081938-5wou5081f8svjs1h
Skip all not implemented nodes.

* doc/en/user-guide/index-plain.txt:
Get rid of the U+2014 trick, I can't find where it's used anyway.

* bzrlib/doc_generate/writers/texinfo.py:
(TexinfoTranslator): Forget about chunks, we just produce text
anyway, the newlines are embedded when needed so the resulting
text can always be joined with ''. Skip nodes that are not yet
implemented.
(TexinfoTranslator.depart_tgroup): Not all tables define column
titles, needs investigation.
(TexinfoTranslator.depart_reference): Mark as incomplete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    writers,
22
22
    )
23
23
 
 
24
DEBUG = 0
24
25
 
25
26
class TexinfoWriter(writers.Writer):
26
27
 
42
43
 
43
44
class TexinfoTranslator(nodes.NodeVisitor):
44
45
 
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 ->
47
 
    # texinfo).
48
 
    # part -> chapter
49
 
    # chapter -> section
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.
55
48
 
60
53
    section    -> subsection
61
54
    subsection -> subsubsection
62
55
 
63
 
    Additionally, sphinx defines subsubsections and paragraphs.
 
56
    Additionally, sphinx defines subsubsections and paragraphs which are
 
57
    handled as @heading (unnumbered).
64
58
    """
65
59
 
66
60
    def __init__(self, document, builder):
67
61
        nodes.NodeVisitor.__init__(self, document)
68
 
        self.chunks = []
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
89
82
 
90
83
    def visit_document(self, node):
91
 
        # The debug killer trick
92
 
        #import sys
93
 
        #sys.stderr.write(node.pformat())
94
 
        set_item_list_collector(node, 'chunk')
 
84
        if DEBUG:
 
85
            import sys
 
86
            sys.stdout.write(node.pformat().encode('utf8'))
 
87
        set_item_list_collector(node, 'text')
95
88
 
96
89
    def depart_document(self, node):
97
 
        self.body = ''.join(node['chunk'])
 
90
        self.body = ''.join(node['text'])
98
91
 
99
92
    # Layout
100
93
 
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')
104
97
 
105
98
    def depart_section(self, node):
106
99
        try:
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
115
108
 
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)
130
123
 
131
124
    def visit_compact_paragraph(self, node):
132
125
        set_item_list_collector(node, 'text')
137
130
 
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)
156
149
        else:
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)
161
154
 
162
155
    def visit_literal_block(self, node):
163
156
        set_item_collector(node, 'text')
164
157
 
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)
168
161
 
169
162
    def visit_block_quote(self, node):
170
 
        set_item_list_collector(node, 'chunk')
 
163
        set_item_list_collector(node, 'text')
171
164
 
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')
176
169
 
177
170
    def visit_note(self, node):
178
 
        pass
 
171
        raise nodes.SkipNode # Not implemented yet
179
172
 
180
173
    def depart_warning(self, node):
181
174
        pass
182
175
 
183
176
    def visit_warning(self, node):
184
 
        pass
 
177
        raise nodes.SkipNode # Not implemented yet
185
178
 
186
179
    def depart_note(self, node):
187
180
        pass
188
181
 
189
182
    def visit_footnote(self, node):
190
 
        pass
 
183
        raise nodes.SkipNode # Not implemented yet
191
184
 
192
185
    def depart_footnote(self, node):
193
186
        pass
194
187
 
195
188
    def visit_comment(self, node):
196
 
        raise nodes.SkipNode
 
189
        raise nodes.SkipNode # Not implemented yet
197
190
 
198
191
    # Attributes
199
192
 
205
198
        node.parent['title'] = text
206
199
 
207
200
    def visit_label(self, node):
208
 
        raise nodes.SkipNode
 
201
        raise nodes.SkipNode # Not implemented yet
209
202
 
210
203
    def visit_substitution_definition(self, node):
211
 
        raise nodes.SkipNode
 
204
        raise nodes.SkipNode # Not implemented yet
212
205
 
213
206
    # Plain text
214
207
 
269
262
        if self.in_toctree:
270
263
            self._decorate_list(node['list_item'], node.parent.collect_text)
271
264
        else:
272
 
            self._decorate_list(node['list_item'], node.parent.collect_chunk,
 
265
            self._decorate_list(node['list_item'], node.parent.collect_text,
273
266
                                '@item\n%s',
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')
279
272
 
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,
282
275
                            '@item\n%s',
283
276
                            '@enumerate\n', '@end enumerate\n')
284
277
 
285
278
    def visit_definition_list(self, node):
286
 
        pass
 
279
        raise nodes.SkipNode # Not implemented yet
287
280
 
288
281
    def depart_definition_list(self, node):
289
 
        pass
 
282
        raise nodes.SkipNode # Not implemented yet
290
283
 
291
284
    def visit_definition_list_item(self, node):
292
 
        pass
 
285
        raise nodes.SkipNode # Not implemented yet
293
286
 
294
287
    def depart_definition_list_item(self, node):
295
288
        pass
296
289
 
297
290
    def visit_term(self, node):
298
 
        pass
 
291
        raise nodes.SkipNode # Not implemented yet
299
292
 
300
293
    def depart_term(self, node):
301
294
        pass
302
295
 
303
296
    def visit_definition(self, node):
304
 
        pass
 
297
        raise nodes.SkipNode # Not implemented yet
305
298
 
306
299
    def depart_definition(self, node):
307
300
        pass
308
301
 
309
302
    def visit_field_list(self, node):
310
 
        pass
 
303
        raise nodes.SkipNode # Not implemented yet
 
304
 
311
305
    def depart_field_list(self, node):
312
306
        pass
313
307
 
314
308
    def visit_field(self, node):
315
 
        pass
 
309
        raise nodes.SkipNode # Not implemented yet
 
310
 
316
311
    def depart_field(self, node):
317
312
        pass
318
313
 
319
314
    def visit_field_name(self, node):
320
 
        pass
 
315
        raise nodes.SkipNode # Not implemented yet
321
316
 
322
317
    def depart_field_name(self, node):
323
318
        pass
324
319
 
325
320
    def visit_field_body(self, node):
326
 
        pass
 
321
        raise nodes.SkipNode # Not implemented yet
327
322
 
328
323
    def depart_field_body(self, node):
329
324
        pass
330
325
 
331
326
    def visit_list_item(self, node):
332
 
        set_item_list_collector(node, 'chunk')
 
327
        set_item_list_collector(node, 'text')
333
328
 
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)
337
332
 
338
333
    def visit_option_list(self, node):
339
 
        pass
 
334
        raise nodes.SkipNode # Not implemented yet
340
335
 
341
336
    def depart_option_list(self, node):
342
337
        pass
380
375
        set_item_collector(node, 'table')
381
376
 
382
377
    def depart_table(self, node):
383
 
        node.parent.collect_chunk(node['table'])
 
378
        node.parent.collect_text(node['table'])
384
379
 
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 ?
 
394
            # FIXME: need a test
 
395
            self._decorate_list(head_entries[1:], header.append,
 
396
                                ' @tab %s',
 
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'])
432
431
 
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 = ''
437
436
 
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']
441
440
 
442
441
    # References
449
448
        set_item_collector(node, 'text')
450
449
 
451
450
    def depart_reference(self, node):
452
 
        node.parent.collect_reference((node.get('anchorname', ''),
453
 
                                       node.get('refuri', ''),
454
 
                                       ''.join(node['text']),
455
 
                                       ))
 
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
                     ))
456
458
 
457
459
    def visit_footnote_reference(self, node):
458
 
        raise nodes.SkipNode
 
460
        raise nodes.SkipNode # Not implemented yet
459
461
 
460
462
    def visit_citation_reference(self, node):
461
 
        raise nodes.SkipNode
 
463
        raise nodes.SkipNode # Not implemented yet
462
464
 
463
465
    def visit_title_reference(self, node):
464
 
        pass
 
466
        raise nodes.SkipNode # Not implemented yet
465
467
 
466
468
    def depart_title_reference(self, node):
467
469
        pass
468
470
 
469
471
    def visit_target(self, node):
470
 
        pass
 
472
        raise nodes.SkipNode # Not implemented yet
471
473
 
472
474
    def depart_target(self, node):
473
475
        pass
474
476
 
475
477
    def visit_image(self, node):
476
 
        self.add_text(_('[image]'))
477
 
        raise nodes.SkipNode
 
478
        raise nodes.SkipNode # Not implemented yet
478
479
 
479
480
# Helpers to collect data in parent node
480
481