def build_help(self):
# type: () -> None
if not color_terminal():
nocolor()
print(bold("Sphinx v%s" % sphinx.__display_version__))
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print(' %s %s' % (blue(bname.ljust(10)), description))
def setup_logger(verbose=1, color=True):
"""
Sets up and returns a Python Logger instance for the Sage
documentation builder. The optional argument sets logger's level
and message format.
"""
# Set up colors. Adapted from sphinx.cmdline.
import sphinx.util.console as c
if not color or not sys.stdout.isatty() or not c.color_terminal():
c.nocolor()
# Available colors: black, darkgray, (dark)red, dark(green),
# brown, yellow, (dark)blue, purple, fuchsia, turquoise, teal,
# lightgray, white. Available styles: reset, bold, faint,
# standout, underline, blink.
# Set up log record formats.
format_std = "%(message)s"
formatter = logging.Formatter(format_std)
# format_debug = "%(module)s #%(lineno)s %(funcName)s() %(message)s"
fields = ["%(module)s", "#%(lineno)s", "%(funcName)s()", "%(message)s"]
colors = ["darkblue", "darkred", "brown", "reset"]
styles = ["reset", "reset", "reset", "reset"]
format_debug = ""
for i in xrange(len(fields)):
format_debug += c.colorize(styles[i], c.colorize(colors[i], fields[i]))
if i != len(fields):
format_debug += " "
# Documentation: http://docs.python.org/library/logging.html
logger = logging.getLogger("doc.common.builder")
# Note: There's also Handler.setLevel(). The argument is the
# lowest severity message that the respective logger or handler
# will pass on. The default levels are DEBUG, INFO, WARNING,
# ERROR, and CRITICAL. We use "WARNING" for normal verbosity and
# "ERROR" for quiet operation. It's possible to define custom
# levels. See the documentation for details.
if verbose == 0:
logger.setLevel(logging.ERROR)
if verbose == 1:
logger.setLevel(logging.WARNING)
if verbose == 2:
logger.setLevel(logging.INFO)
if verbose == 3:
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(format_debug)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def run(self):
if is_sphinx_installed():
from sphinx.application import Sphinx
from sphinx.util.console import nocolor
# Windows' poor cmd box doesn't understand ANSI sequences
if not sys.stdout.isatty() or sys.platform == 'win32':
nocolor()
# Check to see if version information is provided in setup.py
# If it is, it will override version information in conf.py.
conf_overrides = {}
version = self.distribution.get_version()
if version != "0.0.0":
conf_overrides['version'] = version
conf_overrides['release'] = version
for i in range(len(self.source_dirs)):
for format in self.formats:
try:
builder_target = os.path.join(self.target_dir, format,
self.projects[i])
doctree_dir = os.path.join(builder_target, '.doctrees')
self.mkpath(doctree_dir)
# The sphinx interface requires 7 arguments: sourcedir,
# confdir, outdir, doctreedir, buildername,
# confoverrides, and status
app = Sphinx(self.source_dirs[i], self.source_dirs[i],
builder_target, doctree_dir, format, conf_overrides,
self.status_stream
)
app.builder.build_update()
if self.pdf_build and format == 'latex':
try:
os.chdir(builder_target)
subprocess.call(["make", "all-pdf"])
log.info("PDF doc created in %s."
% builder_target)
except Exception, e:
log.error(e)
except IOError, e:
log.warn(e)
except Exception, e:
log.error('Unable to generate %s docs.' % format)
if format == 'html' and len(self.formats) == 1:
log.info("Installing %s html documentation from zip"
" file.\n" % self.distribution.get_name())
unzip_html_docs(HTML_ZIP, TARGET_DIR)
def main(argv):
if not color_terminal():
nocolor()
parser = optparse.OptionParser(USAGE, epilog=EPILOG, formatter=MyFormatter())
parser.add_option('--version', action='store_true', dest='version',
help='show version information and exit')
group = parser.add_option_group('General options')
group.add_option('-b', metavar='BUILDER', dest='builder', default='html',
help='builder to use; default is html')
group.add_option('-a', action='store_true', dest='force_all',
help='write all files; default is to only write new and '
'changed files')
group.add_option('-E', action='store_true', dest='freshenv',
help='don\'t use a saved environment, always read '
'all files')
group.add_option('-d', metavar='PATH', default=None, dest='doctreedir',
help='path for the cached environment and doctree files '
'(default: outdir/.doctrees)')
group.add_option('-j', metavar='N', default=1, type='int', dest='jobs',
help='build in parallel with N processes where possible')
# this option never gets through to this point (it is intercepted earlier)
# group.add_option('-M', metavar='BUILDER', dest='make_mode',
# help='"make" mode -- as used by Makefile, like '
# '"sphinx-build -M html"')
group = parser.add_option_group('Build configuration options')
group.add_option('-c', metavar='PATH', dest='confdir',
help='path where configuration file (conf.py) is located '
'(default: same as sourcedir)')
group.add_option('-C', action='store_true', dest='noconfig',
help='use no config file at all, only -D options')
group.add_option('-D', metavar='setting=value', action='append',
dest='define', default=[],
help='override a setting in configuration file')
group.add_option('-A', metavar='name=value', action='append',
dest='htmldefine', default=[],
help='pass a value into HTML templates')
group.add_option('-t', metavar='TAG', action='append',
dest='tags', default=[],
help='define tag: include "only" blocks with TAG')
group.add_option('-n', action='store_true', dest='nitpicky',
help='nit-picky mode, warn about all missing references')
group = parser.add_option_group('Console output options')
group.add_option('-v', action='count', dest='verbosity', default=0,
help='increase verbosity (can be repeated)')
group.add_option('-q', action='store_true', dest='quiet',
help='no output on stdout, just warnings on stderr')
group.add_option('-Q', action='store_true', dest='really_quiet',
help='no output at all, not even warnings')
group.add_option('-N', action='store_true', dest='nocolor',
help='do not emit colored output')
group.add_option('-w', metavar='FILE', dest='warnfile',
help='write warnings (and errors) to given file')
group.add_option('-W', action='store_true', dest='warningiserror',
help='turn warnings into errors')
group.add_option('-T', action='store_true', dest='traceback',
help='show full traceback on exception')
group.add_option('-P', action='store_true', dest='pdb',
help='run Pdb on exception')
# parse options
try:
opts, args = parser.parse_args(argv[1:])
except SystemExit as err:
return err.code
# handle basic options
if opts.version:
print('Sphinx (sphinx-build) %s' % __version__)
return 0
# get paths (first and second positional argument)
try:
srcdir = abspath(args[0])
confdir = abspath(opts.confdir or srcdir)
if opts.noconfig:
confdir = None
if not path.isdir(srcdir):
print('Error: Cannot find source directory `%s\'.' % srcdir,
file=sys.stderr)
return 1
if not opts.noconfig and not path.isfile(path.join(confdir, 'conf.py')):
print('Error: Config directory doesn\'t contain a conf.py file.',
file=sys.stderr)
return 1
outdir = abspath(args[1])
except IndexError:
usage(argv, 'Error: Insufficient arguments.')
return 1
except UnicodeError:
print(
'Error: Multibyte filename not supported on this filesystem '
'encoding (%r).' % fs_encoding, file=sys.stderr)
return 1
# handle remaining filename arguments
filenames = args[2:]
#.........这里部分代码省略.........
def inner_main(args):
d = {}
if os.name == 'nt' or not sys.stdout.isatty():
nocolor()
print bold('Welcome to the Sphinx quickstart utility.')
print '''
Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).'''
print '''
Enter the root path for documentation.'''
do_prompt(d, 'path', 'Root path for the documentation', '.', is_path)
print '''
You have two options for placing the build directory for Sphinx output.
Either, you use a directory ".build" within the root path, or you separate
"source" and "build" directories within the root path.'''
do_prompt(d, 'sep', 'Separate source and build directories (y/n)', 'n',
boolean)
print '''
Inside the root directory, two more directories will be created; ".templates"
for custom HTML templates and ".static" for custom stylesheets and other
static files. Since the leading dot may be inconvenient for Windows users,
you can enter another prefix (such as "_") to replace the dot.'''
do_prompt(d, 'dot', 'Name prefix for templates and static dir', '.', ok)
print '''
The project name will occur in several places in the built documentation.'''
do_prompt(d, 'project', 'Project name')
do_prompt(d, 'author', 'Author name(s)')
print '''
Sphinx has the notion of a "version" and a "release" for the
software. Each version can have multiple releases. For example, for
Python the version is something like 2.5 or 3.0, while the release is
something like 2.5.1 or 3.0a1. If you don't need this dual structure,
just set both to the same value.'''
do_prompt(d, 'version', 'Project version')
do_prompt(d, 'release', 'Project release', d['version'])
print '''
The file name suffix for source files. Commonly, this is either ".txt"
or ".rst". Only files with this suffix are considered documents.'''
do_prompt(d, 'suffix', 'Source file suffix', '.rst', suffix)
print '''
One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.'''
do_prompt(d, 'master', 'Name of your master document (without suffix)',
'index')
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)
do_prompt(d, 'ext_doctest', 'doctest: automatically test code snippets '
'in doctest blocks (y/n)', 'n', boolean)
print '''
If you are under Unix, a Makefile can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.'''
do_prompt(d, 'makefile', 'Create Makefile? (y/n)',
os.name == 'posix' and 'y' or 'n', boolean)
d['project_fn'] = make_filename(d['project'])
d['year'] = time.strftime('%Y')
d['now'] = time.asctime()
d['underline'] = len(d['project']) * '='
d['extensions'] = ', '.join(
repr('sphinx.ext.' + name) for name in ('autodoc', 'doctest')
if d['ext_' + name].upper() in ('Y', 'YES'))
if not path.isdir(d['path']):
mkdir_p(d['path'])
separate = d['sep'].upper() in ('Y', 'YES')
srcdir = separate and path.join(d['path'], 'source') or d['path']
mkdir_p(srcdir)
if separate:
builddir = path.join(d['path'], 'build')
else:
builddir = path.join(srcdir, d['dot'] + 'build')
mkdir_p(builddir)
mkdir_p(path.join(srcdir, d['dot'] + 'templates'))
mkdir_p(path.join(srcdir, d['dot'] + 'static'))
f = open(path.join(srcdir, 'conf.py'), 'w')
f.write(QUICKSTART_CONF % d)
f.close()
masterfile = path.join(srcdir, d['master'] + d['suffix'])
f = open(masterfile, 'w')
f.write(MASTER_FILE % d)
f.close()
create_makefile = d['makefile'].upper() in ('Y', 'YES')
if create_makefile:
d['rsrcdir'] = separate and 'source' or '.'
d['rbuilddir'] = separate and 'build' or d['dot'] + 'build'
f = open(path.join(d['path'], 'Makefile'), 'w')
#.........这里部分代码省略.........
def build_main(argv=sys.argv[1:]):
# type: (List[str]) -> int
"""Sphinx build "main" command-line entry."""
parser = get_parser()
args = parser.parse_args(argv)
if args.noconfig:
args.confdir = None
elif not args.confdir:
args.confdir = args.sourcedir
if not args.doctreedir:
args.doctreedir = os.path.join(args.outputdir, '.doctrees')
# handle remaining filename arguments
filenames = args.filenames
missing_files = []
for filename in filenames:
if not os.path.isfile(filename):
missing_files.append(filename)
if missing_files:
parser.error(__('cannot find files %r') % missing_files)
if args.force_all and filenames:
parser.error(__('cannot combine -a option and filenames'))
if args.color == 'no' or (args.color == 'auto' and not color_terminal()):
nocolor()
status = sys.stdout
warning = sys.stderr
error = sys.stderr
if args.quiet:
status = None
if args.really_quiet:
status = warning = None
if warning and args.warnfile:
try:
warnfp = open(args.warnfile, 'w')
except Exception as exc:
parser.error(__('cannot open warning file %r: %s') % (
args.warnfile, exc))
warning = Tee(warning, warnfp) # type: ignore
error = warning
confoverrides = {}
for val in args.define:
try:
key, val = val.split('=', 1)
except ValueError:
parser.error(__('-D option argument must be in the form name=value'))
confoverrides[key] = val
for val in args.htmldefine:
try:
key, val = val.split('=')
except ValueError:
parser.error(__('-A option argument must be in the form name=value'))
try:
val = int(val)
except ValueError:
pass
confoverrides['html_context.%s' % key] = val
if args.nitpicky:
confoverrides['nitpicky'] = True
app = None
try:
confdir = args.confdir or args.sourcedir
with patch_docutils(confdir), docutils_namespace():
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
args.doctreedir, args.builder, confoverrides, status,
warning, args.freshenv, args.warningiserror,
args.tags, args.verbosity, args.jobs, args.keep_going)
app.build(args.force_all, filenames)
return app.statuscode
except (Exception, KeyboardInterrupt) as exc:
handle_exception(app, args, exc, error)
return 2
请发表评论