null+****@clear*****
null+****@clear*****
2011年 5月 3日 (火) 23:06:53 JST
Kouhei Sutou 2011-05-03 14:06:53 +0000 (Tue, 03 May 2011) New Revision: ff52e31c9fc45b4ee7156022f58d634d18440816 Log: add not completed textile builder for Sphinx. :p Added files: doc/ja/source/textile.py Modified files: .gitignore doc/ja/Makefile.am doc/ja/source/conf.py Modified: .gitignore (+2 -0) =================================================================== --- .gitignore 2011-05-01 08:51:08 +0000 (84d8368) +++ .gitignore 2011-05-03 14:06:53 +0000 (1713efe) @@ -42,6 +42,8 @@ version.sh /doc/ja/html/ /doc/ja/rdoc/ /doc/ja/man/ +/doc/ja/pickle/ +/doc/ja/textile/ /doc/ja/.buildinfo /doc/ja/_sources/ /doc/ja/_static/ Modified: doc/ja/Makefile.am (+8 -0) =================================================================== --- doc/ja/Makefile.am 2011-05-01 08:51:08 +0000 (98c3f7e) +++ doc/ja/Makefile.am 2011-05-03 14:06:53 +0000 (9f3b5e9) @@ -28,6 +28,7 @@ help: @echo " qthelp to make HTML files and a qthelp project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " rdoc to make RDoc files" + @echo " textile to make Textile files" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @@ -43,6 +44,7 @@ clean-local: -rm -rf $(BUILDDIR)/qthelp -rm -rf $(BUILDDIR)/latex -rm -rf $(BUILDDIR)/rdoc + -rm -rf $(BUILDDIR)/textile -rm -rf $(BUILDDIR)/changes -rm -rf $(BUILDDIR)/linkcheck -rm -rf $(BUILDDIR)/doctest @@ -100,6 +102,11 @@ rdoc: @echo @echo "Build finished; the RDoc files are in $(BUILDDIR)/rdoc." +textile: + $(SPHINX_BUILD) -b textile $(ALLSPHINXOPTS) $(BUILDDIR)/textile + @echo + @echo "Build finished; the Textile files are in $(BUILDDIR)/textile." + changes: $(SPHINX_BUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @@ -258,6 +265,7 @@ source_files = \ source/reference.txt \ source/spec.txt \ source/spec/search.txt \ + source/textile.py \ source/troubleshooting.txt \ source/troubleshooting/different_results_with_the_same_keyword.txt \ source/tutorial.txt \ Modified: doc/ja/source/conf.py (+2 -1) =================================================================== --- doc/ja/source/conf.py 2011-05-01 08:51:08 +0000 (a78231d) +++ doc/ja/source/conf.py 2011-05-03 14:06:53 +0000 (f1e4f43) @@ -37,8 +37,9 @@ if parse_version(sphinx.__version__) < parse_version(SPHINX_VERSION_REQUIRED): # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -#extensions = ["source.rdoc"] extensions = [] +# extensions.append("source.rdoc") +# extensions.append("source.textile") try: import rst2pdf if parse_version(rst2pdf.version) >= parse_version(RST2PDF_VERSION_REQUIRED): Added: doc/ja/source/textile.py (+771 -0) 100644 =================================================================== --- /dev/null +++ doc/ja/source/textile.py 2011-05-03 14:06:53 +0000 (a747741) @@ -0,0 +1,771 @@ +# -*- coding: utf-8 -*- +""" + source.textile + ~~~~~~~~~~~~~~ + + Textile Sphinx builder. + + Derived from Sphinx's plain-text sphinx builder. + + NOTE: NOT COMPLETED YET. + + :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + Copyright 2011 by Kouhei Sutou. + :license: BSD, see LICENSE for details. +""" + +# For builder. +import codecs +from os import path + +from docutils.io import StringOutput + +from sphinx.builders import Builder +from sphinx.util.osutil import ensuredir, os_path + +class TextileBuilder(Builder): + name = 'textile' + format = 'textile' + out_suffix = '.textile' + + def init(self): + pass + + def get_outdated_docs(self): + for docname in self.env.found_docs: + if docname not in self.env.all_docs: + yield docname + continue + targetname = self.env.doc2path(docname, self.outdir, + self.out_suffix) + try: + targetmtime = path.getmtime(targetname) + except Exception: + targetmtime = 0 + try: + srcmtime = path.getmtime(self.env.doc2path(docname)) + if srcmtime > targetmtime: + yield docname + except EnvironmentError: + # source doesn't exist anymore + pass + + def get_target_uri(self, docname, typ=None): + return '' + + def prepare_writing(self, docnames): + self.writer = TextileWriter(self) + + def write_doc(self, docname, doctree): + destination = StringOutput(encoding='utf-8') + self.writer.write(doctree, destination) + outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix) + ensuredir(path.dirname(outfilename)) + try: + f = codecs.open(outfilename, 'w', 'utf-8') + try: + f.write(self.writer.output) + finally: + f.close() + except (IOError, OSError), err: + self.warn("error writing file %s: %s" % (outfilename, err)) + + def finish(self): + pass + +# For writer. +import re +import textwrap + +from docutils import nodes, writers + +from sphinx import addnodes +from sphinx.locale import admonitionlabels, versionlabels, _ + +class TextileWriter(writers.Writer): + supported = ('textile',) + settings_spec = ('No options here.', '', ()) + settings_defaults = {} + + output = None + + def __init__(self, builder): + writers.Writer.__init__(self) + self.builder = builder + + def translate(self): + visitor = TextileTranslator(self.document, self.builder) + self.document.walkabout(visitor) + self.output = visitor.body + + +MAXWIDTH = 700 +STDINDENT = 3 + +class TextileTranslator(nodes.NodeVisitor): + sectionchars = '*=-~"+' + + def __init__(self, document, builder): + nodes.NodeVisitor.__init__(self, document) + + self.states = [[]] + self.stateindent = [0] + self.list_counter = [] + self.sectionlevel = 0 + self.table = None + + def add_text(self, text): + self.states[-1].append((-1, text)) + def new_state(self, indent=STDINDENT): + self.states.append([]) + self.stateindent.append(indent) + def end_state(self, wrap=True, end=[''], first=None): + content = self.states.pop() + maxindent = sum(self.stateindent) + indent = self.stateindent.pop() + result = [] + toformat = [] + def do_format(): + if not toformat: + return + if wrap: + res = textwrap.wrap(''.join(toformat), width=MAXWIDTH-maxindent) + else: + res = ''.join(toformat).splitlines() + if end: + res += end + result.append((indent, res)) + for itemindent, item in content: + if itemindent == -1: + toformat.append(item) + else: + do_format() + result.append((indent + itemindent, item)) + toformat = [] + do_format() + if first is not None and result: + itemindent, item = result[0] + if item: + result.insert(0, (itemindent - indent, [first + item[0]])) + result[1] = (itemindent, item[1:]) + self.states[-1].extend(result) + + def visit_document(self, node): + self.new_state(0) + def depart_document(self, node): + self.end_state() + self.body = '\n'.join(line and (' '*indent + line) + for indent, lines in self.states[0] + for line in lines) + # XXX header/footer? + + def visit_highlightlang(self, node): + raise nodes.SkipNode + + def visit_section(self, node): + self._title_char = self.sectionchars[self.sectionlevel] + self.sectionlevel += 1 + def depart_section(self, node): + self.sectionlevel -= 1 + + def visit_topic(self, node): + self.new_state(0) + def depart_topic(self, node): + self.end_state() + + visit_sidebar = visit_topic + depart_sidebar = depart_topic + + def visit_rubric(self, node): + self.new_state(0) + self.add_text('-[ ') + def depart_rubric(self, node): + self.add_text(' ]-') + self.end_state() + + def visit_compound(self, node): + pass + def depart_compound(self, node): + pass + + def visit_glossary(self, node): + pass + def depart_glossary(self, node): + pass + + def visit_title(self, node): + if isinstance(node.parent, nodes.Admonition): + self.add_text(node.astext()+': ') + raise nodes.SkipNode + self.new_state(0) + def depart_title(self, node): + text = ''.join(x[1] for x in self.states.pop() if x[0] == -1) + text = "h%d. %s" % (self.sectionlevel, text) + self.stateindent.pop() + self.states[-1].append((0, ['', text, ''])) + + def visit_subtitle(self, node): + pass + def depart_subtitle(self, node): + pass + + def visit_attribution(self, node): + self.add_text('-- ') + def depart_attribution(self, node): + pass + + def visit_desc(self, node): + pass + def depart_desc(self, node): + pass + + def visit_desc_signature(self, node): + self.new_state(0) + if node.parent['objtype'] in ('class', 'exception'): + self.add_text('%s ' % node.parent['objtype']) + def depart_desc_signature(self, node): + # XXX: wrap signatures in a way that makes sense + self.end_state(wrap=False, end=None) + + def visit_desc_name(self, node): + pass + def depart_desc_name(self, node): + pass + + 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.add_text(' -> ') + def depart_desc_returns(self, node): + pass + + def visit_desc_parameterlist(self, node): + self.add_text('(') + self.first_param = 1 + def depart_desc_parameterlist(self, node): + self.add_text(')') + + def visit_desc_parameter(self, node): + if not self.first_param: + self.add_text(', ') + else: + self.first_param = 0 + self.add_text(node.astext()) + raise nodes.SkipNode + + def visit_desc_optional(self, node): + self.add_text('[') + def depart_desc_optional(self, node): + self.add_text(']') + + def visit_desc_annotation(self, node): + pass + def depart_desc_annotation(self, node): + pass + + def visit_refcount(self, node): + pass + def depart_refcount(self, node): + pass + + def visit_desc_content(self, node): + self.new_state() + self.add_text('\n') + def depart_desc_content(self, node): + self.end_state() + + def visit_figure(self, node): + self.new_state() + def depart_figure(self, node): + self.end_state() + + def visit_caption(self, node): + pass + def depart_caption(self, node): + pass + + def visit_productionlist(self, node): + self.new_state() + names = [] + for production in node: + names.append(production['tokenname']) + maxlen = max(len(name) for name in names) + for production in node: + if production['tokenname']: + self.add_text(production['tokenname'].ljust(maxlen) + ' ::=') + lastname = production['tokenname'] + else: + self.add_text('%s ' % (' '*len(lastname))) + self.add_text(production.astext() + '\n') + self.end_state(wrap=False) + raise nodes.SkipNode + + def visit_seealso(self, node): + self.new_state() + def depart_seealso(self, node): + self.end_state(first='') + + def visit_footnote(self, node): + self._footnote = node.children[0].astext().strip() + self.new_state(len(self._footnote) + 3) + def depart_footnote(self, node): + self.end_state(first='[%s] ' % self._footnote) + + def visit_citation(self, node): + if len(node) and isinstance(node[0], nodes.label): + self._citlabel = node[0].astext() + else: + self._citlabel = '' + self.new_state(len(self._citlabel) + 3) + def depart_citation(self, node): + self.end_state(first='[%s] ' % self._citlabel) + + def visit_label(self, node): + raise nodes.SkipNode + + # XXX: option list could use some better styling + + def visit_option_list(self, node): + pass + def depart_option_list(self, node): + pass + + def visit_option_list_item(self, node): + self.new_state(0) + def depart_option_list_item(self, node): + self.end_state() + + def visit_option_group(self, node): + self._firstoption = True + def depart_option_group(self, node): + self.add_text(' ') + + def visit_option(self, node): + if self._firstoption: + self._firstoption = False + else: + self.add_text(', ') + def depart_option(self, node): + pass + + def visit_option_string(self, node): + pass + def depart_option_string(self, node): + pass + + def visit_option_argument(self, node): + self.add_text(node['delimiter']) + def depart_option_argument(self, node): + pass + + def visit_description(self, node): + pass + def depart_description(self, node): + pass + + def visit_tabular_col_spec(self, node): + raise nodes.SkipNode + + def visit_colspec(self, node): + self.table[0].append(node['colwidth']) + raise nodes.SkipNode + + def visit_tgroup(self, node): + pass + def depart_tgroup(self, node): + pass + + def visit_thead(self, node): + pass + def depart_thead(self, node): + pass + + def visit_tbody(self, node): + self.table.append('sep') + def depart_tbody(self, node): + pass + + def visit_row(self, node): + self.table.append([]) + def depart_row(self, node): + pass + + def visit_entry(self, node): + if node.has_key('morerows') or node.has_key('morecols'): + raise NotImplementedError('Column or row spanning cells are ' + 'not implemented.') + self.new_state(0) + def depart_entry(self, node): + text = '\n'.join('\n'.join(x[1]) for x in self.states.pop()) + self.stateindent.pop() + self.table[-1].append(text) + + def visit_table(self, node): + if self.table: + raise NotImplementedError('Nested tables are not supported.') + self.new_state(0) + self.table = [[]] + def depart_table(self, node): + lines = self.table[1:] + fmted_rows = [] + colwidths = self.table[0] + realwidths = colwidths[:] + separator = 0 + # don't allow paragraphs in table cells for now + for line in lines: + if line == 'sep': + separator = len(fmted_rows) + else: + cells = [] + for i, cell in enumerate(line): + par = textwrap.wrap(cell, width=colwidths[i]) + if par: + maxwidth = max(map(len, par)) + else: + maxwidth = 0 + realwidths[i] = max(realwidths[i], maxwidth) + cells.append(par) + fmted_rows.append(cells) + + def writesep(char='-'): + out = ['+'] + for width in realwidths: + out.append(char * (width+2)) + out.append('+') + self.add_text(''.join(out) + '\n') + + def writerow(row): + lines = map(None, *row) + for line in lines: + out = ['|'] + for i, cell in enumerate(line): + if cell: + out.append(' ' + cell.ljust(realwidths[i]+1)) + else: + out.append(' ' * (realwidths[i] + 2)) + out.append('|') + self.add_text(''.join(out) + '\n') + + for i, row in enumerate(fmted_rows): + if separator and i == separator: + writesep('=') + else: + writesep('-') + writerow(row) + writesep('-') + self.table = None + self.end_state(wrap=False) + + def visit_acks(self, node): + self.new_state(0) + self.add_text(', '.join(n.astext() for n in node.children[0].children) + + '.') + self.end_state() + raise nodes.SkipNode + + def visit_image(self, node): + self.add_text(_('[image]')) + raise nodes.SkipNode + + def visit_transition(self, node): + indent = sum(self.stateindent) + self.new_state(0) + self.add_text('=' * (MAXWIDTH - indent)) + self.end_state() + raise nodes.SkipNode + + def visit_bullet_list(self, node): + self.list_counter.append(-1) + def depart_bullet_list(self, node): + self.list_counter.pop() + + def visit_enumerated_list(self, node): + self.list_counter.append(0) + def depart_enumerated_list(self, node): + self.list_counter.pop() + + def visit_definition_list(self, node): + self.list_counter.append(-2) + def depart_definition_list(self, node): + self.list_counter.pop() + + def visit_list_item(self, node): + if self.list_counter[-1] == -1: + # bullet list + self.new_state(2) + elif self.list_counter[-1] == -2: + # definition list + pass + else: + # enumerated list + self.list_counter[-1] += 1 + self.new_state(len(str(self.list_counter[-1])) + 2) + def depart_list_item(self, node): + if self.list_counter[-1] == -1: + self.end_state(first='* ', end=None) + elif self.list_counter[-1] == -2: + pass + else: + self.end_state(first='%s. ' % self.list_counter[-1], end=None) + + def visit_definition_list_item(self, node): + self._li_has_classifier = len(node) >= 2 and \ + isinstance(node[1], nodes.classifier) + def depart_definition_list_item(self, node): + pass + + def visit_term(self, node): + self.new_state(0) + def depart_term(self, node): + if not self._li_has_classifier: + self.end_state(end=None) + + def visit_classifier(self, node): + self.add_text(' : ') + def depart_classifier(self, node): + self.end_state(end=None) + + def visit_definition(self, node): + self.new_state() + def depart_definition(self, node): + self.end_state() + + def visit_field_list(self, node): + pass + def depart_field_list(self, node): + pass + + def visit_field(self, node): + pass + def depart_field(self, node): + pass + + def visit_field_name(self, node): + self.new_state(0) + def depart_field_name(self, node): + self.add_text(':') + self.end_state(end=None) + + def visit_field_body(self, node): + self.new_state() + def depart_field_body(self, node): + self.end_state() + + def visit_centered(self, node): + pass + def depart_centered(self, node): + pass + + def visit_hlist(self, node): + pass + def depart_hlist(self, node): + pass + + def visit_hlistcol(self, node): + pass + def depart_hlistcol(self, node): + pass + + def visit_admonition(self, node): + self.new_state(0) + def depart_admonition(self, node): + self.end_state() + + def _visit_admonition(self, node): + self.new_state(2) + def _make_depart_admonition(name): + def depart_admonition(self, node): + self.end_state(first=admonitionlabels[name] + ': ') + return depart_admonition + + visit_attention = _visit_admonition + depart_attention = _make_depart_admonition('attention') + visit_caution = _visit_admonition + depart_caution = _make_depart_admonition('caution') + visit_danger = _visit_admonition + depart_danger = _make_depart_admonition('danger') + visit_error = _visit_admonition + depart_error = _make_depart_admonition('error') + visit_hint = _visit_admonition + depart_hint = _make_depart_admonition('hint') + visit_important = _visit_admonition + depart_important = _make_depart_admonition('important') + visit_note = _visit_admonition + depart_note = _make_depart_admonition('note') + visit_tip = _visit_admonition + depart_tip = _make_depart_admonition('tip') + visit_warning = _visit_admonition + depart_warning = _make_depart_admonition('warning') + + def visit_versionmodified(self, node): + self.new_state(0) + if node.children: + self.add_text(versionlabels[node['type']] % node['version'] + ': ') + else: + self.add_text(versionlabels[node['type']] % node['version'] + '.') + def depart_versionmodified(self, node): + self.end_state() + + def visit_literal_block(self, node): + self.new_state() + def depart_literal_block(self, node): + self.end_state(wrap=False) + + def visit_doctest_block(self, node): + self.new_state(0) + def depart_doctest_block(self, node): + self.end_state(wrap=False) + + def visit_line_block(self, node): + self.new_state(0) + def depart_line_block(self, node): + self.end_state(wrap=False) + + def visit_line(self, node): + pass + def depart_line(self, node): + pass + + def visit_block_quote(self, node): + self.new_state() + def depart_block_quote(self, node): + self.end_state() + + def visit_compact_paragraph(self, node): + pass + def depart_compact_paragraph(self, node): + pass + + def visit_paragraph(self, node): + if not isinstance(node.parent, nodes.Admonition) or \ + isinstance(node.parent, addnodes.seealso): + self.new_state(0) + def depart_paragraph(self, node): + if not isinstance(node.parent, nodes.Admonition) or \ + isinstance(node.parent, addnodes.seealso): + self.end_state() + + def visit_target(self, node): + raise nodes.SkipNode + + def visit_index(self, node): + raise nodes.SkipNode + + def visit_substitution_definition(self, node): + raise nodes.SkipNode + + def visit_pending_xref(self, node): + pass + def depart_pending_xref(self, node): + pass + + def visit_reference(self, node): + pass + def depart_reference(self, node): + pass + + def visit_download_reference(self, node): + pass + def depart_download_reference(self, node): + pass + + def visit_emphasis(self, node): + self.add_text('*') + def depart_emphasis(self, node): + self.add_text('*') + + def visit_literal_emphasis(self, node): + self.add_text('*') + def depart_literal_emphasis(self, node): + self.add_text('*') + + def visit_strong(self, node): + self.add_text('**') + def depart_strong(self, node): + self.add_text('**') + + def visit_abbreviation(self, node): + self.add_text('') + def depart_abbreviation(self, node): + if node.hasattr('explanation'): + self.add_text(' (%s)' % node['explanation']) + + def visit_title_reference(self, node): + self.add_text('*') + def depart_title_reference(self, node): + self.add_text('*') + + def visit_literal(self, node): + self.add_text('``') + def depart_literal(self, node): + self.add_text('``') + + def visit_subscript(self, node): + self.add_text('_') + def depart_subscript(self, node): + pass + + def visit_superscript(self, node): + self.add_text('^') + def depart_superscript(self, node): + pass + + def visit_footnote_reference(self, node): + self.add_text('[%s]' % node.astext()) + raise nodes.SkipNode + + def visit_citation_reference(self, node): + self.add_text('[%s]' % node.astext()) + raise nodes.SkipNode + + def visit_Text(self, node): + self.add_text(node.astext()) + def depart_Text(self, node): + pass + + def visit_generated(self, node): + pass + def depart_generated(self, node): + pass + + def visit_inline(self, node): + pass + def depart_inline(self, node): + pass + + def visit_problematic(self, node): + self.add_text('>>') + def depart_problematic(self, node): + self.add_text('<<') + + def visit_system_message(self, node): + self.new_state(0) + self.add_text('<SYSTEM MESSAGE: %s>' % node.astext()) + self.end_state() + raise nodes.SkipNode + + def visit_comment(self, node): + raise nodes.SkipNode + + def visit_meta(self, node): + # only valid for HTML + raise nodes.SkipNode + + def visit_raw(self, node): + if 'text' in node.get('format', '').split(): + self.body.append(node.astext()) + raise nodes.SkipNode + + def unknown_visit(self, node): + raise NotImplementedError('Unknown node: ' + node.__class__.__name__) + +def setup(app): + app.add_builder(TextileBuilder)