Mercurial > hg
comparison doc/hgmanpage.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 93a1a4fef532 |
children | 89a2afe31e82 |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
51 from docutils import ( | 51 from docutils import ( |
52 languages, | 52 languages, |
53 nodes, | 53 nodes, |
54 writers, | 54 writers, |
55 ) | 55 ) |
56 | |
56 try: | 57 try: |
57 import roman | 58 import roman |
58 except ImportError: | 59 except ImportError: |
59 from docutils.utils import roman | 60 from docutils.utils import roman |
60 | 61 |
63 OPTION_LIST_INDENT = 7 | 64 OPTION_LIST_INDENT = 7 |
64 BLOCKQOUTE_INDENT = 3.5 | 65 BLOCKQOUTE_INDENT = 3.5 |
65 | 66 |
66 # Define two macros so man/roff can calculate the | 67 # Define two macros so man/roff can calculate the |
67 # indent/unindent margins by itself | 68 # indent/unindent margins by itself |
68 MACRO_DEF = (r""". | 69 MACRO_DEF = r""". |
69 .nr rst2man-indent-level 0 | 70 .nr rst2man-indent-level 0 |
70 . | 71 . |
71 .de1 rstReportMargin | 72 .de1 rstReportMargin |
72 \\$1 \\n[an-margin] | 73 \\$1 \\n[an-margin] |
73 level \\n[rst2man-indent-level] | 74 level \\n[rst2man-indent-level] |
90 .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] | 91 .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] |
91 .nr rst2man-indent-level -1 | 92 .nr rst2man-indent-level -1 |
92 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] | 93 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] |
93 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u | 94 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u |
94 .. | 95 .. |
95 """) | 96 """ |
97 | |
96 | 98 |
97 class Writer(writers.Writer): | 99 class Writer(writers.Writer): |
98 | 100 |
99 supported = ('manpage') | 101 supported = 'manpage' |
100 """Formats this writer supports.""" | 102 """Formats this writer supports.""" |
101 | 103 |
102 output = None | 104 output = None |
103 """Final translated form of `document`.""" | 105 """Final translated form of `document`.""" |
104 | 106 |
116 def __init__(self): | 118 def __init__(self): |
117 self._rows = [] | 119 self._rows = [] |
118 self._options = ['center'] | 120 self._options = ['center'] |
119 self._tab_char = '\t' | 121 self._tab_char = '\t' |
120 self._coldefs = [] | 122 self._coldefs = [] |
123 | |
121 def new_row(self): | 124 def new_row(self): |
122 self._rows.append([]) | 125 self._rows.append([]) |
126 | |
123 def append_separator(self, separator): | 127 def append_separator(self, separator): |
124 """Append the separator for table head.""" | 128 """Append the separator for table head.""" |
125 self._rows.append([separator]) | 129 self._rows.append([separator]) |
130 | |
126 def append_cell(self, cell_lines): | 131 def append_cell(self, cell_lines): |
127 """cell_lines is an array of lines""" | 132 """cell_lines is an array of lines""" |
128 start = 0 | 133 start = 0 |
129 if len(cell_lines) > 0 and cell_lines[0] == '.sp\n': | 134 if len(cell_lines) > 0 and cell_lines[0] == '.sp\n': |
130 start = 1 | 135 start = 1 |
131 self._rows[-1].append(cell_lines[start:]) | 136 self._rows[-1].append(cell_lines[start:]) |
132 if len(self._coldefs) < len(self._rows[-1]): | 137 if len(self._coldefs) < len(self._rows[-1]): |
133 self._coldefs.append('l') | 138 self._coldefs.append('l') |
139 | |
134 def _minimize_cell(self, cell_lines): | 140 def _minimize_cell(self, cell_lines): |
135 """Remove leading and trailing blank and ``.sp`` lines""" | 141 """Remove leading and trailing blank and ``.sp`` lines""" |
136 while (cell_lines and cell_lines[0] in ('\n', '.sp\n')): | 142 while cell_lines and cell_lines[0] in ('\n', '.sp\n'): |
137 del cell_lines[0] | 143 del cell_lines[0] |
138 while (cell_lines and cell_lines[-1] in ('\n', '.sp\n')): | 144 while cell_lines and cell_lines[-1] in ('\n', '.sp\n'): |
139 del cell_lines[-1] | 145 del cell_lines[-1] |
146 | |
140 def as_list(self): | 147 def as_list(self): |
141 text = ['.TS\n'] | 148 text = ['.TS\n'] |
142 text.append(' '.join(self._options) + ';\n') | 149 text.append(' '.join(self._options) + ';\n') |
143 text.append('|%s|.\n' % ('|'.join(self._coldefs))) | 150 text.append('|%s|.\n' % ('|'.join(self._coldefs))) |
144 for row in self._rows: | 151 for row in self._rows: |
145 # row = array of cells. cell = array of lines. | 152 # row = array of cells. cell = array of lines. |
146 text.append('_\n') # line above | 153 text.append('_\n') # line above |
147 text.append('T{\n') | 154 text.append('T{\n') |
148 for i in range(len(row)): | 155 for i in range(len(row)): |
149 cell = row[i] | 156 cell = row[i] |
150 self._minimize_cell(cell) | 157 self._minimize_cell(cell) |
151 text.extend(cell) | 158 text.extend(cell) |
152 if not text[-1].endswith('\n'): | 159 if not text[-1].endswith('\n'): |
153 text[-1] += '\n' | 160 text[-1] += '\n' |
154 if i < len(row) - 1: | 161 if i < len(row) - 1: |
155 text.append('T}'+self._tab_char+'T{\n') | 162 text.append('T}' + self._tab_char + 'T{\n') |
156 else: | 163 else: |
157 text.append('T}\n') | 164 text.append('T}\n') |
158 text.append('_\n') | 165 text.append('_\n') |
159 text.append('.TE\n') | 166 text.append('.TE\n') |
160 return text | 167 return text |
168 | |
161 | 169 |
162 class Translator(nodes.NodeVisitor): | 170 class Translator(nodes.NodeVisitor): |
163 """""" | 171 """""" |
164 | 172 |
165 words_and_spaces = re.compile(r'\S+| +|\n') | 173 words_and_spaces = re.compile(r'\S+| +|\n') |
169 nodes.NodeVisitor.__init__(self, document) | 177 nodes.NodeVisitor.__init__(self, document) |
170 self.settings = settings = document.settings | 178 self.settings = settings = document.settings |
171 lcode = settings.language_code | 179 lcode = settings.language_code |
172 arglen = len(inspect.getargspec(languages.get_language)[0]) | 180 arglen = len(inspect.getargspec(languages.get_language)[0]) |
173 if arglen == 2: | 181 if arglen == 2: |
174 self.language = languages.get_language(lcode, | 182 self.language = languages.get_language( |
175 self.document.reporter) | 183 lcode, self.document.reporter |
184 ) | |
176 else: | 185 else: |
177 self.language = languages.get_language(lcode) | 186 self.language = languages.get_language(lcode) |
178 self.head = [] | 187 self.head = [] |
179 self.body = [] | 188 self.body = [] |
180 self.foot = [] | 189 self.foot = [] |
187 # the list style "*" bullet or "#" numbered | 196 # the list style "*" bullet or "#" numbered |
188 self._list_char = [] | 197 self._list_char = [] |
189 # writing the header .TH and .SH NAME is postboned after | 198 # writing the header .TH and .SH NAME is postboned after |
190 # docinfo. | 199 # docinfo. |
191 self._docinfo = { | 200 self._docinfo = { |
192 "title" : "", "title_upper": "", | 201 "title": "", |
193 "subtitle" : "", | 202 "title_upper": "", |
194 "manual_section" : "", "manual_group" : "", | 203 "subtitle": "", |
195 "author" : [], | 204 "manual_section": "", |
196 "date" : "", | 205 "manual_group": "", |
197 "copyright" : "", | 206 "author": [], |
198 "version" : "", | 207 "date": "", |
199 } | 208 "copyright": "", |
200 self._docinfo_keys = [] # a list to keep the sequence as in source. | 209 "version": "", |
201 self._docinfo_names = {} # to get name from text not normalized. | 210 } |
211 self._docinfo_keys = [] # a list to keep the sequence as in source. | |
212 self._docinfo_names = {} # to get name from text not normalized. | |
202 self._in_docinfo = None | 213 self._in_docinfo = None |
203 self._active_table = None | 214 self._active_table = None |
204 self._in_literal = False | 215 self._in_literal = False |
205 self.header_written = 0 | 216 self.header_written = 0 |
206 self._line_block = 0 | 217 self._line_block = 0 |
215 # Fonts are put on a stack, the top one is used. | 226 # Fonts are put on a stack, the top one is used. |
216 # ``.ft P`` or ``\\fP`` pop from stack. | 227 # ``.ft P`` or ``\\fP`` pop from stack. |
217 # ``B`` bold, ``I`` italic, ``R`` roman should be available. | 228 # ``B`` bold, ``I`` italic, ``R`` roman should be available. |
218 # Hopefully ``C`` courier too. | 229 # Hopefully ``C`` courier too. |
219 self.defs = { | 230 self.defs = { |
220 'indent' : ('.INDENT %.1f\n', '.UNINDENT\n'), | 231 'indent': ('.INDENT %.1f\n', '.UNINDENT\n'), |
221 'definition_list_item' : ('.TP', ''), | 232 'definition_list_item': ('.TP', ''), |
222 'field_name' : ('.TP\n.B ', '\n'), | 233 'field_name': ('.TP\n.B ', '\n'), |
223 'literal' : ('\\fB', '\\fP'), | 234 'literal': ('\\fB', '\\fP'), |
224 'literal_block' : ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'), | 235 'literal_block': ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'), |
225 | 236 'option_list_item': ('.TP\n', ''), |
226 'option_list_item' : ('.TP\n', ''), | 237 'reference': (r'\%', r'\:'), |
227 | 238 'emphasis': ('\\fI', '\\fP'), |
228 'reference' : (r'\%', r'\:'), | 239 'strong': ('\\fB', '\\fP'), |
229 'emphasis': ('\\fI', '\\fP'), | 240 'term': ('\n.B ', '\n'), |
230 'strong' : ('\\fB', '\\fP'), | 241 'title_reference': ('\\fI', '\\fP'), |
231 'term' : ('\n.B ', '\n'), | 242 'topic-title': ('.SS ',), |
232 'title_reference' : ('\\fI', '\\fP'), | 243 'sidebar-title': ('.SS ',), |
233 | 244 'problematic': ('\n.nf\n', '\n.fi\n'), |
234 'topic-title' : ('.SS ',), | 245 } |
235 'sidebar-title' : ('.SS ',), | |
236 | |
237 'problematic' : ('\n.nf\n', '\n.fi\n'), | |
238 } | |
239 # NOTE don't specify the newline before a dot-command, but ensure | 246 # NOTE don't specify the newline before a dot-command, but ensure |
240 # it is there. | 247 # it is there. |
241 | 248 |
242 def comment_begin(self, text): | 249 def comment_begin(self, text): |
243 """Return commented version of the passed text WITHOUT end of | 250 """Return commented version of the passed text WITHOUT end of |
244 line/comment.""" | 251 line/comment.""" |
245 prefix = '.\\" ' | 252 prefix = '.\\" ' |
246 out_text = ''.join( | 253 out_text = ''.join( |
247 [(prefix + in_line + '\n') | 254 [(prefix + in_line + '\n') for in_line in text.split('\n')] |
248 for in_line in text.split('\n')]) | 255 ) |
249 return out_text | 256 return out_text |
250 | 257 |
251 def comment(self, text): | 258 def comment(self, text): |
252 """Return commented version of the passed text.""" | 259 """Return commented version of the passed text.""" |
253 return self.comment_begin(text)+'.\n' | 260 return self.comment_begin(text) + '.\n' |
254 | 261 |
255 def ensure_eol(self): | 262 def ensure_eol(self): |
256 """Ensure the last line in body is terminated by new line.""" | 263 """Ensure the last line in body is terminated by new line.""" |
257 if self.body[-1][-1] != '\n': | 264 if self.body[-1][-1] != '\n': |
258 self.body.append('\n') | 265 self.body.append('\n') |
264 self.head.append(self.header()) | 271 self.head.append(self.header()) |
265 # filter body | 272 # filter body |
266 for i in range(len(self.body) - 1, 0, -1): | 273 for i in range(len(self.body) - 1, 0, -1): |
267 # remove superfluous vertical gaps. | 274 # remove superfluous vertical gaps. |
268 if self.body[i] == '.sp\n': | 275 if self.body[i] == '.sp\n': |
269 if self.body[i - 1][:4] in ('.BI ','.IP '): | 276 if self.body[i - 1][:4] in ('.BI ', '.IP '): |
270 self.body[i] = '.\n' | 277 self.body[i] = '.\n' |
271 elif (self.body[i - 1][:3] == '.B ' and | 278 elif ( |
272 self.body[i - 2][:4] == '.TP\n'): | 279 self.body[i - 1][:3] == '.B ' |
280 and self.body[i - 2][:4] == '.TP\n' | |
281 ): | |
273 self.body[i] = '.\n' | 282 self.body[i] = '.\n' |
274 elif (self.body[i - 1] == '\n' and | 283 elif ( |
275 self.body[i - 2][0] != '.' and | 284 self.body[i - 1] == '\n' |
276 (self.body[i - 3][:7] == '.TP\n.B ' | 285 and self.body[i - 2][0] != '.' |
277 or self.body[i - 3][:4] == '\n.B ') | 286 and ( |
278 ): | 287 self.body[i - 3][:7] == '.TP\n.B ' |
288 or self.body[i - 3][:4] == '\n.B ' | |
289 ) | |
290 ): | |
279 self.body[i] = '.\n' | 291 self.body[i] = '.\n' |
280 return ''.join(self.head + self.body + self.foot) | 292 return ''.join(self.head + self.body + self.foot) |
281 | 293 |
282 def deunicode(self, text): | 294 def deunicode(self, text): |
283 text = text.replace(u'\xa0', '\\ ') | 295 text = text.replace(u'\xa0', '\\ ') |
284 text = text.replace(u'\u2020', '\\(dg') | 296 text = text.replace(u'\u2020', '\\(dg') |
285 return text | 297 return text |
286 | 298 |
287 def visit_Text(self, node): | 299 def visit_Text(self, node): |
288 text = node.astext() | 300 text = node.astext() |
289 text = text.replace('\\','\\e') | 301 text = text.replace('\\', '\\e') |
290 replace_pairs = [ | 302 replace_pairs = [ |
291 (u'-', u'\\-'), | 303 (u'-', u'\\-'), |
292 (u"'", u'\\(aq'), | 304 (u"'", u'\\(aq'), |
293 (u'´', u"\\'"), | 305 (u'´', u"\\'"), |
294 (u'`', u'\\(ga'), | 306 (u'`', u'\\(ga'), |
295 ] | 307 ] |
296 for (in_char, out_markup) in replace_pairs: | 308 for (in_char, out_markup) in replace_pairs: |
297 text = text.replace(in_char, out_markup) | 309 text = text.replace(in_char, out_markup) |
298 # unicode | 310 # unicode |
299 text = self.deunicode(text) | 311 text = self.deunicode(text) |
300 if self._in_literal: | 312 if self._in_literal: |
308 pass | 320 pass |
309 | 321 |
310 def list_start(self, node): | 322 def list_start(self, node): |
311 class enum_char(object): | 323 class enum_char(object): |
312 enum_style = { | 324 enum_style = { |
313 'bullet' : '\\(bu', | 325 'bullet': '\\(bu', |
314 'emdash' : '\\(em', | 326 'emdash': '\\(em', |
315 } | 327 } |
316 | 328 |
317 def __init__(self, style): | 329 def __init__(self, style): |
318 self._style = style | 330 self._style = style |
319 if 'start' in node: | 331 if 'start' in node: |
320 self._cnt = node['start'] - 1 | 332 self._cnt = node['start'] - 1 |
356 | 368 |
357 next = __next__ | 369 next = __next__ |
358 | 370 |
359 def get_width(self): | 371 def get_width(self): |
360 return self._indent | 372 return self._indent |
373 | |
361 def __repr__(self): | 374 def __repr__(self): |
362 return 'enum_style-%s' % list(self._style) | 375 return 'enum_style-%s' % list(self._style) |
363 | 376 |
364 if 'enumtype' in node: | 377 if 'enumtype' in node: |
365 self._list_char.append(enum_char(node['enumtype'])) | 378 self._list_char.append(enum_char(node['enumtype'])) |
374 def list_end(self): | 387 def list_end(self): |
375 self.dedent() | 388 self.dedent() |
376 self._list_char.pop() | 389 self._list_char.pop() |
377 | 390 |
378 def header(self): | 391 def header(self): |
379 tmpl = (".TH %(title_upper)s %(manual_section)s" | 392 tmpl = ( |
380 " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n" | 393 ".TH %(title_upper)s %(manual_section)s" |
381 ".SH NAME\n" | 394 " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n" |
382 "%(title)s \\- %(subtitle)s\n") | 395 ".SH NAME\n" |
396 "%(title)s \\- %(subtitle)s\n" | |
397 ) | |
383 return tmpl % self._docinfo | 398 return tmpl % self._docinfo |
384 | 399 |
385 def append_header(self): | 400 def append_header(self): |
386 """append header with .TH and .SH NAME""" | 401 """append header with .TH and .SH NAME""" |
387 # NOTE before everything | 402 # NOTE before everything |
398 def depart_address(self, node): | 413 def depart_address(self, node): |
399 pass | 414 pass |
400 | 415 |
401 def visit_admonition(self, node, name=None): | 416 def visit_admonition(self, node, name=None): |
402 if name: | 417 if name: |
403 self.body.append('.IP %s\n' % | 418 self.body.append('.IP %s\n' % self.language.labels.get(name, name)) |
404 self.language.labels.get(name, name)) | |
405 | 419 |
406 def depart_admonition(self, node): | 420 def depart_admonition(self, node): |
407 self.body.append('.RE\n') | 421 self.body.append('.RE\n') |
408 | 422 |
409 def visit_attention(self, node): | 423 def visit_attention(self, node): |
468 | 482 |
469 def depart_citation(self, node): | 483 def depart_citation(self, node): |
470 pass | 484 pass |
471 | 485 |
472 def visit_citation_reference(self, node): | 486 def visit_citation_reference(self, node): |
473 self.body.append('['+node.astext()+']') | 487 self.body.append('[' + node.astext() + ']') |
474 raise nodes.SkipNode() | 488 raise nodes.SkipNode() |
475 | 489 |
476 def visit_classifier(self, node): | 490 def visit_classifier(self, node): |
477 pass | 491 pass |
478 | 492 |
484 | 498 |
485 def depart_colspec(self, node): | 499 def depart_colspec(self, node): |
486 pass | 500 pass |
487 | 501 |
488 def write_colspecs(self): | 502 def write_colspecs(self): |
489 self.body.append("%s.\n" % ('L '*len(self.colspecs))) | 503 self.body.append("%s.\n" % ('L ' * len(self.colspecs))) |
490 | 504 |
491 def visit_comment(self, node, | 505 def visit_comment(self, node, sub=re.compile('-(?=-)').sub): |
492 sub=re.compile('-(?=-)').sub): | |
493 self.body.append(self.comment(node.astext())) | 506 self.body.append(self.comment(node.astext())) |
494 raise nodes.SkipNode() | 507 raise nodes.SkipNode() |
495 | 508 |
496 def visit_contact(self, node): | 509 def visit_contact(self, node): |
497 self.visit_docinfo_item(node, 'contact') | 510 self.visit_docinfo_item(node, 'contact') |
567 self._in_literal = False | 580 self._in_literal = False |
568 self.body.append(self.defs['literal_block'][1]) | 581 self.body.append(self.defs['literal_block'][1]) |
569 | 582 |
570 def visit_document(self, node): | 583 def visit_document(self, node): |
571 # no blank line between comment and header. | 584 # no blank line between comment and header. |
572 self.body.append(self.comment(self.document_start).rstrip()+'\n') | 585 self.body.append(self.comment(self.document_start).rstrip() + '\n') |
573 # writing header is postboned | 586 # writing header is postboned |
574 self.header_written = 0 | 587 self.header_written = 0 |
575 | 588 |
576 def depart_document(self, node): | 589 def depart_document(self, node): |
577 if self._docinfo['author']: | 590 if self._docinfo['author']: |
578 self.body.append('.SH AUTHOR\n%s\n' | 591 self.body.append( |
579 % ', '.join(self._docinfo['author'])) | 592 '.SH AUTHOR\n%s\n' % ', '.join(self._docinfo['author']) |
580 skip = ('author', 'copyright', 'date', | 593 ) |
581 'manual_group', 'manual_section', | 594 skip = ( |
582 'subtitle', | 595 'author', |
583 'title', 'title_upper', 'version') | 596 'copyright', |
597 'date', | |
598 'manual_group', | |
599 'manual_section', | |
600 'subtitle', | |
601 'title', | |
602 'title_upper', | |
603 'version', | |
604 ) | |
584 for name in self._docinfo_keys: | 605 for name in self._docinfo_keys: |
585 if name == 'address': | 606 if name == 'address': |
586 self.body.append("\n%s:\n%s%s.nf\n%s\n.fi\n%s%s" % ( | 607 self.body.append( |
587 self.language.labels.get(name, name), | 608 "\n%s:\n%s%s.nf\n%s\n.fi\n%s%s" |
588 self.defs['indent'][0] % 0, | 609 % ( |
589 self.defs['indent'][0] % BLOCKQOUTE_INDENT, | 610 self.language.labels.get(name, name), |
590 self._docinfo[name], | 611 self.defs['indent'][0] % 0, |
591 self.defs['indent'][1], | 612 self.defs['indent'][0] % BLOCKQOUTE_INDENT, |
592 self.defs['indent'][1])) | 613 self._docinfo[name], |
614 self.defs['indent'][1], | |
615 self.defs['indent'][1], | |
616 ) | |
617 ) | |
593 elif name not in skip: | 618 elif name not in skip: |
594 if name in self._docinfo_names: | 619 if name in self._docinfo_names: |
595 label = self._docinfo_names[name] | 620 label = self._docinfo_names[name] |
596 else: | 621 else: |
597 label = self.language.labels.get(name, name) | 622 label = self.language.labels.get(name, name) |
598 self.body.append("\n%s: %s\n" % (label, self._docinfo[name])) | 623 self.body.append("\n%s: %s\n" % (label, self._docinfo[name])) |
599 if self._docinfo['copyright']: | 624 if self._docinfo['copyright']: |
600 self.body.append('.SH COPYRIGHT\n%s\n' | 625 self.body.append('.SH COPYRIGHT\n%s\n' % self._docinfo['copyright']) |
601 % self._docinfo['copyright']) | 626 self.body.append( |
602 self.body.append(self.comment( | 627 self.comment('Generated by docutils manpage writer.\n') |
603 'Generated by docutils manpage writer.\n')) | 628 ) |
604 | 629 |
605 def visit_emphasis(self, node): | 630 def visit_emphasis(self, node): |
606 self.body.append(self.defs['emphasis'][0]) | 631 self.body.append(self.defs['emphasis'][0]) |
607 | 632 |
608 def depart_emphasis(self, node): | 633 def depart_emphasis(self, node): |
609 self.body.append(self.defs['emphasis'][1]) | 634 self.body.append(self.defs['emphasis'][1]) |
610 | 635 |
611 def visit_entry(self, node): | 636 def visit_entry(self, node): |
612 # a cell in a table row | 637 # a cell in a table row |
613 if 'morerows' in node: | 638 if 'morerows' in node: |
614 self.document.reporter.warning('"table row spanning" not supported', | 639 self.document.reporter.warning( |
615 base_node=node) | 640 '"table row spanning" not supported', base_node=node |
641 ) | |
616 if 'morecols' in node: | 642 if 'morecols' in node: |
617 self.document.reporter.warning( | 643 self.document.reporter.warning( |
618 '"table cell spanning" not supported', base_node=node) | 644 '"table cell spanning" not supported', base_node=node |
645 ) | |
619 self.context.append(len(self.body)) | 646 self.context.append(len(self.body)) |
620 | 647 |
621 def depart_entry(self, node): | 648 def depart_entry(self, node): |
622 start = self.context.pop() | 649 start = self.context.pop() |
623 self._active_table.append_cell(self.body[start:]) | 650 self._active_table.append_cell(self.body[start:]) |
640 def depart_field(self, node): | 667 def depart_field(self, node): |
641 pass | 668 pass |
642 | 669 |
643 def visit_field_body(self, node): | 670 def visit_field_body(self, node): |
644 if self._in_docinfo: | 671 if self._in_docinfo: |
645 name_normalized = self._field_name.lower().replace(" ","_") | 672 name_normalized = self._field_name.lower().replace(" ", "_") |
646 self._docinfo_names[name_normalized] = self._field_name | 673 self._docinfo_names[name_normalized] = self._field_name |
647 self.visit_docinfo_item(node, name_normalized) | 674 self.visit_docinfo_item(node, name_normalized) |
648 raise nodes.SkipNode() | 675 raise nodes.SkipNode() |
649 | 676 |
650 def depart_field_body(self, node): | 677 def depart_field_body(self, node): |
673 def depart_figure(self, node): | 700 def depart_figure(self, node): |
674 self.dedent() | 701 self.dedent() |
675 self.dedent() | 702 self.dedent() |
676 | 703 |
677 def visit_footer(self, node): | 704 def visit_footer(self, node): |
678 self.document.reporter.warning('"footer" not supported', | 705 self.document.reporter.warning('"footer" not supported', base_node=node) |
679 base_node=node) | |
680 | 706 |
681 def depart_footer(self, node): | 707 def depart_footer(self, node): |
682 pass | 708 pass |
683 | 709 |
684 def visit_footnote(self, node): | 710 def visit_footnote(self, node): |
688 | 714 |
689 def depart_footnote(self, node): | 715 def depart_footnote(self, node): |
690 pass | 716 pass |
691 | 717 |
692 def footnote_backrefs(self, node): | 718 def footnote_backrefs(self, node): |
693 self.document.reporter.warning('"footnote_backrefs" not supported', | 719 self.document.reporter.warning( |
694 base_node=node) | 720 '"footnote_backrefs" not supported', base_node=node |
721 ) | |
695 | 722 |
696 def visit_footnote_reference(self, node): | 723 def visit_footnote_reference(self, node): |
697 self.body.append('['+self.deunicode(node.astext())+']') | 724 self.body.append('[' + self.deunicode(node.astext()) + ']') |
698 raise nodes.SkipNode() | 725 raise nodes.SkipNode() |
699 | 726 |
700 def depart_footnote_reference(self, node): | 727 def depart_footnote_reference(self, node): |
701 pass | 728 pass |
702 | 729 |
734 | 761 |
735 def depart_attribution(self, node): | 762 def depart_attribution(self, node): |
736 self.body.append('\n') | 763 self.body.append('\n') |
737 | 764 |
738 def visit_image(self, node): | 765 def visit_image(self, node): |
739 self.document.reporter.warning('"image" not supported', | 766 self.document.reporter.warning('"image" not supported', base_node=node) |
740 base_node=node) | |
741 text = [] | 767 text = [] |
742 if 'alt' in node.attributes: | 768 if 'alt' in node.attributes: |
743 text.append(node.attributes['alt']) | 769 text.append(node.attributes['alt']) |
744 if 'uri' in node.attributes: | 770 if 'uri' in node.attributes: |
745 text.append(node.attributes['uri']) | 771 text.append(node.attributes['uri']) |
751 | 777 |
752 depart_important = depart_admonition | 778 depart_important = depart_admonition |
753 | 779 |
754 def visit_label(self, node): | 780 def visit_label(self, node): |
755 # footnote and citation | 781 # footnote and citation |
756 if (isinstance(node.parent, nodes.footnote) | 782 if isinstance(node.parent, nodes.footnote) or isinstance( |
757 or isinstance(node.parent, nodes.citation)): | 783 node.parent, nodes.citation |
784 ): | |
758 raise nodes.SkipNode() | 785 raise nodes.SkipNode() |
759 self.document.reporter.warning('"unsupported "label"', | 786 self.document.reporter.warning('"unsupported "label"', base_node=node) |
760 base_node=node) | |
761 self.body.append('[') | 787 self.body.append('[') |
762 | 788 |
763 def depart_label(self, node): | 789 def depart_label(self, node): |
764 self.body.append(']\n') | 790 self.body.append(']\n') |
765 | 791 |
792 def depart_line(self, node): | 818 def depart_line(self, node): |
793 self.body.append('\n') | 819 self.body.append('\n') |
794 | 820 |
795 def visit_list_item(self, node): | 821 def visit_list_item(self, node): |
796 # man 7 man argues to use ".IP" instead of ".TP" | 822 # man 7 man argues to use ".IP" instead of ".TP" |
797 self.body.append('.IP %s %d\n' % ( | 823 self.body.append( |
798 next(self._list_char[-1]), | 824 '.IP %s %d\n' |
799 self._list_char[-1].get_width(),)) | 825 % (next(self._list_char[-1]), self._list_char[-1].get_width(),) |
826 ) | |
800 | 827 |
801 def depart_list_item(self, node): | 828 def depart_list_item(self, node): |
802 pass | 829 pass |
803 | 830 |
804 def visit_literal(self, node): | 831 def visit_literal(self, node): |
853 # as one option could have several forms it is a group | 880 # as one option could have several forms it is a group |
854 # options without parameter bold only, .B, -v | 881 # options without parameter bold only, .B, -v |
855 # options with parameter bold italic, .BI, -f file | 882 # options with parameter bold italic, .BI, -f file |
856 # | 883 # |
857 # we do not know if .B or .BI | 884 # we do not know if .B or .BI |
858 self.context.append('.B') # blind guess | 885 self.context.append('.B') # blind guess |
859 self.context.append(len(self.body)) # to be able to insert later | 886 self.context.append(len(self.body)) # to be able to insert later |
860 self.context.append(0) # option counter | 887 self.context.append(0) # option counter |
861 | 888 |
862 def depart_option_group(self, node): | 889 def depart_option_group(self, node): |
863 self.context.pop() # the counter | 890 self.context.pop() # the counter |
864 start_position = self.context.pop() | 891 start_position = self.context.pop() |
865 text = self.body[start_position:] | 892 text = self.body[start_position:] |
883 | 910 |
884 def depart_option_string(self, node): | 911 def depart_option_string(self, node): |
885 pass | 912 pass |
886 | 913 |
887 def visit_option_argument(self, node): | 914 def visit_option_argument(self, node): |
888 self.context[-3] = '.BI' # bold/italic alternate | 915 self.context[-3] = '.BI' # bold/italic alternate |
889 if node['delimiter'] != ' ': | 916 if node['delimiter'] != ' ': |
890 self.body.append('\\fB%s ' % node['delimiter']) | 917 self.body.append('\\fB%s ' % node['delimiter']) |
891 elif self.body[len(self.body) - 1].endswith('='): | 918 elif self.body[len(self.body) - 1].endswith('='): |
892 # a blank only means no blank in output, just changing font | 919 # a blank only means no blank in output, just changing font |
893 self.body.append(' ') | 920 self.body.append(' ') |
966 def visit_substitution_definition(self, node): | 993 def visit_substitution_definition(self, node): |
967 """Internal only.""" | 994 """Internal only.""" |
968 raise nodes.SkipNode() | 995 raise nodes.SkipNode() |
969 | 996 |
970 def visit_substitution_reference(self, node): | 997 def visit_substitution_reference(self, node): |
971 self.document.reporter.warning('"substitution_reference" not supported', | 998 self.document.reporter.warning( |
972 base_node=node) | 999 '"substitution_reference" not supported', base_node=node |
1000 ) | |
973 | 1001 |
974 def visit_subtitle(self, node): | 1002 def visit_subtitle(self, node): |
975 if isinstance(node.parent, nodes.sidebar): | 1003 if isinstance(node.parent, nodes.sidebar): |
976 self.body.append(self.defs['strong'][0]) | 1004 self.body.append(self.defs['strong'][0]) |
977 elif isinstance(node.parent, nodes.document): | 1005 elif isinstance(node.parent, nodes.document): |
979 elif isinstance(node.parent, nodes.section): | 1007 elif isinstance(node.parent, nodes.section): |
980 self.body.append(self.defs['strong'][0]) | 1008 self.body.append(self.defs['strong'][0]) |
981 | 1009 |
982 def depart_subtitle(self, node): | 1010 def depart_subtitle(self, node): |
983 # document subtitle calls SkipNode | 1011 # document subtitle calls SkipNode |
984 self.body.append(self.defs['strong'][1]+'\n.PP\n') | 1012 self.body.append(self.defs['strong'][1] + '\n.PP\n') |
985 | 1013 |
986 def visit_system_message(self, node): | 1014 def visit_system_message(self, node): |
987 # TODO add report_level | 1015 # TODO add report_level |
988 #if node['level'] < self.document.reporter['writer'].report_level: | 1016 # if node['level'] < self.document.reporter['writer'].report_level: |
989 # Level is too low to display: | 1017 # Level is too low to display: |
990 # raise nodes.SkipNode | 1018 # raise nodes.SkipNode |
991 attr = {} | 1019 attr = {} |
992 if node.hasattr('id'): | 1020 if node.hasattr('id'): |
993 attr['name'] = node['id'] | 1021 attr['name'] = node['id'] |
994 if node.hasattr('line'): | 1022 if node.hasattr('line'): |
995 line = ', line %s' % node['line'] | 1023 line = ', line %s' % node['line'] |
996 else: | 1024 else: |
997 line = '' | 1025 line = '' |
998 self.body.append('.IP "System Message: %s/%s (%s:%s)"\n' | 1026 self.body.append( |
999 % (node['type'], node['level'], node['source'], line)) | 1027 '.IP "System Message: %s/%s (%s:%s)"\n' |
1028 % (node['type'], node['level'], node['source'], line) | |
1029 ) | |
1000 | 1030 |
1001 def depart_system_message(self, node): | 1031 def depart_system_message(self, node): |
1002 pass | 1032 pass |
1003 | 1033 |
1004 def visit_table(self, node): | 1034 def visit_table(self, node): |
1109 self.visit_admonition(node, 'warning') | 1139 self.visit_admonition(node, 'warning') |
1110 | 1140 |
1111 depart_warning = depart_admonition | 1141 depart_warning = depart_admonition |
1112 | 1142 |
1113 def unimplemented_visit(self, node): | 1143 def unimplemented_visit(self, node): |
1114 raise NotImplementedError('visiting unimplemented node type: %s' | 1144 raise NotImplementedError( |
1115 % node.__class__.__name__) | 1145 'visiting unimplemented node type: %s' % node.__class__.__name__ |
1146 ) | |
1147 | |
1116 | 1148 |
1117 # vim: set fileencoding=utf-8 et ts=4 ai : | 1149 # vim: set fileencoding=utf-8 et ts=4 ai : |