diff options
| author | Martin Trigaux <mat@odoo.com> | 2016-10-11 12:06:39 +0200 |
|---|---|---|
| committer | Martin Trigaux <mat@odoo.com> | 2016-10-11 12:09:28 +0200 |
| commit | 731fe1c9abbcd3df0cf27053daaf3e7ca3d08ba3 (patch) | |
| tree | ea956bbfd1e21d82cce8faa9406b71945546d4b8 /doc/_extensions/odoo/translator.py | |
| parent | 95280245367da42fead8be9892079a5795171fd0 (diff) | |
[FIX] doc: avoid conflict on extenstion and odoo folder
Diffstat (limited to 'doc/_extensions/odoo/translator.py')
| -rw-r--r-- | doc/_extensions/odoo/translator.py | 691 |
1 files changed, 0 insertions, 691 deletions
diff --git a/doc/_extensions/odoo/translator.py b/doc/_extensions/odoo/translator.py deleted file mode 100644 index 48c5e901f28..00000000000 --- a/doc/_extensions/odoo/translator.py +++ /dev/null @@ -1,691 +0,0 @@ -# -*- coding: utf-8 -*- -import os.path -import posixpath -import re -import urllib - -from docutils import nodes -from sphinx import addnodes, util -from sphinx.locale import admonitionlabels - - -def _parents(node): - while node.parent: - node = node.parent - yield node - -class BootstrapTranslator(nodes.NodeVisitor, object): - head_prefix = 'head_prefix' - head = 'head' - stylesheet = 'stylesheet' - body_prefix = 'body_prefix' - body_pre_docinfo = 'body_pre_docinfo' - docinfo = 'docinfo' - body_suffix = 'body_suffix' - subtitle = 'subtitle' - header = 'header' - footer = 'footer' - html_prolog = 'html_prolog' - html_head = 'html_head' - html_title = 'html_title' - html_subtitle = 'html_subtitle' - - # <meta> tags - meta = [ - '<meta http-equiv="X-UA-Compatible" content="IE=edge">', - '<meta name="viewport" content="width=device-width, initial-scale=1">' - ] - - def __init__(self, builder, document): - super(BootstrapTranslator, self).__init__(document) - self.builder = builder - self.body = [] - self.fragment = self.body - self.html_body = self.body - # document title - self.title = [] - self.start_document_title = 0 - self.first_title = False - - self.context = [] - self.section_level = 0 - - self.highlightlang = self.highlightlang_base = self.builder.config.highlight_language - self.highlightopts = getattr(builder.config, 'highlight_options', {}) - - self.first_param = 1 - self.optional_param_level = 0 - self.required_params_left = 0 - self.param_separator = ',' - - def encode(self, text): - return unicode(text).translate({ - ord('&'): u'&', - ord('<'): u'<', - ord('"'): u'"', - ord('>'): u'>', - 0xa0: u' ' - }) - - def starttag(self, node, tagname, **attributes): - tagname = unicode(tagname).lower() - - # extract generic attributes - attrs = {name.lower(): value for name, value in attributes.iteritems()} - attrs.update( - (name, value) for name, value in node.attributes.iteritems() - if name.startswith('data-') - ) - - prefix = [] - postfix = [] - - # handle possibly multiple ids - assert 'id' not in attrs, "starttag can't be passed a single id attribute, use a list of ids" - ids = node.get('ids', []) + attrs.pop('ids', []) - if ids: - _ids = iter(ids) - attrs['id'] = next(_ids) - postfix.extend(u'<i id="{}"></i>'.format(_id) for _id in _ids) - - # set CSS class - classes = set(node.get('classes', []) + attrs.pop('class', '').split()) - if classes: - attrs['class'] = u' '.join(classes) - - return u'{prefix}<{tag} {attrs}>{postfix}'.format( - prefix=u''.join(prefix), - tag=tagname, - attrs=u' '.join(u'{}="{}"'.format(name, self.attval(value)) - for name, value in attrs.iteritems()), - postfix=u''.join(postfix), - ) - # only "space characters" SPACE, CHARACTER TABULATION, LINE FEED, - # FORM FEED and CARRIAGE RETURN should be collapsed, not al White_Space - def attval(self, value, whitespace=re.compile(u'[ \t\n\f\r]')): - return self.encode(whitespace.sub(u' ', unicode(value))) - - def astext(self): - return u''.join(self.body) - - def unknown_visit(self, node): - print "unknown node", node.__class__.__name__ - self.body.append(u'[UNKNOWN NODE {}]'.format(node.__class__.__name__)) - raise nodes.SkipNode - - def visit_highlightlang(self, node): - self.highlightlang = node['lang'] - def depart_highlightlang(self, node): - pass - - def visit_document(self, node): - self.first_title = True - def depart_document(self, node): - pass - - def visit_section(self, node): - # close "parent" or preceding section, unless this is the opening of - # the first section - if self.section_level: - self.body.append(u'</section>') - self.section_level += 1 - - self.body.append(self.starttag(node, 'section')) - def depart_section(self, node): - self.section_level -= 1 - # close last section of document - if not self.section_level: - self.body.append(u'</section>') - - def is_compact_paragraph(self, node): - parent = node.parent - if isinstance(parent, (nodes.document, nodes.compound, - addnodes.desc_content, - addnodes.versionmodified)): - # Never compact paragraphs in document or compound. - return False - - for key, value in node.attlist(): - # we can ignore a few specific classes, all other non-default - # attributes require that a <p> node remains - if key != 'classes' or value not in ([], ['first'], ['last'], ['first', 'last']): - return False - - first = isinstance(node.parent[0], nodes.label) - for child in parent.children[first:]: - # only first paragraph can be compact - if isinstance(child, nodes.Invisible): - continue - if child is node: - break - return False - parent_length = len([ - 1 for n in parent - if not isinstance(n, (nodes.Invisible, nodes.label)) - ]) - return parent_length == 1 - - def visit_paragraph(self, node): - if self.is_compact_paragraph(node): - self.context.append(u'') - return - self.body.append(self.starttag(node, 'p')) - self.context.append(u'</p>') - def depart_paragraph(self, node): - self.body.append(self.context.pop()) - def visit_compact_paragraph(self, node): - pass - def depart_compact_paragraph(self, node): - pass - - def visit_literal_block(self, node): - if node.rawsource != node.astext(): - # most probably a parsed-literal block -- don't highlight - self.body.append(self.starttag(node, 'pre')) - return - lang = self.highlightlang - highlight_args = node.get('highlight_args', {}) - if 'language' in node: - # code-block directives - lang = node['language'] - highlight_args['force'] = True - linenos = node.get('linenos', False) - if lang is self.highlightlang_base: - # only pass highlighter options for original language - opts = self.highlightopts - else: - opts = {} - - def warner(msg): - self.builder.warn(msg, (self.builder.current_docname, node.line)) - highlighted = self.builder.highlighter.highlight_block( - node.rawsource, lang, opts=opts, warn=warner, linenos=linenos, - **highlight_args) - self.body.append(self.starttag(node, 'div', CLASS='highlight-%s' % lang)) - self.body.append(highlighted) - self.body.append(u'</div>\n') - raise nodes.SkipNode - def depart_literal_block(self, node): - self.body.append(u'</pre>') - - def visit_bullet_list(self, node): - self.body.append(self.starttag(node, 'ul')) - def depart_bullet_list(self, node): - self.body.append(u'</ul>') - def visit_enumerated_list(self, node): - self.body.append(self.starttag(node, 'ol')) - def depart_enumerated_list(self, node): - self.body.append(u'</ol>') - def visit_list_item(self, node): - self.body.append(self.starttag(node, 'li')) - def depart_list_item(self, node): - self.body.append(u'</li>') - def visit_definition_list(self, node): - self.body.append(self.starttag(node, 'dl')) - def depart_definition_list(self, node): - self.body.append(u'</dl>') - def visit_definition_list_item(self, node): - pass - def depart_definition_list_item(self, node): - pass - def visit_term(self, node): - self.body.append(self.starttag(node, 'dt')) - def depart_term(self, node): - self.body.append(u'</dt>') - def visit_termsep(self, node): - self.body.append(self.starttag(node, 'br')) - raise nodes.SkipNode - def visit_definition(self, node): - self.body.append(self.starttag(node, 'dd')) - def depart_definition(self, node): - self.body.append(u'</dd>') - - def visit_admonition(self, node, type=None): - clss = { - # ???: 'alert-success', - - 'note': 'alert-info', - 'hint': 'alert-info', - 'tip': 'alert-info', - 'seealso': 'alert-go_to', - - 'warning': 'alert-warning', - 'attention': 'alert-warning', - 'caution': 'alert-warning', - 'important': 'alert-warning', - - 'danger': 'alert-danger', - 'error': 'alert-danger', - - 'exercise': 'alert-exercise', - } - self.body.append(self.starttag(node, 'div', role='alert', CLASS='alert {}'.format( - clss.get(type, '') - ))) - if 'alert-dismissible' in node.get('classes', []): - self.body.append( - u'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' - u'<span aria-hidden="true">×</span>' - u'</button>') - if type: - node.insert(0, nodes.title(type, admonitionlabels[type])) - def depart_admonition(self, node): - self.body.append(u'</div>') - visit_note = lambda self, node: self.visit_admonition(node, 'note') - visit_warning = lambda self, node: self.visit_admonition(node, 'warning') - visit_attention = lambda self, node: self.visit_admonition(node, 'attention') - visit_caution = lambda self, node: self.visit_admonition(node, 'caution') - visit_danger = lambda self, node: self.visit_admonition(node, 'danger') - visit_error = lambda self, node: self.visit_admonition(node, 'error') - visit_hint = lambda self, node: self.visit_admonition(node, 'hint') - visit_important = lambda self, node: self.visit_admonition(node, 'important') - visit_tip = lambda self, node: self.visit_admonition(node, 'tip') - visit_exercise = lambda self, node: self.visit_admonition(node, 'exercise') - visit_seealso = lambda self, node: self.visit_admonition(node, 'seealso') - depart_note = depart_admonition - depart_warning = depart_admonition - depart_attention = depart_admonition - depart_caution = depart_admonition - depart_danger = depart_admonition - depart_error = depart_admonition - depart_hint = depart_admonition - depart_important = depart_admonition - depart_tip = depart_admonition - depart_exercise = depart_admonition - depart_seealso = depart_admonition - def visit_versionmodified(self, node): - self.body.append(self.starttag(node, 'div', CLASS=node['type'])) - def depart_versionmodified(self, node): - self.body.append(u'</div>') - - def visit_title(self, node): - parent = node.parent - closing = u'</p>' - if isinstance(parent, nodes.Admonition): - self.body.append(self.starttag(node, 'p', CLASS='alert-title')) - elif isinstance(node.parent, nodes.document): - self.body.append(self.starttag(node, 'h1')) - closing = u'</h1>' - self.start_document_title = len(self.body) - else: - assert isinstance(parent, nodes.section), "expected a section node as parent to the title, found {}".format(parent) - if self.first_title: - self.first_title = False - raise nodes.SkipNode() - nodename = 'h{}'.format(self.section_level) - self.body.append(self.starttag(node, nodename)) - closing = u'</{}>'.format(nodename) - self.context.append(closing) - def depart_title(self, node): - self.body.append(self.context.pop()) - if self.start_document_title: - self.title = self.body[self.start_document_title:-1] - self.start_document_title = 0 - del self.body[:] - - # the rubric should be a smaller heading than the current section, up to - # h6... maybe "h7" should be a ``p`` instead? - def visit_rubric(self, node): - self.body.append(self.starttag(node, 'h{}'.format(min(self.section_level + 1, 6)))) - def depart_rubric(self, node): - self.body.append(u'</h{}>'.format(min(self.section_level + 1, 6))) - - def visit_block_quote(self, node): - self.body.append(self.starttag(node, 'blockquote')) - def depart_block_quote(self, node): - self.body.append(u'</blockquote>') - def visit_attribution(self, node): - self.body.append(self.starttag(node, 'footer')) - def depart_attribution(self, node): - self.body.append(u'</footer>') - - def visit_container(self, node): - self.body.append(self.starttag(node, 'div')) - def depart_container(self, node): - self.body.append(u'</div>') - def visit_compound(self, node): - self.body.append(self.starttag(node, 'div')) - def depart_compound(self, node): - self.body.append(u'</div>') - - def visit_image(self, node): - uri = node['uri'] - if uri in self.builder.images: - uri = posixpath.join(self.builder.imgpath, - self.builder.images[uri]) - attrs = {'src': uri, 'class': 'img-responsive'} - if 'alt' in node: - attrs['alt'] = node['alt'] - if 'align' in node: - if node['align'] == 'center': - attrs['class'] += ' center-block' - else: - doc = None - if node.source: - doc = node.source - if node.line: - doc += ':%d' % node.line - self.builder.app.warn( - "Unsupported alignment value \"%s\"" % node['align'], - location=doc - ) - # todo: explicit width/height/scale? - self.body.append(self.starttag(node, 'img', **attrs)) - def depart_image(self, node): pass - def visit_figure(self, node): - self.body.append(self.starttag(node, 'div')) - def depart_figure(self, node): - self.body.append(u'</div>') - def visit_caption(self, node): - # first paragraph of figure content - self.body.append(self.starttag(node, 'h4')) - def depart_caption(self, node): - self.body.append(u'</h4>') - def visit_legend(self, node): pass - def depart_legend(self, node): pass - - def visit_line(self, node): - self.body.append(self.starttag(node, 'div', CLASS='line')) - # ensure the line still takes the room it needs - if not len(node): self.body.append(u'<br />') - def depart_line(self, node): - self.body.append(u'</div>') - - def visit_line_block(self, node): - self.body.append(self.starttag(node, 'div', CLASS='line-block')) - def depart_line_block(self, node): - self.body.append(u'</div>') - - def visit_table(self, node): - self.body.append(self.starttag(node, 'table', CLASS='table')) - def depart_table(self, node): - self.body.append(u'</table>') - def visit_tgroup(self, node): pass - def depart_tgroup(self, node): pass - def visit_colspec(self, node): raise nodes.SkipNode - def visit_thead(self, node): - self.body.append(self.starttag(node, 'thead')) - def depart_thead(self, node): - self.body.append(u'</thead>') - def visit_tbody(self, node): - self.body.append(self.starttag(node, 'tbody')) - def depart_tbody(self, node): - self.body.append(u'</tbody>') - def visit_row(self, node): - self.body.append(self.starttag(node, 'tr')) - def depart_row(self, node): - self.body.append(u'</tr>') - def visit_entry(self, node): - if isinstance(node.parent.parent, nodes.thead): - tagname = 'th' - else: - tagname = 'td' - self.body.append(self.starttag(node, tagname)) - self.context.append(tagname) - def depart_entry(self, node): - self.body.append(u'</{}>'.format(self.context.pop())) - - def visit_Text(self, node): - self.body.append(self.encode(node.astext())) - def depart_Text(self, node): - pass - def visit_literal(self, node): - self.body.append(self.starttag(node, 'code')) - def depart_literal(self, node): - self.body.append(u'</code>') - visit_literal_emphasis = visit_literal - depart_literal_emphasis = depart_literal - def visit_emphasis(self, node): - self.body.append(self.starttag(node, 'em')) - def depart_emphasis(self, node): - self.body.append(u'</em>') - def visit_strong(self, node): - self.body.append(self.starttag(node, 'strong')) - def depart_strong(self, node): - self.body.append(u'</strong>') - visit_literal_strong = visit_strong - depart_literal_strong = depart_strong - def visit_inline(self, node): - self.body.append(self.starttag(node, 'span')) - def depart_inline(self, node): - self.body.append(u'</span>') - def visit_abbreviation(self, node): - attrs = {} - if 'explanation' in node: - attrs['title'] = node['explanation'] - self.body.append(self.starttag(node, 'abbr', **attrs)) - def depart_abbreviation(self, node): - self.body.append(u'</abbr>') - - def visit_reference(self, node): - attrs = { - 'class': 'reference', - 'href': node['refuri'] if 'refuri' in node else '#' + node['refid'] - } - attrs['class'] += ' internal' if (node.get('internal') or 'refuri' not in node) else ' external' - if any(isinstance(ancestor, nodes.Admonition) for ancestor in _parents(node)): - attrs['class'] += ' alert-link' - - if 'reftitle' in node: - attrs['title'] = node['reftitle'] - - self.body.append(self.starttag(node, 'a', **attrs)) - def depart_reference(self, node): - self.body.append(u'</a>') - def visit_target(self, node): pass - def depart_target(self, node): pass - def visit_footnote(self, node): - self.body.append(self.starttag(node, 'div', CLASS='footnote')) - self.footnote_backrefs(node) - def depart_footnote(self, node): - self.body.append(u'</div>') - def visit_footnote_reference(self, node): - self.body.append(self.starttag( - node, 'a', href='#' + node['refid'], CLASS="footnote-ref")) - def depart_footnote_reference(self, node): - self.body.append(u'</a>') - def visit_label(self, node): - self.body.append(self.starttag(node, 'span', CLASS='footnote-label')) - self.body.append(u'%s[' % self.context.pop()) - def depart_label(self, node): - # Context added in footnote_backrefs. - self.body.append(u']%s</span> %s' % (self.context.pop(), self.context.pop())) - def footnote_backrefs(self, node): - # should store following data on context stack (in that order since - # they'll be popped so LIFO) - # - # * outside (after) label - # * after label text - # * before label text - backrefs = node['backrefs'] - if not backrefs: - self.context.extend(['', '', '']) - elif len(backrefs) == 1: - self.context.extend([ - '', - '</a>', - '<a class="footnote-backref" href="#%s">' % backrefs[0] - ]) - else: - backlinks = ( - '<a class="footnote-backref" href="#%s">%s</a>' % (backref, i) - for i, backref in enumerate(backrefs, start=1) - ) - self.context.extend([ - '<em class="footnote-backrefs">(%s)</em> ' % ', '.join(backlinks), - '', - '' - ]) - - def visit_desc(self, node): - self.body.append(self.starttag(node, 'section', CLASS='code-' + node['objtype'])) - def depart_desc(self, node): - self.body.append(u'</section>') - def visit_desc_signature(self, node): - self.body.append(self.starttag(node, 'h6')) - self.body.append(u'<code>') - def depart_desc_signature(self, node): - self.body.append(u'</code>') - self.body.append(u'</h6>') - def visit_desc_addname(self, node): pass - def depart_desc_addname(self, node): pass - def visit_desc_type(self, node): pass - def depart_desc_type(self, node): pass - def visit_desc_returns(self, node): - self.body.append(u' → ') - def depart_desc_returns(self, node): - pass - def visit_desc_name(self, node): pass - def depart_desc_name(self, node): pass - def visit_desc_parameterlist(self, node): - self.body.append(u'(') - self.first_param = True - self.optional_param_level = 0 - # How many required parameters are left. - self.required_params_left = sum(isinstance(c, addnodes.desc_parameter) for c in node.children) - self.param_separator = node.child_text_separator - def depart_desc_parameterlist(self, node): - self.body.append(u')') - # If required parameters are still to come, then put the comma after - # the parameter. Otherwise, put the comma before. This ensures that - # signatures like the following render correctly (see issue #1001): - # - # foo([a, ]b, c[, d]) - # - def visit_desc_parameter(self, node): - if self.first_param: - self.first_param = 0 - elif not self.required_params_left: - self.body.append(self.param_separator) - if self.optional_param_level == 0: - self.required_params_left -= 1 - if 'noemph' not in node: self.body.append(u'<em>') - def depart_desc_parameter(self, node): - if 'noemph' not in node: self.body.append(u'</em>') - if self.required_params_left: - self.body.append(self.param_separator) - def visit_desc_optional(self, node): - self.optional_param_level += 1 - self.body.append(u'[') - def depart_desc_optional(self, node): - self.optional_param_level -= 1 - self.body.append(u']') - def visit_desc_annotation(self, node): - self.body.append(self.starttag(node, 'em')) - def depart_desc_annotation(self, node): - self.body.append(u'</em>') - def visit_desc_content(self, node): pass - def depart_desc_content(self, node): pass - def visit_field_list(self, node): - self.body.append(self.starttag(node, 'div', CLASS='code-fields')) - def depart_field_list(self, node): - self.body.append(u'</div>') - def visit_field(self, node): - self.body.append(self.starttag(node, 'div', CLASS='code-field')) - def depart_field(self, node): - self.body.append(u'</div>') - def visit_field_name(self, node): - self.body.append(self.starttag(node, 'div', CLASS='code-field-name')) - def depart_field_name(self, node): - self.body.append(u'</div>') - def visit_field_body(self, node): - self.body.append(self.starttag(node, 'div', CLASS='code-field-body')) - def depart_field_body(self, node): - self.body.append(u'</div>') - - def visit_glossary(self, node): pass - def depart_glossary(self, node): pass - - def visit_comment(self, node): raise nodes.SkipNode - def visit_toctree(self, node): - # div class=row {{ section_type }} - # h2 class=col-sm-12 - # {{ section title }} - # div class=col-sm-6 col-md-3 - # figure class=card - # a href=current_link style=background-image: document-image-attribute class=card-img - # figcaption - # {{ card title }} - env = self.builder.env - conf = self.builder.app.config - for title, ref in ((e[0], e[1]) for e in node['entries']): - # external URL, no toc, can't recurse into - if ref not in env.tocs: - continue - toc = env.tocs[ref].traverse(addnodes.toctree) - - classes = env.metadata[ref].get('types', 'tutorials') - classes += ' toc-single-entry' if not toc else ' toc-section' - self.body.append(self.starttag(node, 'div', CLASS="row " + classes)) - self.body.append(u'<h2 class="col-sm-12">') - self.body.append(title if title else util.nodes.clean_astext(env.titles[ref])) - self.body.append(u'</h2>') - - entries = [(title, ref)] if not toc else ((e[0], e[1]) for e in toc[0]['entries']) - for subtitle, subref in entries: - baseuri = self.builder.get_target_uri(node['parent']) - - if subref in env.metadata: - cover = env.metadata[subref].get('banner', conf.odoo_cover_default) - elif subref in conf.odoo_cover_external: - cover = conf.odoo_cover_external[subref] - else: - cover = conf.odoo_cover_default_external - - if cover: - banner = '_static/' + cover - base, ext = os.path.splitext(banner) - small = "{}.small{}".format(base, ext) - if os.path.isfile(urllib.url2pathname(small)): - banner = small - style = u"background-image: url('{}')".format( - util.relative_uri(baseuri, banner) or '#') - else: - style = u'' - - self.body.append(u""" - <div class="col-sm-6 col-md-3"> - <figure class="card"> - <a href="{link}" class="card-img"> - <span style="{style}"></span> - <figcaption>{title}</figcaption> - </a> - </figure> - </div> - """.format( - link=subref if util.url_re.match(subref) else util.relative_uri( - baseuri, self.builder.get_target_uri(subref)), - style=style, - title=subtitle if subtitle else util.nodes.clean_astext(env.titles[subref]), - )) - - self.body.append(u'</div>') - raise nodes.SkipNode - - def visit_index(self, node): raise nodes.SkipNode - - def visit_raw(self, node): - if 'html' in node.get('format', '').split(): - t = 'span' if isinstance(node.parent, nodes.TextElement) else 'div' - if node['classes']: - self.body.append(self.starttag(node, t)) - self.body.append(node.astext()) - if node['classes']: - self.body.append('</%s>' % t) - # Keep non-HTML raw text out of output: - raise nodes.SkipNode - - # internal node - def visit_substitution_definition(self, node): raise nodes.SkipNode - - # without set_translator, add_node doesn't work correctly, so the - # serialization of html_domain nodes needs to be embedded here - def visit_div(self, node): - self.body.append(self.starttag(node, 'div')) - def depart_div(self, node): - self.body.append(u'</div>\n') - def visit_address(self, node): - self.body.append(self.starttag(node, 'address')) - def depart_address(self, node): - self.body.append(u'</address>') - # TODO: inline elements |
