summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--doc/Makefile6
-rw-r--r--doc/builders.rst16
-rw-r--r--doc/conf.py5
-rw-r--r--doc/config.rst29
-rw-r--r--doc/ext/appapi.rst10
-rw-r--r--sphinx/application.py2
-rw-r--r--sphinx/builders/__init__.py1
-rw-r--r--sphinx/builders/manpage.py93
-rw-r--r--sphinx/config.py3
-rw-r--r--sphinx/ext/autosummary/__init__.py6
-rw-r--r--sphinx/ext/todo.py3
-rw-r--r--sphinx/quickstart.py58
-rw-r--r--sphinx/writers/manpage.py308
-rw-r--r--tests/test_build.py9
-rw-r--r--tests/test_quickstart.py5
16 files changed, 543 insertions, 13 deletions
diff --git a/CHANGES b/CHANGES
index 3129ca29..72a8b462 100644
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,8 @@ Release 1.0 (in development)
* Support for docutils 0.4 has been removed.
+* Added a manual page builder.
+
* New more compact doc field syntax is now recognized:
``:param type name: description``.
diff --git a/doc/Makefile b/doc/Makefile
index bfd5ca83..153a93db 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -21,6 +21,7 @@ help:
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " epub to make an epub file"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " man to make manual pages"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@@ -47,6 +48,11 @@ text:
@echo
@echo "Build finished."
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) _build/man
+ @echo
+ @echo "Build finished."
+
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
diff --git a/doc/builders.rst b/doc/builders.rst
index 9895fabc..5c61fba0 100644
--- a/doc/builders.rst
+++ b/doc/builders.rst
@@ -127,6 +127,22 @@ Note that a direct PDF builder using ReportLab is available in `rst2pdf
.. versionadded:: 0.4
+.. module:: sphinx.builders.manpage
+.. class:: ManualPageBuilder
+
+ This builder produces manual pages in the groff format. You have to specify
+ which documents are to be included in which manual pages via the
+ :confval:`man_pages` configuration value.
+
+ Its name is ``man``.
+
+ .. note::
+
+ This builder requires the docutils manual page writer, which is only
+ available as of docutils 0.6.
+
+ .. versionadded:: 1.0
+
.. currentmodule:: sphinx.builders.html
.. class:: SerializingHTMLBuilder
diff --git a/doc/conf.py b/doc/conf.py
index 57556990..b1a55b0e 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -49,6 +49,11 @@ latex_elements = {
todo_include_todos = True
+man_pages = [
+ ('contents', 'sphinx-all', 'Sphinx documentation generator system manual',
+ 'Georg Brandl', 1),
+]
+
# -- Extension interface -------------------------------------------------------
diff --git a/doc/config.rst b/doc/config.rst
index 0793759a..6f9a7603 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -914,6 +914,35 @@ These options influence LaTeX output.
Use the ``'pointsize'`` key in the :confval:`latex_elements` value.
+.. _man-options:
+
+Options for manual page output
+------------------------------
+
+These options influence manual page output.
+
+.. confval:: man_pages
+
+ This value determines how to group the document tree into manual pages. It
+ must be a list of tuples ``(startdocname, name, description, authors,
+ section)``, where the items are:
+
+ * *startdocname*: document name that is the "root" of the manual page. All
+ documents referenced by it in TOC trees will be included in the manual file
+ too. (If you want one master manual page, use your :confval:`master_doc`
+ here.)
+ * *name*: name of the manual page. This should be a short string without
+ spaces or special characters. It is used to determine the file name as
+ well as the name of the manual page (in the NAME section).
+ * *description*: description of the manual page. This is used in the NAME
+ section.
+ * *authors*: A list of strings with authors, or a single string.
+ * *section*: The manual page section. Used for the output file name as well
+ as in the manual page header.
+
+ .. versionadded:: 1.0
+
+
.. rubric:: Footnotes
.. [1] A note on available globbing syntax: you can use the standard shell
diff --git a/doc/ext/appapi.rst b/doc/ext/appapi.rst
index a643a478..8df028e1 100644
--- a/doc/ext/appapi.rst
+++ b/doc/ext/appapi.rst
@@ -61,11 +61,11 @@ the following public API:
Register a Docutils node class. This is necessary for Docutils internals.
It may also be used in the future to validate nodes in the parsed documents.
- Node visitor functions for the Sphinx HTML, LaTeX and text writers can be
- given as keyword arguments: the keyword must be one or more of ``'html'``,
- ``'latex'``, ``'text'``, the value a 2-tuple of ``(visit, depart)`` methods.
- ``depart`` can be ``None`` if the ``visit`` function raises
- :exc:`docutils.nodes.SkipNode`. Example:
+ Node visitor functions for the Sphinx HTML, LaTeX, text and manpage writers
+ can be given as keyword arguments: the keyword must be one or more of
+ ``'html'``, ``'latex'``, ``'text'``, ``'man'``, the value a 2-tuple of
+ ``(visit, depart)`` methods. ``depart`` can be ``None`` if the ``visit``
+ function raises :exc:`docutils.nodes.SkipNode`. Example:
.. code-block:: python
diff --git a/sphinx/application.py b/sphinx/application.py
index 2b26fa66..95ca6279 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -351,6 +351,8 @@ class Sphinx(object):
from sphinx.writers.latex import LaTeXTranslator as translator
elif key == 'text':
from sphinx.writers.text import TextTranslator as translator
+ elif key == 'man':
+ from sphinx.writers.manpage import ManualPageTranslator as translator
else:
# ignore invalid keys for compatibility
continue
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index 6ab6af3e..e345d570 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -326,6 +326,7 @@ BUILTIN_BUILDERS = {
'epub': ('epub', 'EpubBuilder'),
'latex': ('latex', 'LaTeXBuilder'),
'text': ('text', 'TextBuilder'),
+ 'man': ('manpage', 'ManualPageBuilder'),
'changes': ('changes', 'ChangesBuilder'),
'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
}
diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py
new file mode 100644
index 00000000..7b3aef1d
--- /dev/null
+++ b/sphinx/builders/manpage.py
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.builders.manpage
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ Manual pages builder.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from os import path
+
+from docutils.io import FileOutput
+from docutils.frontend import OptionParser
+
+from sphinx import addnodes
+from sphinx.errors import SphinxError
+from sphinx.builders import Builder
+from sphinx.environment import NoUri
+from sphinx.util.nodes import inline_all_toctrees
+from sphinx.util.console import bold, darkgreen
+try:
+ from sphinx.writers.manpage import ManualPageWriter
+ has_manpage_writer = True
+except ImportError:
+ has_manpage_writer = False
+
+
+class ManualPageBuilder(Builder):
+ """
+ Builds groff output in manual page format.
+ """
+ name = 'man'
+ format = 'man'
+ supported_image_types = []
+
+ def init(self):
+ if not has_manpage_writer:
+ raise SphinxError('The docutils manual page writer can\'t be '
+ 'found; it is only available as of docutils 0.6.')
+ if not self.config.man_pages:
+ self.warn('no "man_pages" config value found; no manual pages '
+ 'will be written')
+
+ def get_outdated_docs(self):
+ return 'all manpages' # for now
+
+ def get_target_uri(self, docname, typ=None):
+ if typ == 'token':
+ return ''
+ raise NoUri
+
+ def write(self, *ignored):
+ docwriter = ManualPageWriter(self)
+ docsettings = OptionParser(
+ defaults=self.env.settings,
+ components=(docwriter,)).get_default_values()
+
+ self.info(bold('writing... '), nonl=True)
+
+ for info in self.config.man_pages:
+ docname, name, description, authors, section = info
+ if isinstance(authors, basestring):
+ authors = [authors]
+
+ targetname = '%s.%s' % (name, section)
+ self.info(darkgreen(targetname) + ' { ', nonl=True)
+ destination = FileOutput(
+ destination_path=path.join(self.outdir, targetname),
+ encoding='utf-8')
+
+ tree = self.env.get_doctree(docname)
+ docnames = set()
+ largetree = inline_all_toctrees(self, docnames, docname, tree,
+ darkgreen)
+ self.info('} ', nonl=True)
+ self.env.resolve_references(largetree, docname, self)
+ # remove pending_xref nodes
+ for pendingnode in largetree.traverse(addnodes.pending_xref):
+ pendingnode.replace_self(pendingnode.children)
+
+ largetree.settings = docsettings
+ largetree.settings.title = name
+ largetree.settings.subtitle = description
+ largetree.settings.authors = authors
+ largetree.settings.section = section
+
+ docwriter.write(largetree, destination)
+ self.info()
+
+ def finish(self):
+ pass
diff --git a/sphinx/config.py b/sphinx/config.py
index 1c262eb1..0de30a5a 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -141,6 +141,9 @@ class Config(object):
# text options
text_sectionchars = ('*=-~"+`', 'text'),
text_windows_newlines = (False, 'text'),
+
+ # manpage options
+ man_pages = ([], None),
)
def __init__(self, dirname, filename, overrides, tags):
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index a4d46b1f..cf67c7fb 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -486,11 +486,13 @@ def setup(app):
app.add_node(autosummary_toc,
html=(autosummary_toc_visit_html, autosummary_noop),
latex=(autosummary_noop, autosummary_noop),
- text=(autosummary_noop, autosummary_noop))
+ text=(autosummary_noop, autosummary_noop),
+ man=(autosummary_noop, autosummary_noop))
app.add_node(autosummary_table,
html=(autosummary_table_visit_html, autosummary_noop),
latex=(autosummary_noop, autosummary_noop),
- text=(autosummary_noop, autosummary_noop))
+ text=(autosummary_noop, autosummary_noop),
+ man=(autosummary_noop, autosummary_noop))
app.add_directive('autosummary', Autosummary)
app.add_role('autolink', autolink_role)
app.connect('doctree-read', process_autosummary_toc)
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index 96f9fdfc..ac362919 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -159,7 +159,8 @@ def setup(app):
app.add_node(todo_node,
html=(visit_todo_node, depart_todo_node),
latex=(visit_todo_node, depart_todo_node),
- text=(visit_todo_node, depart_todo_node))
+ text=(visit_todo_node, depart_todo_node),
+ man=(visit_todo_node, depart_todo_node))
app.add_directive('todo', Todo)
app.add_directive('todolist', TodoList)
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index daa88c36..4ad6e18d 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -226,13 +226,25 @@ latex_documents = [
#latex_domain_indices = True
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('%(master_str)s', '%(project_manpage)s', u'%(project_doc)s',
+ [u'%(author_str)s'], 1)
+]
+'''
+
+EPUB_CONFIG = '''
+
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
-#epub_title = ''
-#epub_author = ''
-#epub_publisher = ''
-#epub_copyright = ''
+epub_title = u'%(project_str)s'
+epub_author = u'%(author_str)s'
+epub_publisher = u'%(author_str)s'
+epub_copyright = u'%(copyright_str)s'
# The language of the text. It defaults to the language option
# or en if the language is not set.
@@ -324,6 +336,8 @@ help:
\t@echo " epub to make an epub"
\t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
\t@echo " latexpdf to make LaTeX files and run them through pdflatex"
+\t@echo " text to make text files"
+\t@echo " man to make manual pages"
\t@echo " changes to make an overview of all changed/added/deprecated items"
\t@echo " linkcheck to check all external links for integrity"
\t@echo " doctest to run all doctests embedded in the documentation \
@@ -400,6 +414,16 @@ latexpdf: latex
\tmake -C %(rbuilddir)s/latex all-pdf
\t@echo "pdflatex finished; the PDF files are in %(rbuilddir)s/latex."
+text:
+\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+\t@echo
+\t@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+\t@echo
+\t@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
changes:
\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
\t@echo
@@ -444,6 +468,8 @@ if "%%1" == "help" (
\techo. devhelp to make HTML files and a Devhelp project
\techo. epub to make an epub
\techo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+\techo. text to make text files
+\techo. man to make manual pages
\techo. changes to make an overview over all changed/added/deprecated items
\techo. linkcheck to check all external links for integrity
\techo. doctest to run all doctests embedded in the documentation if enabled
@@ -531,6 +557,20 @@ if "%%1" == "latex" (
\tgoto end
)
+if "%%1" == "text" (
+\t%%SPHINXBUILD%% -b text %%ALLSPHINXOPTS%% %%BUILDDIR%%/text
+\techo.
+\techo.Build finished. The text files are in %%BUILDDIR%%/text.
+\tgoto end
+)
+
+if "%%1" == "man" (
+\t%%SPHINXBUILD%% -b man %%ALLSPHINXOPTS%% %%BUILDDIR%%/man
+\techo.
+\techo.Build finished. The manual pages are in %%BUILDDIR%%/man.
+\tgoto end
+)
+
if "%%1" == "changes" (
\t%%SPHINXBUILD%% -b changes %%ALLSPHINXOPTS%% %%BUILDDIR%%/changes
\techo.
@@ -704,6 +744,11 @@ document is a custom template, you can also set this to another filename.'''
'existing file and press Enter', d['master'])
print '''
+Sphinx can also add configuration for epub output:'''
+ do_prompt(d, 'epub', 'Do you want to use the epub builder (y/N)',
+ 'n', boolean)
+
+ print '''
Please indicate if you want to use one of the following Sphinx extensions:'''
do_prompt(d, 'ext_autodoc', 'autodoc: automatically insert docstrings '
'from modules (y/N)', 'n', boolean)
@@ -735,6 +780,7 @@ directly.'''
'y', boolean)
d['project_fn'] = make_filename(d['project'])
+ d['project_manpage'] = d['project_fn'].lower()
d['now'] = time.asctime()
d['underline'] = len(d['project']) * '='
d['extensions'] = ', '.join(
@@ -751,7 +797,7 @@ directly.'''
# escape backslashes and single quotes in strings that are put into
# a Python string literal
- for key in ('project', 'copyright', 'author_texescaped',
+ for key in ('project', 'copyright', 'author', 'author_texescaped',
'project_doc_texescaped', 'version', 'release', 'master'):
d[key + '_str'] = d[key].replace('\\', '\\\\').replace("'", "\\'")
@@ -772,6 +818,8 @@ directly.'''
mkdir_p(path.join(srcdir, d['dot'] + 'static'))
conf_text = QUICKSTART_CONF % d
+ if d['epub']:
+ conf_text += EPUB_CONFIG % d
if d['ext_intersphinx']:
conf_text += INTERSPHINX_CONFIG
diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py
new file mode 100644
index 00000000..6ba61a40
--- /dev/null
+++ b/sphinx/writers/manpage.py
@@ -0,0 +1,308 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.writers.manpage
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Manual page writer, extended for Sphinx custom nodes.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from docutils import nodes
+from docutils.writers.manpage import MACRO_DEF, Writer, \
+ Translator as BaseTranslator
+
+from sphinx import addnodes
+from sphinx.locale import admonitionlabels, versionlabels, _
+from sphinx.util.osutil import ustrftime
+
+
+class ManualPageWriter(Writer):
+ def __init__(self, builder):
+ Writer.__init__(self)
+ self.builder = builder
+
+ def translate(self):
+ visitor = ManualPageTranslator(self.builder, self.document)
+ self.visitor = visitor
+ self.document.walkabout(visitor)
+ self.output = visitor.astext()
+
+
+class ManualPageTranslator(BaseTranslator):
+ """
+ Custom translator.
+ """
+
+ def __init__(self, builder, *args, **kwds):
+ BaseTranslator.__init__(self, *args, **kwds)
+ self.builder = builder
+
+ self.in_productionlist = 0
+
+ # first title is the manpage title
+ self.section_level = -1
+
+ # docinfo set by man_pages config value
+ self._docinfo['title'] = self.document.settings.title
+ self._docinfo['subtitle'] = self.document.settings.subtitle
+ self._docinfo['author'] = self.document.settings.authors
+ self._docinfo['manual_section'] = self.document.settings.section
+
+ # docinfo set by other config values
+ self._docinfo['title_upper'] = self._docinfo['title'].upper()
+ if builder.config.today:
+ self._docinfo['date'] = builder.config.today
+ else:
+ self._docinfo['date'] = ustrftime(builder.config.today_fmt
+ or _('%B %d, %Y'))
+ self._docinfo['copyright'] = builder.config.copyright
+ self._docinfo['version'] = builder.config.version
+ self._docinfo['manual_group'] = builder.config.project
+
+ # since self.append_header() is never called, need to do this here
+ self.body.append(MACRO_DEF)
+
+ # overwritten -- added quotes around all .TH arguments
+ def header(self):
+ tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\""
+ " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
+ ".SH NAME\n"
+ "%(title)s \- %(subtitle)s\n")
+ return tmpl % self._docinfo
+
+ def visit_start_of_file(self, node):
+ pass
+ def depart_start_of_file(self, node):
+ pass
+
+ def visit_desc(self, node):
+ self.visit_definition_list(node)
+ def depart_desc(self, node):
+ self.depart_definition_list(node)
+
+ def visit_desc_signature(self, node):
+ self.visit_definition_list_item(node)
+ self.visit_term(node)
+ def depart_desc_signature(self, node):
+ self.depart_term(node)
+
+ def visit_desc_addname(self, node):
+ pass
+ def depart_desc_addname(self, node):
+ pass
+
+ def visit_desc_type(self, node):
+ pass
+ def depart_desc_type(self, node):
+ pass
+
+ def visit_desc_returns(self, node):
+ self.body.append(' -> ')
+ def depart_desc_returns(self, node):
+ pass
+
+ def visit_desc_name(self, node):
+ pass
+ def depart_desc_name(self, node):
+ pass
+
+ def visit_desc_parameterlist(self, node):
+ self.body.append('(')
+ self.first_param = 1
+ def depart_desc_parameterlist(self, node):
+ self.body.append(')')
+
+ def visit_desc_parameter(self, node):
+ if not self.first_param:
+ self.body.append(', ')
+ else:
+ self.first_param = 0
+ def depart_desc_parameter(self, node):
+ pass
+
+ def visit_desc_optional(self, node):
+ self.body.append('[')
+ def depart_desc_optional(self, node):
+ self.body.append(']')
+
+ def visit_desc_annotation(self, node):
+ pass
+ def depart_desc_annotation(self, node):
+ pass
+
+ def visit_desc_content(self, node):
+ self.visit_definition(node)
+ def depart_desc_content(self, node):
+ self.depart_definition(node)
+
+ def visit_refcount(self, node):
+ self.body.append(self.defs['emphasis'][0])
+ def depart_refcount(self, node):
+ self.body.append(self.defs['emphasis'][1])
+
+ def visit_versionmodified(self, node):
+ self.visit_paragraph(node)
+ text = versionlabels[node['type']] % node['version']
+ if len(node):
+ text += ': '
+ else:
+ text += '.'
+ self.body.append(text)
+ def depart_versionmodified(self, node):
+ self.depart_paragraph(node)
+
+ # overwritten -- we don't want source comments to show up
+ def visit_comment(self, node):
+ raise nodes.SkipNode
+
+ # overwritten -- added ensure_eol()
+ def visit_footnote(self, node):
+ self.ensure_eol()
+ BaseTranslator.visit_footnote(self, node)
+
+ # overwritten -- handle footnotes rubric
+ def visit_rubric(self, node):
+ self.ensure_eol()
+ if len(node.children) == 1:
+ rubtitle = node.children[0].astext()
+ if rubtitle in ('Footnotes', _('Footnotes')):
+ self.body.append('.SH ' + self.deunicode(rubtitle).upper() +
+ '\n')
+ raise nodes.SkipNode
+ else:
+ self.body.append('.sp\n')
+ def depart_rubric(self, node):
+ pass
+
+ def visit_seealso(self, node):
+ self.visit_admonition(node)
+ def depart_seealso(self, node):
+ self.depart_admonition(node)
+
+ # overwritten -- use our own label translations
+ def visit_admonition(self, node, name=None):
+ if name:
+ self.body.append('.IP %s\n' %
+ admonitionlabels.get(name, name))
+
+ def visit_productionlist(self, node):
+ self.ensure_eol()
+ names = []
+ self.in_productionlist += 1
+ self.body.append('.sp\n.nf\n')
+ for production in node:
+ names.append(production['tokenname'])
+ maxlen = max(len(name) for name in names)
+ for production in node:
+ if production['tokenname']:
+ lastname = production['tokenname'].ljust(maxlen)
+ self.body.append(self.defs['strong'][0])
+ self.body.append(self.deunicode(lastname))
+ self.body.append(self.defs['strong'][1])
+ self.body.append(' ::= ')
+ else:
+ self.body.append('%s ' % (' '*len(lastname)))
+ production.walkabout(self)
+ self.body.append('\n')
+ self.body.append('\n.fi\n')
+ self.in_productionlist -= 1
+ raise nodes.SkipNode
+
+ def visit_production(self, node):
+ pass
+ def depart_production(self, node):
+ pass
+
+ # overwritten -- don't visit inner marked up nodes
+ def visit_reference(self, node):
+ self.body.append(self.defs['reference'][0])
+ self.body.append(node.astext())
+ self.body.append(self.defs['reference'][1])
+ raise nodes.SkipNode
+
+ def visit_centered(self, node):
+ self.ensure_eol()
+ self.body.append('.sp\n.ce\n')
+ def depart_centered(self, node):
+ self.body.append('\n.ce 0\n')
+
+ def visit_compact_paragraph(self, node):
+ pass
+ def depart_compact_paragraph(self, node):
+ pass
+
+ def visit_highlightlang(self, node):
+ pass
+ def depart_highlightlang(self, node):
+ pass
+
+ def visit_download_reference(self, node):
+ pass
+ def depart_download_reference(self, node):
+ pass
+
+ def visit_toctree(self, node):
+ raise nodes.SkipNode
+
+ def visit_index(self, node):
+ raise nodes.SkipNode
+
+ def visit_tabular_col_spec(self, node):
+ raise nodes.SkipNode
+
+ def visit_glossary(self, node):
+ pass
+ def depart_glossary(self, node):
+ pass
+
+ def visit_acks(self, node):
+ self.ensure_eol()
+ self.body.append(', '.join(n.astext()
+ for n in node.children[0].children) + '.')
+ self.body.append('\n')
+ raise nodes.SkipNode
+
+ def visit_hlist(self, node):
+ self.visit_bullet_list(node)
+ def depart_hlist(self, node):
+ self.depart_bullet_list(node)
+
+ def visit_hlistcol(self, node):
+ pass
+ def depart_hlistcol(self, node):
+ pass
+
+ def visit_literal_emphasis(self, node):
+ return self.visit_emphasis(node)
+ def depart_literal_emphasis(self, node):
+ return self.depart_emphasis(node)
+
+ def visit_abbreviation(self, node):
+ pass
+ def depart_abbreviation(self, node):
+ pass
+
+ # overwritten: handle section titles better than in 0.6 release
+ def visit_title(self, node):
+ if isinstance(node.parent, addnodes.seealso):
+ self.body.append('.IP "')
+ return
+ elif isinstance(node.parent, nodes.section):
+ if self.section_level == 0:
+ # skip the document title
+ raise nodes.SkipNode
+ elif self.section_level == 1:
+ self.body.append('.SH %s\n' %
+ self.deunicode(node.astext().upper()))
+ raise nodes.SkipNode
+ return BaseTranslator.visit_title(self, node)
+ def depart_title(self, node):
+ if isinstance(node.parent, addnodes.seealso):
+ self.body.append('"\n')
+ return
+ return BaseTranslator.depart_title(self, node)
+
+ def unknown_visit(self, node):
+ raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
diff --git a/tests/test_build.py b/tests/test_build.py
index 82657fc0..f18ff175 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -45,6 +45,15 @@ def test_epub(app):
def test_changes(app):
app.builder.build_all()
+try:
+ from docutils.writers.manpage import Writer
+except ImportError:
+ pass
+else:
+ @with_app(buildername='man')
+ def test_man(app):
+ app.builder.build_all()
+
@with_app(buildername='singlehtml', cleanenv=True)
def test_singlehtml(app):
app.builder.build_all()
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index 5138e2c6..cb40d27c 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -129,6 +129,7 @@ def test_quickstart_all_answers(tempdir):
'viewcode': 'no',
'Create Makefile': 'no',
'Create Windows command file': 'no',
+ 'Do you want to use the epub builder': 'yes',
}
qs.raw_input = mock_raw_input(answers, needanswer=True)
qs.TERM_ENCODING = 'utf-8'
@@ -151,6 +152,10 @@ def test_quickstart_all_answers(tempdir):
assert ns['latex_documents'] == [
('contents', 'STASI.tex', u'STASI™ Documentation',
u'Wolfgang Schäuble \\& G\'Beckstein', 'manual')]
+ assert ns['epub_author'] == u'Wolfgang Schäuble & G\'Beckstein'
+ assert ns['man_pages'] == [
+ ('contents', 'stasi', u'STASI™ Documentation',
+ [u'Wolfgang Schäuble & G\'Beckstein'], 1)]
assert (tempdir / 'build').isdir()
assert (tempdir / 'source' / '.static').isdir()