From 71471311459338a23a5b9bb4107f2cc0a32462ba Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Mon, 27 Jun 2011 18:45:00 -0500 Subject: [PATCH 1/7] Add method ``ensure_eol`` and use it to fix paragraph spacing in Texinfo. --- sphinx/writers/texinfo.py | 54 ++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 7eb63c842..7ca2801bc 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -348,6 +348,11 @@ class TexinfoTranslator(nodes.NodeVisitor): s = ' '.join(s.split()).strip() return s + def ensure_eol(self): + """Ensure the last line in body is terminated by new line.""" + if self.body and self.body[-1][-1:] != '\n': + self.body.append('\n') + def format_menu_entry(self, name, node_name, desc): if name == node_name: s = '* %s:: ' % (name,) @@ -703,7 +708,8 @@ class TexinfoTranslator(nodes.NodeVisitor): def visit_block_quote(self, node): self.body.append('\n@quotation\n') def depart_block_quote(self, node): - self.body.append('\n@end quotation\n\n') + self.ensure_eol() + self.body.append('@end quotation\n') def visit_literal_block(self, node): self.body.append('\n@example\n') @@ -795,7 +801,8 @@ class TexinfoTranslator(nodes.NodeVisitor): bullet = node.get('bullet', '*') self.body.append('\n\n@itemize %s\n' % bullet) def depart_bullet_list(self, node): - self.body.append('\n@end itemize\n\n') + self.ensure_eol() + self.body.append('@end itemize\n') def visit_enumerated_list(self, node): # doesn't support Roman numerals @@ -806,10 +813,11 @@ class TexinfoTranslator(nodes.NodeVisitor): start = node.get('start', starters.get(enum, '')) self.body.append('\n\n@enumerate %s\n' % start) def depart_enumerated_list(self, node): - self.body.append('\n@end enumerate\n\n') + self.ensure_eol() + self.body.append('@end enumerate\n') def visit_list_item(self, node): - self.body.append('\n@item\n') + self.body.append('\n@item ') def depart_list_item(self, node): pass @@ -818,7 +826,8 @@ class TexinfoTranslator(nodes.NodeVisitor): def visit_option_list(self, node): self.body.append('\n\n@table @option\n') def depart_option_list(self, node): - self.body.append('\n@end table\n\n') + self.ensure_eol() + self.body.append('@end table\n') def visit_option_list_item(self, node): pass @@ -856,7 +865,8 @@ class TexinfoTranslator(nodes.NodeVisitor): def visit_definition_list(self, node): self.body.append('\n\n@table @asis\n') def depart_definition_list(self, node): - self.body.append('\n@end table\n\n') + self.ensure_eol() + self.body.append('@end table\n') def visit_definition_list_item(self, node): self.at_item_x = '@item' @@ -946,7 +956,8 @@ class TexinfoTranslator(nodes.NodeVisitor): def visit_field_list(self, node): self.body.append('\n\n@itemize @w\n') def depart_field_list(self, node): - self.body.append('\n@end itemize\n\n') + self.ensure_eol() + self.body.append('@end itemize\n') def visit_field(self, node): if not isinstance(node.parent, nodes.field_list): @@ -971,15 +982,15 @@ class TexinfoTranslator(nodes.NodeVisitor): if not name: name = self.escape(node[0].astext()) self.body.append('\n@cartouche\n' - '@quotation %s\n' % name) + '@quotation %s ' % name) def depart_admonition(self, node): - self.body.append('\n@end quotation\n' - '@end cartouche\n\n') + self.ensure_eol() + self.body.append('@end quotation\n' + '@end cartouche\n') def _make_visit_admonition(typ): def visit(self, node): - self.body.append('\n@cartouche\n' - '@quotation %s\n' % self.escape(_(typ))) + self.visit_admonition(node, self.escape(_(typ))) return visit visit_attention = _make_visit_admonition('Attention') @@ -1083,7 +1094,7 @@ class TexinfoTranslator(nodes.NodeVisitor): width = self.tex_image_length(attrs.get('width', '')) height = self.tex_image_length(attrs.get('height', '')) alt = self.escape_arg(attrs.get('alt', '')) - self.body.append('\n\n@image{%s,%s,%s,%s,%s}\n\n' % + self.body.append('\n@image{%s,%s,%s,%s,%s}\n' % (name, width, height, alt, ext[1:])) def depart_image(self, node): pass @@ -1127,8 +1138,9 @@ class TexinfoTranslator(nodes.NodeVisitor): pass def visit_comment(self, node): + self.body.append('\n') for line in node.astext().splitlines(): - self.body.append('\n@c %s\n' % line) + self.body.append('@c %s\n' % line) raise nodes.SkipNode def visit_problematic(self, node): @@ -1181,12 +1193,12 @@ class TexinfoTranslator(nodes.NodeVisitor): for entry in node['entries']: typ, text, tid, text2 = entry text = self.escape_menu(text) - self.body.append('@geindex %s\n' % text) + self.body.append('\n@geindex %s\n' % text) def visit_refcount(self, node): self.body.append('\n') def depart_refcount(self, node): - self.body.append('\n\n') + self.body.append('\n') def visit_versionmodified(self, node): intro = versionlabels[node['type']] % node['version'] @@ -1194,9 +1206,9 @@ class TexinfoTranslator(nodes.NodeVisitor): intro += ': ' else: intro += '.' - self.body.append('\n\n%s' % self.escape(intro)) + self.body.append('\n%s' % self.escape(intro)) def depart_versionmodified(self, node): - self.body.append('\n\n') + self.body.append('\n') def visit_start_of_file(self, node): # add a document target @@ -1257,7 +1269,9 @@ class TexinfoTranslator(nodes.NodeVisitor): def visit_desc(self, node): self.at_deffnx = '@deffn' def depart_desc(self, node): - self.body.append('\n@end deffn\n\n') + self.ensure_eol() + self.body.append('@end deffn\n') + def visit_desc_signature(self, node): self.desctype = node.parent['desctype'].strip() if self.desctype != 'describe': @@ -1313,7 +1327,7 @@ class TexinfoTranslator(nodes.NodeVisitor): raise nodes.SkipNode def visit_desc_content(self, node): - self.body.append("\n") + pass def depart_desc_content(self, node): pass From 10e0fb8ad90a1cf8ca3c61dc23dde4a1875cc86b Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Mon, 27 Jun 2011 19:28:47 -0500 Subject: [PATCH 2/7] Properly escape ``quote'' characters in Texinfo. --- sphinx/writers/texinfo.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 7ca2801bc..9e7414c58 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -319,6 +319,9 @@ class TexinfoTranslator(nodes.NodeVisitor): s = s.replace('@', '@@') s = s.replace('{', '@{') s = s.replace('}', '@}') + # prevent `` and '' quote conversion + s = s.replace('``', "`@w{`}") + s = s.replace("''", "'@w{'}") # prevent "--" from being converted to an "em dash" # s = s.replace('-', '@w{-}') return s From 584dc318838d9afea728c1769b71e89d5d852a54 Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Mon, 27 Jun 2011 19:51:00 -0500 Subject: [PATCH 3/7] Replace no-break spaces with normal ones inside desc_parameters for Texinfo. --- sphinx/writers/texinfo.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 9e7414c58..6eb3cd3bf 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -1318,7 +1318,10 @@ class TexinfoTranslator(nodes.NodeVisitor): self.body.append(', ') else: self.first_param = 0 - self.body.append(self.escape(node.astext())) + text = self.escape(node.astext()) + # replace no-break spaces with normal ones + text = text.replace(u' ', '@w{ }') + self.body.append(text) raise nodes.SkipNode def visit_desc_optional(self, node): From a78b9ec92721987b55b2c694503e17fe7fae0606 Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Wed, 29 Jun 2011 17:33:27 -0500 Subject: [PATCH 4/7] Prevent indexing commands from causing a paragraph break in Texinfo. --- sphinx/writers/texinfo.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 6eb3cd3bf..c110117d1 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -1193,10 +1193,15 @@ class TexinfoTranslator(nodes.NodeVisitor): self.body.append('}') def visit_index(self, node): + # terminate the line but don't prevent paragraph breaks + if isinstance(node.parent, nodes.paragraph): + self.ensure_eol() + else: + self.body.append('\n') for entry in node['entries']: typ, text, tid, text2 = entry text = self.escape_menu(text) - self.body.append('\n@geindex %s\n' % text) + self.body.append('@geindex %s\n' % text) def visit_refcount(self, node): self.body.append('\n') From d16be40da1916ce3eaadbd1b239fb0ee306568ed Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Thu, 30 Jun 2011 17:21:16 -0500 Subject: [PATCH 5/7] Fix NameError in graphviz.render_dot_texinfo. --- sphinx/ext/graphviz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 90874f0b2..e645ad876 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -308,7 +308,8 @@ def render_dot_texinfo(self, node, code, options, prefix='graphviz'): raise nodes.SkipNode if fname is not None: self.body.append('\n\n@float\n') - if node.get('caption'): + caption = node.get('caption') + if caption: self.body.append('@caption{%s}\n' % self.escape_arg(caption)) self.body.append('@image{%s,,,[graphviz],png}\n' '@end float\n\n' % fname[:-4]) From 626a9548211ad078ae8138027f9f6e6ff7400ff7 Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Sun, 3 Jul 2011 17:44:03 -0500 Subject: [PATCH 6/7] Use ``ObjType.lname`` for the category in Texinfo desc_signatures. --- sphinx/writers/texinfo.py | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index c110117d1..526eccbaf 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -10,8 +10,9 @@ """ import re -from os import path +import string import textwrap +from os import path from docutils import nodes, writers @@ -1259,21 +1260,6 @@ class TexinfoTranslator(nodes.NodeVisitor): ## Desc - desc_map = { - 'cfunction': 'C Function', - 'classmethod': 'Class Method', - 'cmacro': 'C Macro', - 'cmdoption': 'Command Option', - 'cmember': 'C Member', - 'confval': 'Configuration Value', - 'ctype': 'C Type', - 'cvar': 'C Variable', - 'describe': 'Description', - 'envvar': 'Environment Variable', - 'staticmethod': 'Static Method', - 'var': 'Variable', - } - def visit_desc(self, node): self.at_deffnx = '@deffn' def depart_desc(self, node): @@ -1281,13 +1267,18 @@ class TexinfoTranslator(nodes.NodeVisitor): self.body.append('@end deffn\n') def visit_desc_signature(self, node): - self.desctype = node.parent['desctype'].strip() - if self.desctype != 'describe': + objtype = node.parent['objtype'] + if objtype != 'describe': for id in node.get('ids'): self.add_anchor(id, node) - typ = _(self.desc_map.get(self.desctype, - self.desctype.capitalize())) - self.body.append('\n%s {%s} ' % (self.at_deffnx, self.escape_arg(typ))) + # use the localized name for the category + try: + domain = self.builder.env.domains[node.parent['domain']] + lname = domain.object_types[objtype].lname + except KeyError: + lname = objtype + category = self.escape_arg(string.capwords(lname)) + self.body.append('\n%s {%s} ' % (self.at_deffnx, category)) self.at_deffnx = '@deffnx' def depart_desc_signature(self, node): self.body.append("\n") From 1fde44cbf63462b18aad202009610540fa3012da Mon Sep 17 00:00:00 2001 From: Jonathan Waltman Date: Thu, 7 Jul 2011 01:39:53 -0500 Subject: [PATCH 7/7] Follow the behavior described by :confval:`primary_domain` to display domain object names and use this as the category in Texinfo desc_signatures. --- sphinx/writers/texinfo.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 526eccbaf..5799e0234 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -1271,13 +1271,15 @@ class TexinfoTranslator(nodes.NodeVisitor): if objtype != 'describe': for id in node.get('ids'): self.add_anchor(id, node) - # use the localized name for the category + # use the full name of the objtype for the category try: domain = self.builder.env.domains[node.parent['domain']] - lname = domain.object_types[objtype].lname + primary = self.builder.config.primary_domain + name = domain.get_type_name(domain.object_types[objtype], + primary == domain.name) except KeyError: - lname = objtype - category = self.escape_arg(string.capwords(lname)) + name = objtype + category = self.escape_arg(string.capwords(name)) self.body.append('\n%s {%s} ' % (self.at_deffnx, category)) self.at_deffnx = '@deffnx' def depart_desc_signature(self, node):