mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add manual page writer.
This commit is contained in:
2
CHANGES
2
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``.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 -------------------------------------------------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -326,6 +326,7 @@ BUILTIN_BUILDERS = {
|
||||
'epub': ('epub', 'EpubBuilder'),
|
||||
'latex': ('latex', 'LaTeXBuilder'),
|
||||
'text': ('text', 'TextBuilder'),
|
||||
'man': ('manpage', 'ManualPageBuilder'),
|
||||
'changes': ('changes', 'ChangesBuilder'),
|
||||
'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
|
||||
}
|
||||
|
||||
93
sphinx/builders/manpage.py
Normal file
93
sphinx/builders/manpage.py
Normal file
@@ -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
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
@@ -703,6 +743,11 @@ document is a custom template, you can also set this to another filename.'''
|
||||
do_prompt(d, 'master', 'Please enter a new file name, or rename the '
|
||||
'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 '
|
||||
@@ -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
|
||||
|
||||
|
||||
308
sphinx/writers/manpage.py
Normal file
308
sphinx/writers/manpage.py
Normal file
@@ -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__)
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user