def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.root = Body() self.indent = 1 self.parents = [] self.current = self.root self.settings = document.settings self.title = self.settings.title or "" self.title_level = int(self.settings.initial_header_level) lcode = document.settings.language_code try: self.language = languages.get_language(lcode) except TypeError: self.language = languages.get_language(lcode, document.reporter) # make settings for this self.content_type = self.settings.output_encoding self.head = Head( Meta(charset=self.content_type), Title(self.title)) self._init_math_handler()
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.root = Body() self.indent = 1 self.parents = [] self.current = self.root self.settings = document.settings self.title_level = int(self.settings.initial_header_level) lcode = document.settings.language_code try: self.language = languages.get_language(lcode) except TypeError: self.language = languages.get_language(lcode, document.reporter) # make settings for this self.content_type = self.settings.output_encoding self.head = Head( Meta(charset=self.content_type), Title("document")) styles = utils.get_stylesheet_list(self.settings) for style in styles: self.head.append(self.css(style))
def get_language_silent(lang): """Docutils get_language() with patches for older versions.""" try: return get_language(lang) except TypeError, err: # Docutils 0.8.1 if 'get_language() takes exactly 2 arguments' in str(err): class SilentReporter(object): def warning(self, msg): pass return get_language(lang, SilentReporter()) raise # re-raise any other TypeError
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) self.head = [] self.body = [] self.foot = [] self.list_type = [] self.indent = 0 self.first_indent = True self.section_level = 0 ##TODO docinfo items can go in a footer HTML element (store in self.foot). self._docinfo = { 'title' : '', 'subtitle' : '', 'author' : [], 'date' : '', 'copyright' : '', 'version' : '', } # Customise Markdown syntax here. Still need to add literal, term, # indent, problematic etc... self.defs = { 'emphasis': ('*', '*'), # Could also use ('_', '_') 'problematic' : ('\n\n', '\n\n'), 'strong' : ('**', '**'), # Could also use ('__', '__') 'subscript' : ('<sub>', '</sub>'), 'superscript' : ('<sup>', '</sup>'), }
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.language = languages.get_language( document.settings.language_code) self.doctype = document.settings.doctype self.doc_header = [ self.XML_DECL % (document.settings.output_encoding,), self.DOCTYPE_DECL % (self.doctype,), '<%s>\n' % (self.doctype,), ] self.doc_footer = [ '</%s>\n' % (self.doctype,) ] self.body = [] self.section = 0 self.context = [] self.colnames = [] self.footnotes = {} self.footnote_map = {} self.docinfo = [] self.title = '' self.subtitle = '' self.table_tag_stack = [] self.figure_tag_stack = [] self.example_tag_stack = [] self.section_stack = [] self._OPTION_DIRECTIVE_RE = re.compile( r'(\n[ ]*\.\.\.[ ]*)?#\s*doctest:\s*([^\n\'"]*)$', re.MULTILINE)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.body = [] self.section_level = 0 self.title = [] self.subtitle = [] self.context = [] self.body_pre_docinfo = [] self.in_document_front = False self.in_author = False self.in_middle = False self.in_pre_document = False self.in_infoitem = False self.in_citation = False # Closures to apply to incoming _text messsages self.textcl = [] # A stack of booleans, determine whether to push a '<t>' # element around the next visited paragraph self.nextparagraph = [] # A stack of booleans, determine whether to push a '<t>' # element around a paragraph self.paragraph = []
def write(self, document, destination): self.document = document self.language = languages.get_language(document.settings.language_code) settings = self.document.settings destdir = '' root_filename = None if settings._destination: destdir = os.path.dirname(settings._destination) root_filename = os.path.basename(settings._destination) chunker = HTMLChunker(document, self.writer_class, root_filename, destination, self.nav_callback) chunks = chunker.chunk() number_of_chunks = len(chunks) self.output = chunker.convert_chunk(chunks[0]) output = destination.write(self.output) for c in chunks: destpath = os.path.join(destdir, c.filename) if settings.chunker_progress and root_filename: n = ('%%%dd' % len(str(number_of_chunks))) % (c.number + 1) print 'Writing chunk %s of %d: %s'\ % (n, number_of_chunks, destpath) if not c.is_root(): out = chunker.convert_chunk(c) f = io.FileOutput(destination=None, destination_path=destpath, encoding=settings.output_encoding, error_handler=settings.output_encoding_error_handler) f.write(out) f.close() return output
def run(self): if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)): raise self.error('The "%s" directive may not be used within ' "topics or body elements." % self.name) document = self.state_machine.document language = languages.get_language(document.settings.language_code) if self.arguments: title_text = self.arguments[0] text_nodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.title(title_text, "", *text_nodes) else: messages = [] if self.options.has_key("local"): title = None else: title = nodes.title("", language.labels["contents"]) topic = nodes.topic(classes=["contents"]) topic["classes"] += self.options.get("class", []) if self.options.has_key("local"): topic["classes"].append("local") if title: name = title.astext() topic += title else: name = language.labels["contents"] name = nodes.fully_normalize_name(name) if not document.has_name(name): topic["names"].append(name) document.note_implicit_target(topic) pending = nodes.pending(parts.Contents, rawsource=self.block_text) pending.details.update(self.options) document.note_pending(pending) topic += pending return [topic] + messages
def run(self): node = nodes.paragraph() node['classes'] = ['versionadded'] node.document = self.state.document set_source_info(self, node) node['type'] = self.name node['version'] = self.arguments[0] text = versionlabels[self.name] % self.arguments[0] if len(self.arguments) == 2: inodes, messages = self.state.inline_text(self.arguments[1], self.lineno + 1) para = nodes.paragraph(self.arguments[1], '', *inodes) set_source_info(self, para) node.append(para) else: messages = [] if self.content: self.state.nested_parse(self.content, self.content_offset, node) if len(node): if isinstance(node[0], nodes.paragraph) and node[0].rawsource: content = nodes.inline(node[0].rawsource, translatable=True) content.source = node[0].source content.line = node[0].line content += node[0].children node[0].replace_self(nodes.paragraph('', '', content)) node[0].insert(0, nodes.inline('', '%s: ' % text, classes=['versionmodified'])) else: para = nodes.paragraph('', '', nodes.inline('', '%s.' % text, classes=['versionmodified'])) node.append(para) language = languages.get_language(self.state.document.settings.language_code, self.state.document.reporter) language.labels.update(versionlabels) return [node] + messages
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.head = [] self.body = [] self.foot = [] self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None # the list style "*" bullet or "#" numbered self._list_char = [] # writing the header .TH and .SH NAME is postboned after # docinfo. self._docinfo = { "title" : "", "subtitle" : "", "manual_section" : "", "manual_group" : "", "author" : "", "date" : "", "copyright" : "", "version" : "", } self._in_docinfo = None self._active_table = None self._in_entry = None self.header_written = 0 self.authors = [] self.section_level = 0 self._indent = [0] # central definition of simple processing rules # what to output on : visit, depart self.defs = { 'indent' : ('.INDENT %.1f\n', '.UNINDENT\n'), 'definition' : ('', ''), 'definition_list' : ('', '.TP 0\n'), 'definition_list_item' : ('\n.TP', ''), #field_list #field 'field_name' : ('\n.TP\n.B ', '\n'), 'field_body' : ('', '.RE\n', ), 'literal' : ('\\fB', '\\fP'), 'literal_block' : ('\n.nf\n', '\n.fi\n'), #option_list 'option_list_item' : ('\n.TP', ''), #option_group, option 'description' : ('\n', ''), 'reference' : (r'\fI\%', r'\fP'), #'target' : (r'\fI\%', r'\fP'), 'emphasis': ('\\fI', '\\fP'), 'strong' : ('\\fB', '\\fP'), 'term' : ('\n.B ', '\n'), 'title_reference' : ('\\fI', '\\fP'), }
def write(self, document, destination): self.document = document self.language = languages.get_language( document.settings.language_code) self.destination = destination self.translate() output = self.destination.write(self.output) return output
def patched_get_language(language_code, reporter=None): # type: (unicode, Reporter) -> Any """A wrapper for docutils.languages.get_language(). This ignores the second argument ``reporter`` to suppress warnings. refs: https://github.com/sphinx-doc/sphinx/issues/3788 """ return get_language(language_code)
def apply(self): try: #incompatible API change in docutils language = languages.get_language(self.document.settings.language_code, None) except TypeError: language = languages.get_language(self.document.settings.language_code ) name = language.labels['contents'] title = nodes.title('', name) topic = nodes.topic('', title, classes=['contents']) name = nodes.fully_normalize_name(name) if not self.document.has_name(name): topic['names'].append(name) self.document.note_implicit_target(topic) pending = nodes.pending(parts.Contents) topic += pending self.document.insert(1, topic) self.document.note_pending(pending)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) # A heterogenous stack used in conjunction with the tree traversal. # Make sure that the pops correspond to the pushes: self.context = [] self.body = [] ws = nbformat.new_worksheet() self.nb = nbformat.new_notebook(worksheets=[ws])
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) # Why does backward compatibility have so little value # in Python and its culture ? *sigh* if docutils.__version__.startswith('0.') and int(docutils.__version__[2]) < 8: self.language = languages.get_language( document.settings.language_code) else: self.language = languages.get_language( document.settings.language_code, document.reporter) self.doctype = document.settings.doctype self.body = [] self.section = 0 self.context = [] self.colnames = [] self.footnotes = {} self.footnote_map = {} self.docinfo = [] self.title = '' self.subtitle = ''
def __init__(self, doctree): self.styleSheet = getStyleSheet() nodes.NodeVisitor.__init__(self, doctree) self.language = languages.get_language(doctree.settings.language_code) self.head = [] self.body = [] self.foot = [] self.sectionlevel = 0 self.context = [] self.topic_class = '' self.story = [] self.bulletText = '\xb7' # maybe move this into stylesheet.
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) self.body = list() self.context = list() self.section_level = 1 self.section_refs = dict() self.list_level = 0 self.list_type = list() self.emphasis_start = None self.emphasis_end = None self.strong_start = None self.strong_end = None self.literal_start = None self.literal_end = None self.title_reference_start = None self.title_reference_end = None self.in_literal = False self.in_literal_block = False self.literal_block_start = None self.literal_block_end = None self._literal_block_indent = 0 self.in_table = False self.in_table_header = False self.table_header_width = 0 self.table_entry_width = 0 self.table_header_sep = None self.table_entry_sep = None self.description = None self.toc = None self.block_quote_start = None self.block_quote_end = None self.in_definition_list = False self.definition_start = None self.definition_end = None self.definition_term_start = None self.definition_term_end = None self.in_paragraph = False self.first_list_paragraph = False self.footnote_refs = dict() self.escape_words = list() if (self.settings.escape_linked_words and os.path.exists(self.settings.escape_linked_words)): fd = open(self.settings.escape_linked_words) try: self.escape_words = [line.strip() for line in fd.readlines()] finally: fd.close() self.escape_word_start = '' self.escape_word_end = ''
def apply(self): language = languages.get_language(self.document.settings.language_code) name = language.labels['contents'] title = nodes.title('', name) topic = nodes.topic('', title, CLASS='contents') name = nodes.fully_normalize_name(name) if not self.document.has_name(name): topic['name'] = name self.document.note_implicit_target(topic) pending = nodes.pending(parts.Contents) topic += pending self.document.insert(1, topic) self.document.note_pending(pending)
def apply(self): language = languages.get_language(self.document.settings.language_code) name = language.labels["contents"] title = nodes.title("", name) topic = nodes.topic("", title, classes=["contents"]) name = nodes.fully_normalize_name(name) if not self.document.has_name(name): topic["names"].append(name) self.document.note_implicit_target(topic) pending = nodes.pending(parts.Contents) topic += pending self.document.insert(1, topic) self.document.note_pending(pending)
def apply(self): lcode = self.document.settings.language_code language = languages.get_language(lcode) for node in self.document.traverse(nodes.Admonition): node_name = node.__class__.__name__ # Set class, so that we know what node this admonition came from. node["classes"].append(node_name) if not isinstance(node, nodes.admonition): # Specific admonition. Transform into a generic admonition. admonition = nodes.admonition(node.rawsource, *node.children, **node.attributes) title = nodes.title("", language.labels[node_name]) admonition.insert(0, title) node.replace_self(admonition)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.head = [] self.body = [] self.foot = [] self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None self.in_docinfo = None
def contents(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ Table of contents. The table of contents is generated in two passes: initial parse and transform. During the initial parse, a 'pending' element is generated which acts as a placeholder, storing the TOC title and any options internally. At a later stage in the processing, the 'pending' element is replaced by a 'topic' element, a title and the table of contents proper. """ if not (state_machine.match_titles or isinstance(state_machine.node, nodes.sidebar)): error = state_machine.reporter.error( 'The "%s" directive may not be used within topics ' 'or body elements.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] document = state_machine.document language = languages.get_language(document.settings.language_code) if arguments: title_text = arguments[0] text_nodes, messages = state.inline_text(title_text, lineno) title = nodes.title(title_text, '', *text_nodes) else: messages = [] if options.has_key('local'): title = None else: title = nodes.title('', language.labels['contents']) topic = nodes.topic(classes=['contents']) topic['classes'] += options.get('class', []) if options.has_key('local'): topic['classes'].append('local') if title: name = title.astext() topic += title else: name = language.labels['contents'] name = nodes.fully_normalize_name(name) if not document.has_name(name): topic['names'].append(name) document.note_implicit_target(topic) pending = nodes.pending(parts.Contents, rawsource=block_text) pending.details.update(options) document.note_pending(pending) topic += pending return [topic] + messages
def __init__(self, document, startnode=None): """ Initial setup for in-place document transforms. """ self.document = document """The document tree to transform.""" self.startnode = startnode """Node from which to begin the transform. For many transforms which apply to the document as a whole, `startnode` is not set (i.e. its value is `None`).""" self.language = languages.get_language( document.settings.language_code, document.reporter) """Language module local to this document."""
def write(self, document, destination): """ Process a document into its final form. Translate `document` (a Docutils document tree) into the Writer's native format, and write it out to its `destination` (a `docutils.io.Output` subclass object). Normally not overridden or extended in subclasses. """ self.document = document self.language = languages.get_language(document.settings.language_code, document.reporter) self.destination = destination self.translate() output = self.destination.write(self.output) return output
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code class Reporter(object): def warning(self, msg): print('docutils warning: %s' % msg) self.language = languages.get_language(lcode, Reporter()) self.section_level = 0 self.doc = rtf.Document() self.style = self.doc.StyleSheet #self.head = rtf.Section() self.body = rtf.Section() #self.doc.Sections.append(self.head) self.doc.Sections.append(self.body) self.next_style = 'Normal'
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.meta = [self.content_type % settings.output_encoding, self.generator % docutils.__version__] self.head_prefix = [] self.html_prolog = [] self.head = self.meta[:] self.stylesheet = [] self.body_prefix = [] # document title, subtitle display self.body_pre_docinfo = [] # author, date, etc. self.docinfo = [] self.body = [] self.fragment = [] self.body_suffix = [] self.section_level = 0 self.list_level = 0 self.list_type = None self.cell_separator = None self.initial_header_level = 1 # A heterogenous stack used in conjunction with the tree traversal. # Make sure that the pops correspond to the pushes: self.context = [] self.topic_classes = [] self.colspecs = [] self.compact_p = 1 self.compact_simple = None self.compact_field_list = None self.in_docinfo = None self.in_sidebar = None self.title = [] self.subtitle = [] self.header = [] self.footer = [] self.html_head = [self.content_type] # charset not interpolated self.html_title = [] self.html_subtitle = [] self.html_body = [] self.in_document_title = 0 self.in_mailto = 0 self.author_in_authors = None self.in_table = False
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.head = [] self.body = [] self.foot = [] self.part = self.body self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None self.in_bullet_list = False self.in_docinfo = False self.in_sidebar = False self.sidebar_start = False self.filterNewlines = True
def __init__(self, document, builder=None): nodes.NodeVisitor.__init__(self, document) self.builder = builder self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) # Not-None here indicates Markdown should use HTTP for internal and # download links. self.markdown_http_base = (builder.markdown_http_base if builder else None) # Warn only once per writer about unsupported elements self._warned = set() # Lookup table to get section list from name self._lists = OrderedDict((('head', []), ('body', []), ('foot', []))) # Reset attributes modified by reading self.reset() # Attribute shortcuts self.head, self.body, self.foot = self._lists.values()
def run(self): if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)): raise self.error('The "%s" directive may not be used within ' 'topics or body elements.' % self.name) document = self.state_machine.document language = languages.get_language(document.settings.language_code, document.reporter) if self.arguments: title_text = self.arguments[0] text_nodes, messages = self.state.inline_text(title_text, self.lineno) title = nodes.title(title_text, '', *text_nodes) else: messages = [] if 'local' in self.options: title = None else: title = nodes.title('', language.labels['contents']) topic = nodes.topic(classes=['contents']) topic['classes'] += self.options.get('class', []) # the latex2e writer needs source and line for a warning: src, srcline = self.state_machine.get_source_and_line() topic.source = src topic.line = srcline - 1 if 'local' in self.options: topic['classes'].append('local') if title: name = title.astext() topic += title else: name = language.labels['contents'] name = nodes.fully_normalize_name(name) if not document.has_name(name): topic['names'].append(name) document.note_implicit_target(topic) pending = nodes.pending(parts.Contents, rawsource=self.block_text) pending.details.update(self.options) document.note_pending(pending) topic += pending return [topic] + messages
def run(self): if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)): raise self.error('The "%s" directive may not be used within ' 'topics or body elements.' % self.name) document = self.state_machine.document language = languages.get_language(document.settings.language_code, document.reporter) if self.arguments: title_text = self.arguments[0] text_nodes, messages = self.state.inline_text( title_text, self.lineno) title = nodes.title(title_text, '', *text_nodes) else: messages = [] if 'local' in self.options: title = None else: title = nodes.title('', language.labels['contents']) topic = nodes.topic(classes=['contents']) topic['classes'] += self.options.get('class', []) # the latex2e writer needs source and line for a warning: src, srcline = self.state_machine.get_source_and_line() topic.source = src topic.line = srcline - 1 if 'local' in self.options: topic['classes'].append('local') if title: name = title.astext() topic += title else: name = language.labels['contents'] name = nodes.fully_normalize_name(name) if not document.has_name(name): topic['names'].append(name) document.note_implicit_target(topic) pending = nodes.pending(parts.Contents, rawsource=self.block_text) pending.details.update(self.options) document.note_pending(pending) topic += pending return [topic] + messages
def __init__(self, document, builder): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) self.builder = builder self.head = [] self.body = [] self.foot = [] self.cells = [ipynb.new_markdown_cell()] self.in_document_title = 0 self.section_level = 0 self.context = [] self.colspecs = [] self.list_level = 0 self.list_itemcount = [] self.list_type = [] # TODO docinfo items can go in a footer HTML element (store in self.foot). self._docinfo = { 'title': '', 'subtitle': '', 'author': [], 'date': '', 'copyright': '', 'version': '', } # Customise Markdown syntax here. Still need to add literal, term, # indent, problematic etc... self.defs = { 'emphasis': ('*', '*'), # Could also use ('_', '_') 'problematic': ('\n\n', '\n\n'), 'strong': ('**', '**'), # Could also use ('__', '__') 'subscript': ('<sub>', '</sub>'), 'superscript': ('<sup>', '</sup>'), }
def __init__(self, document): super(SILETranslator, self).__init__(document) self.settings = document.settings lcode = self.settings.language_code self.language = languages.get_language(lcode, document.reporter) self.doc = [] self.section_level = 0 self.list_depth = 0 self.use_docutils_toc = self.settings.use_docutils_toc # Pre-load all custom packages to simplify package path / loading self.package_code = [] for package in glob.glob(SILE_PATH): p_name = os.path.splitext(package)[0] p_name = os.path.join('packages', os.path.basename(p_name)) self.package_code.append('\\script[src="%s"]\n' % p_name) css_parser = tinycss.make_parser('page3') stylesheets = self.document.settings.stylesheets.split(',') self.styles = defaultdict(dict) for ssheet in stylesheets: rules = css_parser.parse_stylesheet_file(ssheet).rules styles = {} for rule in rules: keys = [ s.strip() for s in rule.selector.as_css().lower().split(',') ] value = {} for dec in rule.declarations: name = dec.name # CSS synonyms if name.startswith('font-'): name = name[5:] value[name] = dec.value.as_css() for k in keys: styles[k] = value self.styles.update(styles)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.language = languages.get_language( document.settings.language_code) self.doctype = document.settings.doctype self.doc_header = [ self.XML_DECL % (document.settings.output_encoding,), self.DOCTYPE_DECL % (self.doctype,), '<%s>\n' % (self.doctype,), ] self.doc_footer = [ '</%s>\n' % (self.doctype,) ] self.body = [] self.section = 0 self.context = [] self.colnames = [] self.footnotes = {} self.footnote_map = {} self.docinfo = [] self.title = '' self.subtitle = ''
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.head_prefix = [ self.doctype, self.html_head % (lcode, lcode), self.content_type % settings.output_encoding, self.generator % docutils.__version__ ] if settings.xml_declaration: self.head_prefix.insert( 0, self.xml_declaration % settings.output_encoding) self.head = [] if settings.embed_stylesheet: stylesheet = self.get_stylesheet_reference( os.path.join(os.getcwd(), 'dummy')) stylesheet_text = open(stylesheet).read() self.stylesheet = [self.embedded_stylesheet % stylesheet_text] else: stylesheet = self.get_stylesheet_reference() if stylesheet: self.stylesheet = [self.stylesheet_link % stylesheet] else: self.stylesheet = [] self.body_prefix = ['</head>\n<body>\n'] self.body_pre_docinfo = [] self.docinfo = [] self.body = [] self.body_suffix = ['</body>\n</html>\n'] self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None self.in_docinfo = None self.in_sidebar = None
def run(self): node = nodes.paragraph() node["classes"] = ["versionadded"] node.document = self.state.document set_source_info(self, node) node["type"] = self.name node["version"] = self.arguments[0] text = versionlabels[self.name] % self.arguments[0] if len(self.arguments) == 2: inodes, messages = self.state.inline_text(self.arguments[1], self.lineno + 1) para = nodes.paragraph(self.arguments[1], "", *inodes) set_source_info(self, para) node.append(para) else: messages = [] if self.content: self.state.nested_parse(self.content, self.content_offset, node) if len(node): if isinstance(node[0], nodes.paragraph) and node[0].rawsource: content = nodes.inline(node[0].rawsource, translatable=True) content.source = node[0].source content.line = node[0].line content += node[0].children node[0].replace_self(nodes.paragraph("", "", content)) node[0].insert( 0, nodes.inline("", "%s: " % text, classes=["versionmodified"])) else: para = nodes.paragraph( "", "", nodes.inline("", "%s." % text, classes=["versionmodified"])) node.append(para) language = languages.get_language( self.state.document.settings.language_code, self.state.document.reporter) language.labels.update(versionlabels) return [node] + messages
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.section_level = 0 self.headerContent = [] self.bodyContent = [] self.bodySuffix = [] self.metaContent = [] self.context = [] self.spewTextContext = [True] self.spewParaTag = [SpewParagraph] self.paraFormat = [(None,None)] self.colspecs = [] self.body_pre_docinfo = [] self.docinfo = [] self.compact_simple = None self.compact_p = 1 self.firstFootnoteVisited = False # lcode = settings.language_code lcode = 'en' self.language = languages.get_language(lcode)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.section_level = 0 self.headerContent = [] self.bodyContent = [] self.bodySuffix = [] self.metaContent = [] self.context = [] self.spewTextContext = [True] self.spewParaTag = [SpewParagraph] self.paraFormat = [(None, None)] self.colspecs = [] self.body_pre_docinfo = [] self.docinfo = [] self.compact_simple = None self.compact_p = 1 self.firstFootnoteVisited = False # lcode = settings.language_code lcode = 'en' self.language = languages.get_language(lcode)
def write(self, document, destination): self.document = document self.language = languages.get_language(document.settings.language_code) settings = self.document.settings destdir = '' root_filename = None if settings._destination: destdir = os.path.dirname(settings._destination) root_filename = os.path.basename(settings._destination) chunker = HTMLChunker(document, self.writer_class, root_filename, destination, self.nav_callback) chunks = chunker.chunk() number_of_chunks = len(chunks) self.output = chunker.convert_chunk(chunks[0]) output = destination.write(self.output) for c in chunks: destpath = os.path.join(destdir, c.filename) if settings.chunker_progress and root_filename: n = ('%%%dd' % len(str(number_of_chunks))) % (c.number + 1) print 'Writing chunk %s of %d: %s'\ % (n, number_of_chunks, destpath) if not c.is_root(): out = chunker.convert_chunk(c) f = io.FileOutput( destination=None, destination_path=destpath, encoding=settings.output_encoding, error_handler=settings.output_encoding_error_handler) f.write(out) f.close() return output
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.language_name = _get_language_name(lcode) self.section_level = 0 self.section_title = None self.section_commands = [] self.section_nesting = 0 self.section_nesting_stack = [] self.body = [] self.literal_block = self.literal = None self.in_dquote = None self.docinfo = {} self.doctype = self.settings.doctype.lower() if self.doctype == 'book': self.chapters = [] self.parts = [] self.preface = [] self.introduction = [] self.topic_class = '' self.kill_next_paragraph = False self.dashes_re = re.compile(settings.dashes_regexp)
from rst2pdf.log import log def get_language_silent(lang): """Docutils get_language() with patches for older versions.""" try: return get_language(lang) except TypeError, err: # Docutils 0.8.1 if 'get_language() takes exactly 2 arguments' in str(err): class SilentReporter(object): def warning(self, msg): pass return get_language(lang, SilentReporter()) raise # re-raise any other TypeError except ImportError: # Docutils < 0.8 return get_language('en') def get_language_available(lang): """Docutils get_language() also returning the available language.""" module = get_language_silent(lang) docutils_lang = module.__name__.rsplit('.', 1)[-1] if (docutils_lang == 'en' and docutils_lang != lang and '_' in lang): module = get_language_silent(lang.split('_', 1)[0]) docutils_lang = module.__name__.rsplit('.', 1)[-1] if docutils_lang != lang: warn = (docutils_lang.split('_', 1)[0] == lang.split('_', 1)[0] and log.info or log.warning) warn("Language '%s' not supported by Docutils," " using '%s' instead." % (lang, docutils_lang))
# dependencies imports import bottle import os from docutils.parsers.rst import directives, roles from docutils import nodes, languages # project imports from watom import views import watom.rst_directives as watom_rst from watom.tools import watom_distro_path # register specific rst directives # small trick here: get_language will reveal languages.en labels = languages.get_language('en').labels # add the label languages.en.labels["todo"] = "Todo" # add node watom_rst.add_node(watom_rst.todo, html=(watom_rst.visit_todo, watom_rst.depart_todo), latex=(watom_rst.visit_todo, watom_rst.depart_todo), text=(watom_rst.visit_todo, watom_rst.depart_todo)) # register the new directive todo directives.register_directive('todo', watom_rst.Todo) # add the label languages.en.labels["done"] = "Done" # add node watom_rst.add_node(watom_rst.done,
def generate_footer(self): # @@@ Text is hard-coded for now. # Should be made dynamic (language-dependent). settings = self.document.settings lcode = settings.language_code language = languages.get_language(lcode) if settings.generator or settings.datestamp or settings.source_link \ or settings.source_url: text = [] if settings.source_link and settings._source \ or settings.source_url: if settings.source_url: source = settings.source_url else: source = utils.relative_path(settings._destination, settings._source) try: label = language.labels['viewdocumentsource'] except KeyError: label = 'View document source' text.extend([ nodes.reference('', label, refuri=source), nodes.Text('.\n')]) if settings.datestamp: if settings.datestamp.strip() == 'CVS_DATE': datestamp = '$' \ +'Date:$' label = 'Last modified' elif settings.datestamp.strip() == 'CVS_VERSION': datestamp = '$' \ +'Id:$' label = '' elif settings.datestamp.strip() == 'SSI_LASTMOD': datestamp = '' label = '' attributes = {'format': 'html'} text.append(nodes.Text('Last modified: ')) text.append(nodes.raw('', '<!--#flastmod file="%s" -->' \ % (os.path.basename(settings._source)), **attributes)) else: datestamp = time.strftime(settings.datestamp, time.gmtime()) try: label = language.labels['generatedon'] except KeyError: label = 'Generated on' if len(label) > 0: text.append(nodes.Text(label+': ' + datestamp + '.\n')) else: text.append(nodes.Text(datestamp+'.\n')) if settings.generator: try: label = language.labels['generatedby'] except KeyError: label = 'Generated by' try: label2 = language.labels['from'] except KeyError: label2 = 'from' try: label3 = language.labels['source'] except KeyError: label3 = 'source' text.extend([ nodes.Text(label+' '), nodes.reference('', 'Docutils', refuri= 'http://docutils.sourceforge.net/'), nodes.Text(' '+label2+' '), nodes.reference('', 'reStructuredText', refuri='http://' 'docutils.sourceforge.net/rst.html'), nodes.Text(' '+label3+'.\n')]) footer = nodes.footer() footer += nodes.paragraph('', '', *text) return footer else: return None
def dict_to_fm_field_list(self, data: Dict[str, Any], language_code: str, line: int = 0) -> nodes.field_list: """Render each key/val pair as a docutils ``field_node``. Bibliographic keys below will be parsed as Markdown, all others will be left as literal text. The field list should be at the start of the document, and will then be converted to a `docinfo` node during the `docutils.docutils.transforms.frontmatter.DocInfo` transform (priority 340), and bibliographic keys (or their translation) will be converted to nodes:: {'author': docutils.nodes.author, 'authors': docutils.nodes.authors, 'organization': docutils.nodes.organization, 'address': docutils.nodes.address, 'contact': docutils.nodes.contact, 'version': docutils.nodes.version, 'revision': docutils.nodes.revision, 'status': docutils.nodes.status, 'date': docutils.nodes.date, 'copyright': docutils.nodes.copyright, 'dedication': docutils.nodes.topic, 'abstract': docutils.nodes.topic} Also, the 'dedication' and 'abstract' will be placed outside the `docinfo`, and so will always be shown in the document. If using sphinx, this `docinfo` node will later be extracted from the AST, by the `DoctreeReadEvent` transform (priority 880), calling `MetadataCollector.process_doc`. In this case keys and values will be converted to strings and stored in `app.env.metadata[app.env.docname]` See https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html for docinfo fields used by sphinx. """ field_list = nodes.field_list() bibliofields = get_language(language_code).bibliographic_fields state_machine = MockStateMachine(self, line) state = MockState(self, state_machine, line) for key, value in data.items(): if not isinstance(value, (str, int, float, date, datetime)): value = json.dumps(value) value = str(value) if key in bibliofields: para_nodes, _ = state.inline_text(value, line) body_children = [nodes.paragraph("", "", *para_nodes)] else: body_children = [nodes.Text(value, value)] field_node = nodes.field() field_node.source = value field_node += nodes.field_name(key, "", nodes.Text(key, key)) field_node += nodes.field_body(value, *body_children) field_list += field_node return field_list
def main(): """main entry point launches the webserver locally """ # register specific rst directives # small trick here: get_language will reveal languages.en labels = languages.get_language('en').labels # add the label languages.en.labels["todo"] = "Todo" # add node add_node(todo, html=(visit_todo, depart_todo), latex=(visit_todo, depart_todo), text=(visit_todo, depart_todo)) # nodes._add_node_class_names(['todo']) # register the new directive todo directives.register_directive('todo', Todo) # add the label languages.en.labels["done"] = "Done" # add node add_node(done, html=(visit_done, depart_done), latex=(visit_done, depart_done), text=(visit_done, depart_done)) # nodes._add_node_class_names(['todo']) # register the new directive todo directives.register_directive('done', Done) # Check if the directory is under git, if not, create the repo try: Repo() except InvalidGitRepositoryError: Repo.init() # add view path from module localisation views_path = attowiki_distro_path() + '/views/' bottle.TEMPLATE_PATH.insert(0, views_path) app = bottle.Bottle() # All the Urls of the project # index or __index__ app.route('/', method='GET')(views.view_page) # new page app.route('/', method='POST')(views.view_page) # meta pages app.route('/__index__')(views.view_meta_index) app.route('/__cheatsheet__')(views.view_meta_cheat_sheet) app.route('/__history__/<gitref>/<name>.__source__')( views.view_history_source) app.route('/__history__/<gitref>/<name>.__diff__')(views.view_history_diff) app.route('/__history__/<gitref>/<name>')(views.view_history) app.route('/__<admonition_name>__')(views.view_meta_admonition) # export pdf app.route('/pdf/<name>')(views.view_pdf) # new page app.route('/edit/')(views.view_edit) # edit an existing page app.route('/edit/<name>')(views.view_edit) # cancel the edition of an existing page app.route('/cancel-edit/')(views.view_cancel_edit) app.route('/cancel-edit/<name>')(views.view_cancel_edit) # meta page for one single document app.route('/<name>.__source__')(views.view_history_source) app.route('/<name>.__diff__')(views.view_history_diff) app.route('/<name>.__<admonition_name>__')(views.view_meta_admonition) # view an existing page app.route('/<name>', method='GET')(views.view_page) # write new content to an existing page app.route('/<name>', method='POST')(views.view_page) # write new content to an existing page (without commit - for quick save) app.route('/<name>', method='PUT')(views.view_quick_save_page) # for devt purpose: set bottle in debug mode bottle.debug(True) # this line may be commented in production mode # run locally by default import argparse cmd_parser = argparse.ArgumentParser( description="usage: %prog package.module:app") cmd_parser.add_argument('-u', '--user', help='user name for auth', default=None) cmd_parser.add_argument('-p', '--password', help='password for auth', default=None) cmd_parser.add_argument('host', help='host to bind', default='localhost', nargs='?') cmd_parser.add_argument('port', help='bind port', default='8080', nargs='?') args = cmd_parser.parse_args() attowiki.user = args.user attowiki.password = args.password if ':' in args.host: args.host, args.port = args.host.rsplit(':', 1) bottle.run(app, host=args.host, port=args.port)
def rst2html(s, fLOG=noLOG, writer="html", keep_warnings=False, directives=None, language="en", layout='docutils', document_name="<<string>>", external_docnames=None, filter_nodes=None, new_extensions=None, update_builder=None, ret_doctree=False, load_bokeh=False, destination=None, destination_path=None, **options): """ Converts a string from :epkg:`RST` into :epkg:`HTML` format or transformed :epkg:`RST`. @param s string to convert @param fLOG logging function (warnings will be logged) @param writer ``'html'`` for :epkg:`HTML` format, ``'rst'`` for :epkg:`RST` format, ``'md'`` for :epkg:`MD` format, ``'elatex'`` for :epkg:`latex` format, ``'doctree'`` to get the doctree, *writer* can also be a tuple for custom formats and must be like ``('buider_name', builder_class)``. @param keep_warnings keep_warnings in the final HTML @param directives new directives to add (see below) @param language language @param layout ``'docutils'``, ``'sphinx'``, ``'sphinx_body'``, see below. @param document_name document name, not really important since the input is a string @param external_docnames if the string to parse makes references to other documents, if one is missing, an exception is raised. @param filter_nodes transforms the doctree before writing the results (layout must be 'sphinx'), the function takes a doctree as a single parameter @param new_extensions additional extension to setup @param update_builder update the builder after it is instantiated @param ret_doctree returns the doctree @param load_bokeh load :epkg:`bokeh` extensions, disabled by default as it takes a few seconds @param destination set a destination (requires for some extension) @param destination_path set a destination path (requires for some extension) @param options :epkg:`Sphinx` options see `Render math as images <http://www.sphinx-doc.org/en/stable/ext/math.html#module-sphinx.ext.imgmath>`_, a subset of options is used, see @see fn default_sphinx_options. By default, the theme (option *html_theme*) will ``'basic'``. @return HTML format *directives* is None or a list of 2 or 5-uple: * a directive name (mandatory) * a directive class: see `Sphinx Directive <http://sphinx-doc.org/extdev/tutorial.html>`_, see also @see cl RunPythonDirective as an example (mandatory) * a docutils node: see @see cl runpython_node as an example * two functions: see @see fn visit_runpython_node, @see fn depart_runpython_node as an example The parameter *layout* specify the kind of HTML you need. * ``'docutils'``: very simple :epkg:`HTML`, style is not included, recursive directives are not processed (recursive means they modify the doctree). The produced :epkg:`HTML` only includes the body (no :epkg:`HTML` header). * ``'sphinx'``: in memory :epkg:`sphinx`, the produced :epkg:`HTML` includes the header, it is also recursive as directives can modify the doctree. * ``'sphinx_body'``: same as ``'sphinx'`` but only the body is returned. If the writer is a tuple, it must be a 2-uple ``(builder_name, builder_class)``. However, the builder class must contain an attribute ``_writer_class`` with the associated writer. The builcer class must also implement a method ``iter_pages`` which enumerates all written pages: ``def iter_pages(self) -> Dict[str,str]`` where the key is the document name and the value is its content. .. exref:: :title: How to test a Sphinx directive? The following code defines a simple directive definedbased on an existing one. It also defined what to do if a new node is inserted in the documentation. :: from docutils import nodes from pyquickhelper.helpgen import rst2html class runpythonthis_node(nodes.Structural, nodes.Element): pass class RunPythonThisDirective (RunPythonDirective): runpython_class = runpythonthis_node def visit_node(self, node): self.body.append("<p><b>visit_node</b></p>") def depart_node(self, node): self.body.append("<p><b>depart_node</b></p>") content = ''' test a directive ================ .. runpythonthis:: print("this code shoud appear" + "___") '''.replace(" ", "") # to remove spaces at the beginning of the line tives = [ ("runpythonthis", RunPythonThisDirective, runpythonthis_node, visit_node, depart_node) ] html = rst2html(content, writer="html", keep_warnings=True, directives=tives) Unfortunately, this functionality is only tested on :epkg:`Python` 3. It might not work on :epkg:`Python` 2.7. The function produces files if the document contains latex converted into image. .. faqref:: :title: How to get more about latex errors? :index: latex :epkg:`Sphinx` is not easy to use when it comes to debug latex expressions. I did not find an easy way to read the error returned by latex about a missing bracket or an unknown command. I finally added a short piece of code in ``sphinx.ext.imgmath.py`` just after the call to the executable indicated by *imgmath_latex* :: if b'...' in stdout or b'LaTeX Error' in stdout: print(self.builder.config.imgmath_latex_preamble) print(p.returncode) print("################") print(latex) print("..........") print(stdout.decode("ascii").replace("\\r", "")) print("-----") print(stderr) It displays the output if an error happened. .. faqref:: :title: How to hide command line window while compiling latex? :lid: command line window :epkg:`Sphinx` calls :epkg:`latex` through command line. On :epkg:`Windows`, a command line window can annoyingly show up anytime a formula is compiled. The following can be added to hide it: :: startupinfo = STARTUPINFO() startupinfo.dwFlags |= STARTF_USESHOWWINDOW And ``, startupinfo=startupinfo`` must be added to lines ``p = Popen(...``. By default, the function now interprets :epkg:`Sphinx` directives and not only *docutils* ones. Parameter *directives* adds a directive before parsing the :epkg:`RST`. The function is more consistent. Format ``rst`` is available as well as custom builders. .. versionchanged:: 1.8 New nodes are now optional in *directives*. Markdown format was added. Parameters *ret_doctree*, *load_bokeh* were added. """ # delayed import to speed up time def _get_MockSphinxApp(): from .sphinxm_mock_app import MockSphinxApp return MockSphinxApp MockSphinxApp = _get_MockSphinxApp() if 'html_theme' not in options: options['html_theme'] = 'basic' defopt = default_sphinx_options(**options) if "master_doc" not in defopt: defopt["master_doc"] = document_name if writer in ('latex', 'elatex') and 'latex_documents' not in defopt: latex_documents = [(document_name, ) * 5] defopt['latex_documents'] = latex_documents if writer in [ "custom", "sphinx", "HTMLWriterWithCustomDirectives", "html" ]: mockapp, writer, title_names = MockSphinxApp.create( "sphinx", directives, confoverrides=defopt, new_extensions=new_extensions, load_bokeh=load_bokeh, fLOG=fLOG, destination_path=destination_path) writer_name = "HTMLWriterWithCustomDirectives" elif writer in ("rst", "md", "latex", "elatex", 'text', 'doctree'): writer_name = writer mockapp, writer, title_names = MockSphinxApp.create( writer, directives, confoverrides=defopt, new_extensions=new_extensions, load_bokeh=load_bokeh, fLOG=fLOG, destination_path=destination_path) elif isinstance(writer, tuple): # We extect something like ("builder_name", builder_class) writer_name = writer mockapp, writer, title_names = MockSphinxApp.create( writer, directives, confoverrides=defopt, new_extensions=new_extensions, load_bokeh=load_bokeh, fLOG=fLOG, destination_path=destination_path) else: raise ValueError( "Unexpected writer '{0}', should be 'rst' or 'html' or 'md' or 'elatex' or 'text'." .format(writer)) if writer is None and directives is not None and len(directives) > 0: raise NotImplementedError( "The writer must not be null if custom directives will be added, check the documentation of the fucntion." ) # delayed import to speed up time from sphinx.environment import default_settings settings_overrides = default_settings.copy() settings_overrides["warning_stream"] = StringIO() settings_overrides["master_doc"] = document_name settings_overrides["source"] = document_name settings_overrides["contentsname"] = document_name settings_overrides.update( {k: v[0] for k, v in mockapp.new_options.items()}) # next settings_overrides.update(defopt) config = mockapp.config config.blog_background = True config.blog_background_page = False config.sharepost = None if hasattr(writer, "add_configuration_options"): writer.add_configuration_options(mockapp.new_options) for k in {'outdir', 'imagedir', 'confdir', 'doctreedir'}: setattr(writer.builder, k, settings_overrides.get(k, '')) if destination_path is not None: writer.builder.outdir = destination_path if update_builder: update_builder(writer.builder) env = mockapp.env if env is None: raise ValueError("No environment was built.") env.temp_data["docname"] = document_name env.temp_data["source"] = document_name mockapp.builder.env.temp_data["docname"] = document_name mockapp.builder.env.temp_data["source"] = document_name settings_overrides["env"] = env lang = languages.get_language(language) for name in title_names: if name not in lang.labels: lang.labels[name] = TITLES[language][name] for k, v in sorted(settings_overrides.items()): fLOG("[rst2html] {0}={1}{2}".format( k, v, " --- added" if hasattr(config, k) else "")) for k, v in sorted(settings_overrides.items()): if hasattr(writer.builder.config, k) and writer.builder.config[k] != v: writer.builder.config[k] = v _, pub = core.publish_programmatically( source=s, source_path=None, destination_path=destination_path, writer=writer, writer_name=writer_name, settings_overrides=settings_overrides, source_class=StringInput, destination_class=StringOutput, destination=destination, reader=None, reader_name='standalone', parser=None, parser_name='restructuredtext', settings=None, settings_spec=None, config_section=None, enable_exit_status=False) doctree = pub.document if filter_nodes is not None: if layout == "docutils" and writer != "doctree": raise ValueError( "filter_nodes is not None, layout must not be 'docutils'") filter_nodes(doctree) mockapp.finalize(doctree, external_docnames=external_docnames) parts = pub.writer.parts if not keep_warnings: if isinstance(parts["whole"], list): # Not html. exp = "".join(parts["whole"]) else: exp = re.sub('(<div class="system-message">(.|\\n)*?</div>)', "", parts["whole"]) else: if isinstance(parts["whole"], list): exp = "".join(parts["whole"]) else: exp = parts["whole"] if ret_doctree: return doctree if layout == "docutils": return exp else: page = None pages = [] main = ("/{0}.m.html".format(document_name), "/{0}.m.{1}".format(document_name, writer_name), document_name) if not hasattr(writer.builder, "iter_pages"): raise AttributeError( "Class '{0}' must have a method 'iter_pages' which returns a dictionary." .format(writer.builder)) contents = [] for k, v in writer.builder.iter_pages(): pages.append(k) contents.append(v) if k in main: page = v break if page is None and len(contents) == 1: page = contents[0] if page is None: raise ValueError( "No page contents was produced, only '{0}'.".format(pages)) if layout == "sphinx": if isinstance(page, str): return page else: return "\n".join(page) elif layout == "sphinx_body": lines = page.replace('</head>', '</head>\n').split("\n") keep = [] begin = False for line in lines: s = line.strip(" \n\r") if s == "</body>": begin = False if begin: keep.append(line) if s == "<body>": begin = True res = "\n".join(keep) return res else: raise ValueError( "Unexpected value for layout '{0}'".format(layout))
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings self.use_latex_toc = settings.use_latex_toc self.hyperlink_color = settings.hyperlink_color if self.hyperlink_color == '0': self.hyperlink_color = 'black' self.colorlinks = 'false' else: self.colorlinks = 'true' # language: labels, bibliographic_fields, and author_separators. # to allow writing labes for specific languages. self.language = languages.get_language(settings.language_code) self.babel = Babel(settings.language_code) self.author_separator = self.language.author_separators[0] if self.babel.get_language(): self.d_options += ',%s' % \ self.babel.get_language() self.head_prefix = [ self.latex_head % (self.d_options, self.settings.documentclass), '\\usepackage{babel}\n', # language is in documents settings. '\\usepackage{shortvrb}\n', # allows verb in footnotes. self.encoding, # * tabularx: for docinfo, automatic width of columns, always on one page. '\\usepackage{tabularx}\n', '\\usepackage{longtable}\n', # possible other packages. # * fancyhdr # * ltxtable is a combination of tabularx and longtable (pagebreaks). # but ?? # # extra space between text in tables and the line above them '\\setlength{\\extrarowheight}{2pt}\n', '\\usepackage{amsmath}\n', # what fore amsmath. '\\usepackage{graphicx}\n', '\\usepackage{color}\n', '\\usepackage{multirow}\n', self.linking % (self.colorlinks, self.hyperlink_color, self.hyperlink_color), # geometry and fonts might go into style.tex. self.geometry % (self.d_paper, self.d_margins), # self.generator, # latex lengths '\\newlength{\\admonitionwidth}\n', '\\setlength{\\admonitionwidth}{0.9\\textwidth}\n' # width for docinfo tablewidth '\\newlength{\\docinfowidth}\n', '\\setlength{\\docinfowidth}{0.9\\textwidth}\n' ] self.head_prefix.extend(latex_headings['optionlist_environment']) self.head_prefix.extend(latex_headings['footnote_floats']) self.head_prefix.extend(latex_headings['some_commands']) ## stylesheet is last: so it might be possible to overwrite defaults. stylesheet = self.get_stylesheet_reference() if stylesheet: self.head_prefix.append(self.stylesheet % (stylesheet)) if self.linking: # and maybe check for pdf self.pdfinfo = [] self.pdfauthor = None # pdftitle, pdfsubject, pdfauthor, pdfkeywords, pdfcreator, pdfproducer else: self.pdfinfo = None # NOTE: Latex wants a date and an author, rst puts this into # docinfo, so normally we donot want latex author/date handling. # latex article has its own handling of date and author, deactivate. self.latex_docinfo = 0 self.head = [] if not self.latex_docinfo: self.head.extend(['\\author{}\n', '\\date{}\n']) self.body_prefix = ['\\raggedbottom\n'] # separate title, so we can appen subtitle. self.title = "" self.body = [] self.body_suffix = ['\n'] self.section_level = 0 self.context = [] self.topic_class = '' # column specification for tables self.colspecs = [] # Flags to encode # --------------- # verbatim: to tell encode not to encode. self.verbatim = 0 # insert_newline: to tell encode to replace blanks by "~". self.insert_none_breaking_blanks = 0 # insert_newline: to tell encode to add latex newline. self.insert_newline = 0 # mbox_newline: to tell encode to add mbox and newline. self.mbox_newline = 0 # enumeration is done by list environment. self._enum_cnt = 0 # docinfo. self.docinfo = None # inside literal block: no quote mangling. self.literal_block = 0 self.literal = 0
def patched_get_language(language_code: str, reporter: Reporter = None) -> Any: return get_language(language_code)
def __init__(self, document, briefing=False): """ Initialize ANSICode translator - briefing: (boolean) Limit translation to a single paragraph """ logger.debug( "Using custom ANSICode translator with docutils document writer") nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) self.head = [] self.body = [] self.section_level = 0 self.brief_translation = briefing self.beyond_limit = False self.first_main_paragraph = None # Identify main paragraph of the document to limit translation if self.brief_translation: error_msg = "RST document is not suitable for single paragraph conversion, {} not found" first_section_index = document.first_child_matching_class( nodes.section) if first_section_index: self.first_section = document[first_section_index] logger.debug( f"Found first section of the document with index {first_section_index}" ) first_paragraph_index = self.first_section.first_child_matching_class( nodes.paragraph) if first_paragraph_index: self.first_main_paragraph = self.first_section[ first_paragraph_index] logger.debug( f"Found main paragraph of the document with index {first_paragraph_index}" ) else: error_exit( error_msg.format("paragraph inside first section")) else: error_exit(error_msg.format("main section element")) # ANSI Escape Codes self.defs = { 'emphasis': ('\033[4m', '\033[24m'), # Underline on/off 'strong': ('\033[1m', '\033[22m'), # Bold on/off 'literal': ('\033[7m`', '`\033[27m'), # Inverse on/off and backquotes 'warning': ('\033[1;31;7m', '\033[0;27m'), # Red badge on/off 'info': ('\033[1;32;7m', '\033[0;27m'), # Green badge on/off 'update': ('\033[7m', '\033[27m'), # Inverse on/off 'problematic': ('\n!!!\n', '\n!!!\n'), } self.badges = ['Warning', 'Info']
def patched_get_language(language_code, reporter=None): # type: (unicode, Reporter) -> Any return get_language(language_code)
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode) self.head = [] self.body = [] self.foot = [] self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None # the list style "*" bullet or "#" numbered self._list_char = [] # writing the header .TH and .SH NAME is postboned after # docinfo. self._docinfo = { "title": "", "subtitle": "", "manual_section": "", "manual_group": "", "author": "", "date": "", "copyright": "", "version": "", } self._in_docinfo = None self._active_table = None self._in_entry = None self.header_written = 0 self.authors = [] self.section_level = 0 self._indent = [0] # central definition of simple processing rules # what to output on : visit, depart self.defs = { 'indent': ('.INDENT %.1f\n', '.UNINDENT\n'), 'definition': ('', ''), 'definition_list': ('', '.TP 0\n'), 'definition_list_item': ('\n.TP', ''), #field_list #field 'field_name': ('\n.TP\n.B ', '\n'), 'field_body': ( '', '.RE\n', ), 'literal': ('\\fB', '\\fP'), 'literal_block': ('\n.nf\n', '\n.fi\n'), #option_list 'option_list_item': ('\n.TP', ''), #option_group, option 'description': ('\n', ''), 'reference': (r'\fI\%', r'\fP'), #'target' : (r'\fI\%', r'\fP'), 'emphasis': ('\\fI', '\\fP'), 'strong': ('\\fB', '\\fP'), 'term': ('\n.B ', '\n'), 'title_reference': ('\\fI', '\\fP'), 'problematic': ('\n.nf\n', '\n.fi\n'), }
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code arglen = len(inspect.getargspec(languages.get_language)[0]) if arglen == 2: self.language = languages.get_language(lcode, self.document.reporter) else: self.language = languages.get_language(lcode) self.head = [] self.body = [] self.foot = [] self.section_level = 0 self.context = [] self.topic_class = '' self.colspecs = [] self.compact_p = 1 self.compact_simple = None # the list style "*" bullet or "#" numbered self._list_char = [] # writing the header .TH and .SH NAME is postboned after # docinfo. self._docinfo = { "title": "", "title_upper": "", "subtitle": "", "manual_section": "", "manual_group": "", "author": [], "date": "", "copyright": "", "version": "", } self._docinfo_keys = [] # a list to keep the sequence as in source. self._docinfo_names = {} # to get name from text not normalized. self._in_docinfo = None self._active_table = None self._in_literal = False self.header_written = 0 self._line_block = 0 self.authors = [] self.section_level = 0 self._indent = [0] # central definition of simple processing rules # what to output on : visit, depart # Do not use paragraph requests ``.PP`` because these set indentation. # use ``.sp``. Remove superfluous ``.sp`` in ``astext``. # # Fonts are put on a stack, the top one is used. # ``.ft P`` or ``\\fP`` pop from stack. # ``B`` bold, ``I`` italic, ``R`` roman should be available. # Hopefully ``C`` courier too. self.defs = { 'indent': ('.INDENT %.1f\n', '.UNINDENT\n'), 'definition_list_item': ('.TP', ''), 'field_name': ('.TP\n.B ', '\n'), 'literal': ('\\fB', '\\fP'), 'literal_block': ('.sp\n.nf\n.ft C\n', '\n.ft P\n.fi\n'), 'option_list_item': ('.TP\n', ''), 'reference': (r'\%', r'\:'), 'emphasis': ('\\fI', '\\fP'), 'strong': ('\\fB', '\\fP'), 'term': ('\n.B ', '\n'), 'title_reference': ('\\fI', '\\fP'), 'topic-title': ('.SS ', ), 'sidebar-title': ('.SS ', ), 'problematic': ('\n.nf\n', '\n.fi\n'), }
def assemble_doctree(self, docname, title, author, appendices): self.docnames = set([docname]) self.info(darkgreen(docname) + " ", nonl=1) def process_tree(docname, tree): tree = tree.deepcopy() for toctreenode in tree.traverse(addnodes.toctree): newnodes = [] includefiles = map(str, toctreenode['includefiles']) for includefile in includefiles: try: self.info(darkgreen(includefile) + " ", nonl=1) subtree = process_tree(includefile, self.env.get_doctree(includefile)) self.docnames.add(includefile) except Exception: self.warn('%s: toctree contains ref to nonexisting file %r'\ % (docname, includefile)) else: sof = addnodes.start_of_file(docname=includefile) sof.children = subtree.children newnodes.append(sof) toctreenode.parent.replace(toctreenode, newnodes) return tree tree = self.env.get_doctree(docname) tree = process_tree(docname, tree) if self.config.language: langmod = languages.get_language(self.config.language[:2]) else: langmod = languages.get_language('en') if self.config.pdf_use_index: # Add index at the end of the document # This is a hack. create_index creates an index from # ALL the documents data, not just this one. # So, we preserve a copy, use just what we need, then # restore it. #from pudb import set_trace; set_trace() t=copy(self.env.indexentries) try: self.env.indexentries={docname:self.env.indexentries[docname+'-gen']} except KeyError: self.env.indexentries={} for dname in self.docnames: self.env.indexentries[dname]=t.get(dname,[]) genindex = self.env.create_index(self) self.env.indexentries=t # EOH (End Of Hack) if genindex: # No point in creating empty indexes index_nodes=genindex_nodes(genindex) tree.append(nodes.raw(text='OddPageBreak twoColumn', format='pdf')) tree.append(index_nodes) # This is stolen from the HTML builder #moduleindex = self.env.domaindata['py']['modules'] if self.config.pdf_use_modindex and self.env.modules: modules = sorted(((mn, ('#module-' + mn, sy, pl, dep)) for (mn, (fn, sy, pl, dep)) in self.env.modules.iteritems()), key=lambda x: x[0].lower()) # collect all platforms platforms = set() letters = [] pmn = '' fl = '' # first letter modindexentries = [] num_toplevels = 0 num_collapsables = 0 cg = 0 # collapse group for mn, (fn, sy, pl, dep) in modules: pl = pl and pl.split(', ') or [] platforms.update(pl) ignore = self.env.config['modindex_common_prefix'] ignore = sorted(ignore, key=len, reverse=True) for i in ignore: if mn.startswith(i): mn = mn[len(i):] stripped = i break else: stripped = '' if fl != mn[0].lower() and mn[0] != '_': # heading letter = mn[0].upper() if letter not in letters: modindexentries.append(['', False, 0, False, letter, '', [], False, '']) letters.append(letter) tn = mn.split('.')[0] if tn != mn: # submodule if pmn == tn: # first submodule - make parent collapsable modindexentries[-1][1] = True num_collapsables += 1 elif not pmn.startswith(tn): # submodule without parent in list, add dummy entry cg += 1 modindexentries.append([tn, True, cg, False, '', '', [], False, stripped]) else: num_toplevels += 1 cg += 1 modindexentries.append([mn, False, cg, (tn != mn), fn, sy, pl, dep, stripped]) pmn = mn fl = mn[0].lower() platforms = sorted(platforms) # As some parts of the module names may have been stripped, those # names have changed, thus it is necessary to sort the entries. if ignore: def sorthelper(entry): name = entry[0] if name == '': # heading name = entry[4] return name.lower() modindexentries.sort(key=sorthelper) letters.sort() # Now, let's try to do the same thing # modindex.html does, more or less output=['DUMMY','=====','', '.. _modindex:\n\n'] t=_('Global Module Index') t+='\n'+'='*len(t)+'\n' output.append(t) for modname, collapse, cgroup, indent,\ fname, synops, pform, dep, stripped in modindexentries: if not modname: # A letter output.append('.. cssclass:: heading4\n\n%s\n\n'%fname) else: # A module if fname: output.append('`%s <%s>`_ '%(stripped+modname,fname)) if pform and pform[0]: output[-1]+='*(%s)*'%' '.join(pform) if synops: output[-1]+=', *%s*'%synops if dep: output[-1]+=' **%s**'%_('Deprecated') output.append('') dt = docutils.core.publish_doctree('\n'.join(output))[1:] dt.insert(0,nodes.raw(text='OddPageBreak twoColumn', format='pdf')) tree.extend(dt) if appendices: tree.append(nodes.raw(text='OddPageBreak %s'%self.page_template, format='pdf')) self.info() self.info('adding appendixes...', nonl=1) for docname in appendices: self.info(darkgreen(docname) + " ", nonl=1) appendix = self.env.get_doctree(docname) appendix['docname'] = docname tree.append(appendix) self.info('done') self.info() self.info("resolving references...") #print tree #print '--------------' self.env.resolve_references(tree, docname, self) #print tree for pendingnode in tree.traverse(addnodes.pending_xref): # This needs work, need to keep track of all targets # so I don't replace and create hanging refs, which # crash if pendingnode.get('reftarget',None) == 'genindex'\ and self.config.pdf_use_index: pendingnode.replace_self(nodes.reference(text=pendingnode.astext(), refuri=pendingnode['reftarget'])) if pendingnode.get('reftarget',None) == 'modindex'\ and self.config.pdf_use_modindex: pendingnode.replace_self(nodes.reference(text=pendingnode.astext(), refuri=pendingnode['reftarget'])) else: # FIXME: This is from the LaTeX builder and I dtill don't understand it # well, and doesn't seem to work # resolve :ref:s to distant tex files -- we can't add a cross-reference, # but append the document name docname = pendingnode['refdocname'] sectname = pendingnode['refsectname'] newnodes = [nodes.emphasis(sectname, sectname)] for subdir, title in self.titles: if docname.startswith(subdir): newnodes.append(nodes.Text(_(' (in '), _(' (in '))) newnodes.append(nodes.emphasis(title, title)) newnodes.append(nodes.Text(')', ')')) break else: pass pendingnode.replace_self(newnodes) #else: #pass return tree
def __init__(self, document): nodes.NodeVisitor.__init__(self, document) self.settings = settings = document.settings lcode = settings.language_code self.language = languages.get_language(lcode, document.reporter) self.head = [] self.body = [] self.foot = [] self.section_level = 0 self.context = [] self.topic_class = "" self.colspecs = [] self.compact_p = 1 self.compact_simple = None # the list style "*" bullet or "#" numbered self._list_char = [] # writing the header .TH and .SH NAME is postboned after # docinfo. self._docinfo = { "title": "", "title_upper": "", "subtitle": "", "manual_section": "", "manual_group": "", "author": [], "date": "", "copyright": "", "version": "", } self._docinfo_keys = [] # a list to keep the sequence as in source. self._docinfo_names = {} # to get name from text not normalized. self._in_docinfo = None self._active_table = None self._in_literal = False self.header_written = 0 self._line_block = 0 self.authors = [] self.section_level = 0 self._indent = [0] # central definition of simple processing rules # what to output on : visit, depart # Do not use paragraph requests ``.PP`` because these set indentation. # use ``.sp``. Remove superfluous ``.sp`` in ``astext``. # # Fonts are put on a stack, the top one is used. # ``.ft P`` or ``\\fP`` pop from stack. # But ``.BI`` seams to fill stack with BIBIBIBIB... # ``B`` bold, ``I`` italic, ``R`` roman should be available. # Hopefully ``C`` courier too. self.defs = { "indent": (".INDENT %.1f\n", ".UNINDENT\n"), "definition_list_item": (".TP", ""), "field_name": (".TP\n.B ", "\n"), "literal": ("\\fB", "\\fP"), "literal_block": (".sp\n.nf\n.ft C\n", "\n.ft P\n.fi\n"), "option_list_item": (".TP\n", ""), "reference": (r"\fI\%", r"\fP"), "emphasis": ("\\fI", "\\fP"), "strong": ("\\fB", "\\fP"), "term": ("\n.B ", "\n"), "title_reference": ("\\fI", "\\fP"), "topic-title": (".SS ", ), "sidebar-title": (".SS ", ), "problematic": ("\n.nf\n", "\n.fi\n"), }
def translate(self): visitor = PDFTranslator(self.document, self.builder) self.document.walkabout(visitor) if self.config.language: langmod = languages.get_language(self.config.language[:2]) else: langmod = languages.get_language('en') # Generate Contents topic manually contents=nodes.topic(classes=['contents']) contents+=nodes.title('') contents[0]+=nodes.Text( langmod.labels['contents']) contents['ids']=['Contents'] pending=nodes.topic() contents.append(pending) pending.details={} self.document.insert(0,nodes.raw(text='SetPageCounter 1 arabic', format='pdf')) self.document.insert(0,nodes.raw(text='OddPageBreak %s'%self.page_template, format='pdf')) self.document.insert(0,contents) self.document.insert(0,nodes.raw(text='SetPageCounter 1 lowerroman', format='pdf')) contTrans=PDFContents(self.document) contTrans.startnode=pending contTrans.apply() if self.config.pdf_use_coverpage: # Generate cover page spacer=docutils.core.publish_doctree('.. raw:: pdf\n\n Spacer 0 3cm\n\n')[0] doctitle=nodes.title() doctitle.append(nodes.Text(self.document.settings.title or visitor.elements['title'])) docsubtitle=nodes.subtitle() docsubtitle.append(nodes.Text('%s %s'%(_('version'),self.config.version))) # This is what's used in the python docs because # Latex does a manual linrebreak. This sucks. authors=self.document.settings.author.split('\\') authornodes=[] for author in authors: node=nodes.paragraph() node.append(nodes.Text(author)) node['classes']=['author'] authornodes.append(node) date=nodes.paragraph() date.append(nodes.Text(ustrftime(self.config.today_fmt or _('%B %d, %Y')))) date['classes']=['author'] self.document.insert(0,nodes.raw(text='OddPageBreak %s'%self.page_template, format='pdf')) self.document.insert(0,date) self.document.insert(0,spacer) for node in authornodes[::-1]: self.document.insert(0,node) self.document.insert(0,spacer) self.document.insert(0,docsubtitle) self.document.insert(0,doctitle) sio=StringIO() if self.invariant: createpdf.patch_PDFDate() createpdf.patch_digester() createpdf.RstToPdf(sphinx=True, stylesheets=self.stylesheets, language=self.__language, breaklevel=self.breaklevel, breakside=self.breakside, fit_mode=self.fitmode, font_path=self.fontpath, inline_footnotes=self.inline_footnotes, highlightlang=self.highlightlang, splittables=self.splittables, style_path=[self.srcdir], basedir=self.srcdir, def_dpi=self.default_dpi, ).createPdf(doctree=self.document, output=sio, compressed=self.compressed) self.output=sio.getvalue()