Merge branch '2.0'

This commit is contained in:
Takeshi KOMIYA 2020-02-01 11:17:03 +09:00
commit 41032572a5
10 changed files with 357 additions and 213 deletions

14
CHANGES
View File

@ -84,6 +84,17 @@ Deprecated
* ``sphinx.util.get_module_source()`` * ``sphinx.util.get_module_source()``
* ``sphinx.util.inspect.Signature`` * ``sphinx.util.inspect.Signature``
* ``sphinx.util.inspect.safe_getmembers()`` * ``sphinx.util.inspect.safe_getmembers()``
* ``sphinx.writers.latex.LaTeXTranslator.settings.author``
* ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
* ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
* ``sphinx.writers.latex.LaTeXTranslator.settings.docname``
* ``sphinx.writers.latex.LaTeXTranslator.settings.title``
* ``sphinx.writers.latex.ADDITIONAL_SETTINGS``
* ``sphinx.writers.latex.DEFAULT_SETTINGS``
* ``sphinx.writers.latex.LUALATEX_DEFAULT_FONTPKG``
* ``sphinx.writers.latex.PDFLATEX_DEFAULT_FONTPKG``
* ``sphinx.writers.latex.XELATEX_DEFAULT_FONTPKG``
* ``sphinx.writers.latex.XELATEX_GREEK_DEFAULT_FONTPKG``
Features added Features added
-------------- --------------
@ -118,11 +129,14 @@ Bugs fixed
* #6961: latex: warning for babel shown twice * #6961: latex: warning for babel shown twice
* #6559: Wrong node-ids are generated in glossary directive * #6559: Wrong node-ids are generated in glossary directive
* #6986: apidoc: misdetects module name for .so file inside module * #6986: apidoc: misdetects module name for .so file inside module
* #6899: apidoc: private members are not shown even if ``--private`` given
* #6999: napoleon: fails to parse tilde in :exc: role * #6999: napoleon: fails to parse tilde in :exc: role
* #7019: gettext: Absolute path used in message catalogs * #7019: gettext: Absolute path used in message catalogs
* #7023: autodoc: nested partial functions are not listed * #7023: autodoc: nested partial functions are not listed
* #7023: autodoc: partial functions imported from other modules are listed as * #7023: autodoc: partial functions imported from other modules are listed as
module members without :impoprted-members: option module members without :impoprted-members: option
* #6889: autodoc: Trailing comma in ``:members::`` option causes cryptic warning
* #7055: linkcheck: redirect is treated as an error
Testing Testing
-------- --------

View File

@ -97,6 +97,61 @@ The following is a list of deprecated interfaces.
- 4.0 - 4.0
- ``inspect.getmembers()`` - ``inspect.getmembers()``
* - ``sphinx.writers.latex.LaTeXTranslator.settings.author``
- 2.4
- 4.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
- 2.4
- 4.0
- ``document['contentsname']``
* - ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
- 2.4
- 4.0
- ``document['docclass']``
* - ``sphinx.writers.latex.LaTeXTranslator.settings.docname``
- 2.4
- 4.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.settings.title``
- 2.4
- 4.0
- N/A
* - ``sphinx.writers.latex.ADDITIONAL_SETTINGS``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.ADDITIONAL_SETTINGS``
* - ``sphinx.writers.latex.DEFAULT_SETTINGS``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.DEFAULT_SETTINGS``
* - ``sphinx.writers.latex.LUALATEX_DEFAULT_FONTPKG``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.LUALATEX_DEFAULT_FONTPKG``
* - ``sphinx.writers.latex.PDFLATEX_DEFAULT_FONTPKG``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.PDFLATEX_DEFAULT_FONTPKG``
* - ``sphinx.writers.latex.XELATEX_DEFAULT_FONTPKG``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.XELATEX_DEFAULT_FONTPKG``
* - ``sphinx.writers.latex.XELATEX_GREEK_DEFAULT_FONTPKG``
- 2.4
- 4.0
- ``sphinx.builders.latex.constants.XELATEX_GREEK_DEFAULT_FONTPKG``
* - ``sphinx.builders.gettext.POHEADER`` * - ``sphinx.builders.gettext.POHEADER``
- 2.3 - 2.3
- 4.0 - 4.0

View File

@ -20,6 +20,7 @@ import sphinx.builders.latex.nodes # NOQA # Workaround: import this before wri
from sphinx import package_dir, addnodes, highlighting from sphinx import package_dir, addnodes, highlighting
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.builders import Builder from sphinx.builders import Builder
from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTINGS
from sphinx.builders.latex.util import ExtBabel from sphinx.builders.latex.util import ExtBabel
from sphinx.config import Config, ENUM from sphinx.config import Config, ENUM
from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.deprecation import RemovedInSphinx40Warning
@ -34,9 +35,7 @@ from sphinx.util.i18n import format_date
from sphinx.util.nodes import inline_all_toctrees from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, make_filename_from_project from sphinx.util.osutil import SEP, make_filename_from_project
from sphinx.util.template import LaTeXRenderer from sphinx.util.template import LaTeXRenderer
from sphinx.writers.latex import ( from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
ADDITIONAL_SETTINGS, DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
)
# load docutils.nodes after loading sphinx.builders.latex.nodes # load docutils.nodes after loading sphinx.builders.latex.nodes
from docutils import nodes # NOQA from docutils import nodes # NOQA
@ -222,6 +221,7 @@ class LaTeXBuilder(Builder):
defaults=self.env.settings, defaults=self.env.settings,
components=(docwriter,), components=(docwriter,),
read_config_files=True).get_default_values() # type: Any read_config_files=True).get_default_values() # type: Any
patch_settings(docsettings)
self.init_document_data() self.init_document_data()
self.write_stylesheet() self.write_stylesheet()
@ -244,16 +244,18 @@ class LaTeXBuilder(Builder):
doctree = self.assemble_doctree( doctree = self.assemble_doctree(
docname, toctree_only, docname, toctree_only,
appendices=(self.config.latex_appendices if docclass != 'howto' else [])) appendices=(self.config.latex_appendices if docclass != 'howto' else []))
doctree['docclass'] = docclass
doctree['contentsname'] = self.get_contentsname(docname)
doctree['tocdepth'] = tocdepth doctree['tocdepth'] = tocdepth
self.post_process_images(doctree) self.post_process_images(doctree)
self.update_doc_context(title, author) self.update_doc_context(title, author)
with progress_message(__("writing")): with progress_message(__("writing")):
docsettings.author = author docsettings._author = author
docsettings.title = title docsettings._title = title
docsettings.contentsname = self.get_contentsname(docname) docsettings._contentsname = doctree['contentsname']
docsettings.docname = docname docsettings._docname = docname
docsettings.docclass = docclass docsettings._docclass = docclass
doctree.settings = docsettings doctree.settings = docsettings
docwriter.write(doctree, destination) docwriter.write(doctree, destination)
@ -401,6 +403,44 @@ class LaTeXBuilder(Builder):
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer()) copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
def patch_settings(settings: Any) -> Any:
"""Make settings object to show deprecation messages."""
class Values(type(settings)): # type: ignore
@property
def author(self):
warnings.warn('settings.author is deprecated',
RemovedInSphinx40Warning, stacklevel=2)
return self._author
@property
def title(self):
warnings.warn('settings.title is deprecated',
RemovedInSphinx40Warning, stacklevel=2)
return self._title
@property
def contentsname(self):
warnings.warn('settings.contentsname is deprecated',
RemovedInSphinx40Warning, stacklevel=2)
return self._contentsname
@property
def docname(self):
warnings.warn('settings.docname is deprecated',
RemovedInSphinx40Warning, stacklevel=2)
return self._docname
@property
def docclass(self):
warnings.warn('settings.docclass is deprecated',
RemovedInSphinx40Warning, stacklevel=2)
return self._docclass
# dynamic subclassing
settings.__class__ = Values
def validate_config_values(app: Sphinx, config: Config) -> None: def validate_config_values(app: Sphinx, config: Config) -> None:
for key in list(config.latex_elements): for key in list(config.latex_elements):
if key not in DEFAULT_SETTINGS: if key not in DEFAULT_SETTINGS:

View File

@ -0,0 +1,192 @@
"""
sphinx.builders.latex.constants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
consntants for LaTeX builder.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from typing import Any, Dict
PDFLATEX_DEFAULT_FONTPKG = r'''
\usepackage{times}
\expandafter\ifx\csname T@LGR\endcsname\relax
\else
% LGR was declared as font encoding
\substitutefont{LGR}{\rmdefault}{cmr}
\substitutefont{LGR}{\sfdefault}{cmss}
\substitutefont{LGR}{\ttdefault}{cmtt}
\fi
\expandafter\ifx\csname T@X2\endcsname\relax
\expandafter\ifx\csname T@T2A\endcsname\relax
\else
% T2A was declared as font encoding
\substitutefont{T2A}{\rmdefault}{cmr}
\substitutefont{T2A}{\sfdefault}{cmss}
\substitutefont{T2A}{\ttdefault}{cmtt}
\fi
\else
% X2 was declared as font encoding
\substitutefont{X2}{\rmdefault}{cmr}
\substitutefont{X2}{\sfdefault}{cmss}
\substitutefont{X2}{\ttdefault}{cmtt}
\fi
'''
XELATEX_DEFAULT_FONTPKG = r'''
\setmainfont{FreeSerif}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Italic,
BoldFont = *Bold,
BoldItalicFont = *BoldItalic
]
\setsansfont{FreeSans}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Oblique,
BoldFont = *Bold,
BoldItalicFont = *BoldOblique,
]
\setmonofont{FreeMono}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Oblique,
BoldFont = *Bold,
BoldItalicFont = *BoldOblique,
]
'''
XELATEX_GREEK_DEFAULT_FONTPKG = (XELATEX_DEFAULT_FONTPKG +
'\n\\newfontfamily\\greekfont{FreeSerif}' +
'\n\\newfontfamily\\greekfontsf{FreeSans}' +
'\n\\newfontfamily\\greekfonttt{FreeMono}')
LUALATEX_DEFAULT_FONTPKG = XELATEX_DEFAULT_FONTPKG
DEFAULT_SETTINGS = {
'latex_engine': 'pdflatex',
'papersize': 'letterpaper',
'pointsize': '10pt',
'pxunit': '.75bp',
'classoptions': '',
'extraclassoptions': '',
'maxlistdepth': '',
'sphinxpkgoptions': '',
'sphinxsetup': '',
'fvset': '\\fvset{fontsize=\\small}',
'passoptionstopackages': '',
'geometry': '\\usepackage{geometry}',
'inputenc': '',
'utf8extra': '',
'cmappkg': '\\usepackage{cmap}',
'fontenc': '\\usepackage[T1]{fontenc}',
'amsmath': '\\usepackage{amsmath,amssymb,amstext}',
'multilingual': '',
'babel': '\\usepackage{babel}',
'polyglossia': '',
'fontpkg': PDFLATEX_DEFAULT_FONTPKG,
'substitutefont': '',
'textcyrillic': '',
'textgreek': '\\usepackage{textalpha}',
'fncychap': '\\usepackage[Bjarne]{fncychap}',
'hyperref': ('% Include hyperref last.\n'
'\\usepackage{hyperref}\n'
'% Fix anchor placement for figures with captions.\n'
'\\usepackage{hypcap}% it must be loaded after hyperref.\n'
'% Set up styles of URL: it should be placed after hyperref.\n'
'\\urlstyle{same}'),
'contentsname': '',
'extrapackages': '',
'preamble': '',
'title': '',
'release': '',
'author': '',
'releasename': '',
'makeindex': '\\makeindex',
'shorthandoff': '',
'maketitle': '\\sphinxmaketitle',
'tableofcontents': '\\sphinxtableofcontents',
'atendofbody': '',
'printindex': '\\printindex',
'transition': '\n\n\\bigskip\\hrule\\bigskip\n\n',
'figure_align': 'htbp',
'tocdepth': '',
'secnumdepth': '',
} # type: Dict[str, Any]
ADDITIONAL_SETTINGS = {
'pdflatex': {
'inputenc': '\\usepackage[utf8]{inputenc}',
'utf8extra': ('\\ifdefined\\DeclareUnicodeCharacter\n'
'% support both utf8 and utf8x syntaxes\n'
' \\ifdefined\\DeclareUnicodeCharacterAsOptional\n'
' \\def\\sphinxDUC#1{\\DeclareUnicodeCharacter{"#1}}\n'
' \\else\n'
' \\let\\sphinxDUC\\DeclareUnicodeCharacter\n'
' \\fi\n'
' \\sphinxDUC{00A0}{\\nobreakspace}\n'
' \\sphinxDUC{2500}{\\sphinxunichar{2500}}\n'
' \\sphinxDUC{2502}{\\sphinxunichar{2502}}\n'
' \\sphinxDUC{2514}{\\sphinxunichar{2514}}\n'
' \\sphinxDUC{251C}{\\sphinxunichar{251C}}\n'
' \\sphinxDUC{2572}{\\textbackslash}\n'
'\\fi'),
},
'xelatex': {
'latex_engine': 'xelatex',
'polyglossia': '\\usepackage{polyglossia}',
'babel': '',
'fontenc': ('\\usepackage{fontspec}\n'
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
'fontpkg': XELATEX_DEFAULT_FONTPKG,
'textgreek': '',
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
'{\\leavevmode\\nobreak\\ }'),
},
'lualatex': {
'latex_engine': 'lualatex',
'polyglossia': '\\usepackage{polyglossia}',
'babel': '',
'fontenc': ('\\usepackage{fontspec}\n'
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
'fontpkg': LUALATEX_DEFAULT_FONTPKG,
'textgreek': '',
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
'{\\leavevmode\\nobreak\\ }'),
},
'platex': {
'latex_engine': 'platex',
'babel': '',
'classoptions': ',dvipdfmx',
'fontpkg': '\\usepackage{times}',
'textgreek': '',
'fncychap': '',
'geometry': '\\usepackage[dvipdfm]{geometry}',
},
'uplatex': {
'latex_engine': 'uplatex',
'babel': '',
'classoptions': ',dvipdfmx',
'fontpkg': '\\usepackage{times}',
'textgreek': '',
'fncychap': '',
'geometry': '\\usepackage[dvipdfm]{geometry}',
},
# special settings for latex_engine + language_code
('xelatex', 'fr'): {
# use babel instead of polyglossia by default
'polyglossia': '',
'babel': '\\usepackage{babel}',
},
('xelatex', 'zh'): {
'fontenc': '\\usepackage{xeCJK}',
},
('xelatex', 'el'): {
'fontpkg': XELATEX_GREEK_DEFAULT_FONTPKG,
},
} # type: Dict[Any, Dict[str, Any]]

View File

@ -26,7 +26,7 @@ from sphinx.builders import Builder
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import encode_uri, requests, logging from sphinx.util import encode_uri, requests, logging
from sphinx.util.console import ( # type: ignore from sphinx.util.console import ( # type: ignore
purple, red, darkgreen, darkgray, darkred, turquoise purple, red, darkgreen, darkgray, turquoise
) )
from sphinx.util.nodes import get_node_line from sphinx.util.nodes import get_node_line
from sphinx.util.requests import is_ssl_error from sphinx.util.requests import is_ssl_error
@ -251,11 +251,11 @@ class CheckExternalLinksBuilder(Builder):
elif status == 'redirected': elif status == 'redirected':
try: try:
text, color = { text, color = {
301: ('permanently', darkred), 301: ('permanently', purple),
302: ('with Found', purple), 302: ('with Found', purple),
303: ('with See Other', purple), 303: ('with See Other', purple),
307: ('temporarily', turquoise), 307: ('temporarily', turquoise),
308: ('permanently', darkred), 308: ('permanently', purple),
}[code] }[code]
except KeyError: except KeyError:
text, color = ('with unknown code', purple) text, color = ('with unknown code', purple)

View File

@ -20,6 +20,7 @@ import locale
import os import os
import sys import sys
import warnings import warnings
from copy import copy
from fnmatch import fnmatch from fnmatch import fnmatch
from importlib.machinery import EXTENSION_SUFFIXES from importlib.machinery import EXTENSION_SUFFIXES
from os import path from os import path
@ -107,12 +108,16 @@ def format_directive(module: str, package: str = None) -> str:
def create_module_file(package: str, basename: str, opts: Any, def create_module_file(package: str, basename: str, opts: Any,
user_template_dir: str = None) -> None: user_template_dir: str = None) -> None:
"""Build the text of the file and write the file.""" """Build the text of the file and write the file."""
options = copy(OPTIONS)
if opts.includeprivate and 'private-members' not in options:
options.append('private-members')
qualname = module_join(package, basename) qualname = module_join(package, basename)
context = { context = {
'show_headings': not opts.noheadings, 'show_headings': not opts.noheadings,
'basename': basename, 'basename': basename,
'qualname': qualname, 'qualname': qualname,
'automodule_options': OPTIONS, 'automodule_options': options,
} }
text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst_t', context) text = ReSTRenderer([user_template_dir, template_dir]).render('module.rst_t', context)
write_file(qualname, text, opts) write_file(qualname, text, opts)
@ -133,6 +138,9 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
sub != INITPY] sub != INITPY]
submodules = [module_join(master_package, subroot, modname) submodules = [module_join(master_package, subroot, modname)
for modname in submodules] for modname in submodules]
options = copy(OPTIONS)
if opts.includeprivate and 'private-members' not in options:
options.append('private-members')
pkgname = module_join(master_package, subroot) pkgname = module_join(master_package, subroot)
context = { context = {
@ -142,7 +150,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
'is_namespace': is_namespace, 'is_namespace': is_namespace,
'modulefirst': opts.modulefirst, 'modulefirst': opts.modulefirst,
'separatemodules': opts.separatemodules, 'separatemodules': opts.separatemodules,
'automodule_options': OPTIONS, 'automodule_options': options,
'show_headings': not opts.noheadings, 'show_headings': not opts.noheadings,
} }
text = ReSTRenderer([user_template_dir, template_dir]).render('package.rst_t', context) text = ReSTRenderer([user_template_dir, template_dir]).render('package.rst_t', context)

View File

@ -70,14 +70,14 @@ def members_option(arg: Any) -> Union[object, List[str]]:
"""Used to convert the :members: option to auto directives.""" """Used to convert the :members: option to auto directives."""
if arg is None or arg is True: if arg is None or arg is True:
return ALL return ALL
return [x.strip() for x in arg.split(',')] return [x.strip() for x in arg.split(',') if x.strip()]
def members_set_option(arg: Any) -> Union[object, Set[str]]: def members_set_option(arg: Any) -> Union[object, Set[str]]:
"""Used to convert the :members: option to auto directives.""" """Used to convert the :members: option to auto directives."""
if arg is None: if arg is None:
return ALL return ALL
return {x.strip() for x in arg.split(',')} return {x.strip() for x in arg.split(',') if x.strip()}
def inherited_members_option(arg: Any) -> Union[object, Set[str]]: def inherited_members_option(arg: Any) -> Union[object, Set[str]]:

View File

@ -9,6 +9,7 @@
""" """
import re import re
from collections import OrderedDict
from typing import Any, Dict, Iterable from typing import Any, Dict, Iterable
from typing import cast from typing import cast
@ -37,13 +38,14 @@ def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
"""Record type hints to env object.""" """Record type hints to env object."""
try: try:
if callable(obj): if callable(obj):
annotations = app.env.temp_data.setdefault('annotations', {}).setdefault(name, {}) annotations = app.env.temp_data.setdefault('annotations', {})
annotation = annotations.setdefault(name, OrderedDict())
sig = inspect.signature(obj) sig = inspect.signature(obj)
for param in sig.parameters.values(): for param in sig.parameters.values():
if param.annotation is not param.empty: if param.annotation is not param.empty:
annotations[param.name] = typing.stringify(param.annotation) annotation[param.name] = typing.stringify(param.annotation)
if sig.return_annotation is not sig.empty: if sig.return_annotation is not sig.empty:
annotations['return'] = typing.stringify(sig.return_annotation) annotation['return'] = typing.stringify(sig.return_annotation)
except TypeError: except TypeError:
pass pass
@ -55,7 +57,10 @@ def merge_typehints(app: Sphinx, domain: str, objtype: str, contentnode: Element
return return
signature = cast(addnodes.desc_signature, contentnode.parent[0]) signature = cast(addnodes.desc_signature, contentnode.parent[0])
fullname = '.'.join([signature['module'], signature['fullname']]) if signature['module']:
fullname = '.'.join([signature['module'], signature['fullname']])
else:
fullname = signature['fullname']
annotations = app.env.temp_data.get('annotations', {}) annotations = app.env.temp_data.get('annotations', {})
if annotations.get(fullname, {}): if annotations.get(fullname, {}):
field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)] field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)]

View File

@ -65,182 +65,6 @@ ENUMERATE_LIST_STYLE = defaultdict(lambda: r'\arabic',
'lowerroman': r'\roman', 'lowerroman': r'\roman',
'upperroman': r'\Roman', 'upperroman': r'\Roman',
}) })
PDFLATEX_DEFAULT_FONTPKG = r'''
\usepackage{times}
\expandafter\ifx\csname T@LGR\endcsname\relax
\else
% LGR was declared as font encoding
\substitutefont{LGR}{\rmdefault}{cmr}
\substitutefont{LGR}{\sfdefault}{cmss}
\substitutefont{LGR}{\ttdefault}{cmtt}
\fi
\expandafter\ifx\csname T@X2\endcsname\relax
\expandafter\ifx\csname T@T2A\endcsname\relax
\else
% T2A was declared as font encoding
\substitutefont{T2A}{\rmdefault}{cmr}
\substitutefont{T2A}{\sfdefault}{cmss}
\substitutefont{T2A}{\ttdefault}{cmtt}
\fi
\else
% X2 was declared as font encoding
\substitutefont{X2}{\rmdefault}{cmr}
\substitutefont{X2}{\sfdefault}{cmss}
\substitutefont{X2}{\ttdefault}{cmtt}
\fi
'''
XELATEX_DEFAULT_FONTPKG = r'''
\setmainfont{FreeSerif}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Italic,
BoldFont = *Bold,
BoldItalicFont = *BoldItalic
]
\setsansfont{FreeSans}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Oblique,
BoldFont = *Bold,
BoldItalicFont = *BoldOblique,
]
\setmonofont{FreeMono}[
Extension = .otf,
UprightFont = *,
ItalicFont = *Oblique,
BoldFont = *Bold,
BoldItalicFont = *BoldOblique,
]
'''
XELATEX_GREEK_DEFAULT_FONTPKG = (XELATEX_DEFAULT_FONTPKG +
'\n\\newfontfamily\\greekfont{FreeSerif}' +
'\n\\newfontfamily\\greekfontsf{FreeSans}' +
'\n\\newfontfamily\\greekfonttt{FreeMono}')
LUALATEX_DEFAULT_FONTPKG = XELATEX_DEFAULT_FONTPKG
DEFAULT_SETTINGS = {
'latex_engine': 'pdflatex',
'papersize': 'letterpaper',
'pointsize': '10pt',
'pxunit': '.75bp',
'classoptions': '',
'extraclassoptions': '',
'maxlistdepth': '',
'sphinxpkgoptions': '',
'sphinxsetup': '',
'fvset': '\\fvset{fontsize=\\small}',
'passoptionstopackages': '',
'geometry': '\\usepackage{geometry}',
'inputenc': '',
'utf8extra': '',
'cmappkg': '\\usepackage{cmap}',
'fontenc': '\\usepackage[T1]{fontenc}',
'amsmath': '\\usepackage{amsmath,amssymb,amstext}',
'multilingual': '',
'babel': '\\usepackage{babel}',
'polyglossia': '',
'fontpkg': PDFLATEX_DEFAULT_FONTPKG,
'substitutefont': '',
'textcyrillic': '',
'textgreek': '\\usepackage{textalpha}',
'fncychap': '\\usepackage[Bjarne]{fncychap}',
'hyperref': ('% Include hyperref last.\n'
'\\usepackage{hyperref}\n'
'% Fix anchor placement for figures with captions.\n'
'\\usepackage{hypcap}% it must be loaded after hyperref.\n'
'% Set up styles of URL: it should be placed after hyperref.\n'
'\\urlstyle{same}'),
'contentsname': '',
'extrapackages': '',
'preamble': '',
'title': '',
'release': '',
'author': '',
'releasename': '',
'makeindex': '\\makeindex',
'shorthandoff': '',
'maketitle': '\\sphinxmaketitle',
'tableofcontents': '\\sphinxtableofcontents',
'atendofbody': '',
'printindex': '\\printindex',
'transition': '\n\n\\bigskip\\hrule\\bigskip\n\n',
'figure_align': 'htbp',
'tocdepth': '',
'secnumdepth': '',
} # type: Dict[str, Any]
ADDITIONAL_SETTINGS = {
'pdflatex': {
'inputenc': '\\usepackage[utf8]{inputenc}',
'utf8extra': ('\\ifdefined\\DeclareUnicodeCharacter\n'
'% support both utf8 and utf8x syntaxes\n'
' \\ifdefined\\DeclareUnicodeCharacterAsOptional\n'
' \\def\\sphinxDUC#1{\\DeclareUnicodeCharacter{"#1}}\n'
' \\else\n'
' \\let\\sphinxDUC\\DeclareUnicodeCharacter\n'
' \\fi\n'
' \\sphinxDUC{00A0}{\\nobreakspace}\n'
' \\sphinxDUC{2500}{\\sphinxunichar{2500}}\n'
' \\sphinxDUC{2502}{\\sphinxunichar{2502}}\n'
' \\sphinxDUC{2514}{\\sphinxunichar{2514}}\n'
' \\sphinxDUC{251C}{\\sphinxunichar{251C}}\n'
' \\sphinxDUC{2572}{\\textbackslash}\n'
'\\fi'),
},
'xelatex': {
'latex_engine': 'xelatex',
'polyglossia': '\\usepackage{polyglossia}',
'babel': '',
'fontenc': ('\\usepackage{fontspec}\n'
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
'fontpkg': XELATEX_DEFAULT_FONTPKG,
'textgreek': '',
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
'{\\leavevmode\\nobreak\\ }'),
},
'lualatex': {
'latex_engine': 'lualatex',
'polyglossia': '\\usepackage{polyglossia}',
'babel': '',
'fontenc': ('\\usepackage{fontspec}\n'
'\\defaultfontfeatures[\\rmfamily,\\sffamily,\\ttfamily]{}'),
'fontpkg': LUALATEX_DEFAULT_FONTPKG,
'textgreek': '',
'utf8extra': ('\\catcode`^^^^00a0\\active\\protected\\def^^^^00a0'
'{\\leavevmode\\nobreak\\ }'),
},
'platex': {
'latex_engine': 'platex',
'babel': '',
'classoptions': ',dvipdfmx',
'fontpkg': '\\usepackage{times}',
'textgreek': '',
'fncychap': '',
'geometry': '\\usepackage[dvipdfm]{geometry}',
},
'uplatex': {
'latex_engine': 'uplatex',
'babel': '',
'classoptions': ',dvipdfmx',
'fontpkg': '\\usepackage{times}',
'textgreek': '',
'fncychap': '',
'geometry': '\\usepackage[dvipdfm]{geometry}',
},
# special settings for latex_engine + language_code
('xelatex', 'fr'): {
# use babel instead of polyglossia by default
'polyglossia': '',
'babel': '\\usepackage{babel}',
},
('xelatex', 'zh'): {
'fontenc': '\\usepackage{xeCJK}',
},
('xelatex', 'el'): {
'fontpkg': XELATEX_GREEK_DEFAULT_FONTPKG,
},
} # type: Dict[Any, Dict[str, Any]]
EXTRA_RE = re.compile(r'^(.*\S)\s+\(([^()]*)\)\s*$') EXTRA_RE = re.compile(r'^(.*\S)\s+\(([^()]*)\)\s*$')
@ -477,16 +301,18 @@ class LaTeXTranslator(SphinxTranslator):
self.compact_list = 0 self.compact_list = 0
self.first_param = 0 self.first_param = 0
sphinxpkgoptions = []
# sort out some elements # sort out some elements
self.elements = self.builder.context.copy() self.elements = self.builder.context.copy()
# but some have other interface in config file # but some have other interface in config file
self.elements['wrapperclass'] = self.format_docclass(self.settings.docclass) self.elements['wrapperclass'] = self.format_docclass(document.get('docclass'))
# we assume LaTeX class provides \chapter command except in case # we assume LaTeX class provides \chapter command except in case
# of non-Japanese 'howto' case # of non-Japanese 'howto' case
self.sectionnames = LATEXSECTIONNAMES[:] self.sectionnames = LATEXSECTIONNAMES[:]
if self.settings.docclass == 'howto': if document.get('docclass') == 'howto':
docclass = self.config.latex_docclass.get('howto', 'article') docclass = self.config.latex_docclass.get('howto', 'article')
if docclass[0] == 'j': # Japanese class... if docclass[0] == 'j': # Japanese class...
pass pass
@ -520,15 +346,12 @@ class LaTeXTranslator(SphinxTranslator):
self.numfig_secnum_depth = min(self.numfig_secnum_depth, self.numfig_secnum_depth = min(self.numfig_secnum_depth,
len(LATEXSECTIONNAMES) - 1) len(LATEXSECTIONNAMES) - 1)
# if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty # if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty
self.elements['sphinxpkgoptions'] += \ sphinxpkgoptions.append('numfigreset=%s' % self.numfig_secnum_depth)
(',numfigreset=%s' % self.numfig_secnum_depth)
else: else:
self.elements['sphinxpkgoptions'] += ',nonumfigreset' sphinxpkgoptions.append('nonumfigreset')
try:
if self.config.math_numfig: if self.config.numfig and self.config.math_numfig:
self.elements['sphinxpkgoptions'] += ',mathnumfig' sphinxpkgoptions.append('mathnumfig')
except AttributeError:
pass
if (self.config.language not in {None, 'en', 'ja'} and if (self.config.language not in {None, 'en', 'ja'} and
'fncychap' not in self.config.latex_elements): 'fncychap' not in self.config.latex_elements):
@ -591,7 +414,7 @@ class LaTeXTranslator(SphinxTranslator):
# tocdepth = 1: show parts, chapters and sections # tocdepth = 1: show parts, chapters and sections
# tocdepth = 2: show parts, chapters, sections and subsections # tocdepth = 2: show parts, chapters, sections and subsections
# ... # ...
tocdepth = self.document['tocdepth'] + self.top_sectionlevel - 2 tocdepth = self.document.get('tocdepth', 999) + self.top_sectionlevel - 2
if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \ if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
self.top_sectionlevel > 0: self.top_sectionlevel > 0:
tocdepth += 1 # because top_sectionlevel is shifted by -1 tocdepth += 1 # because top_sectionlevel is shifted by -1
@ -609,17 +432,15 @@ class LaTeXTranslator(SphinxTranslator):
self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\ self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\
minsecnumdepth minsecnumdepth
contentsname = self.settings.contentsname contentsname = document.get('contentsname')
if contentsname: if contentsname:
self.elements['contentsname'] = self.babel_renewcommand('\\contentsname', self.elements['contentsname'] = self.babel_renewcommand('\\contentsname',
contentsname) contentsname)
if self.elements['maxlistdepth']: if self.elements['maxlistdepth']:
self.elements['sphinxpkgoptions'] += (',maxlistdepth=%s' % sphinxpkgoptions.append('maxlistdepth=%s' % self.elements['maxlistdepth'])
self.elements['maxlistdepth']) if sphinxpkgoptions:
if self.elements['sphinxpkgoptions']: self.elements['sphinxpkgoptions'] = '[,%s]' % ','.join(sphinxpkgoptions)
self.elements['sphinxpkgoptions'] = ('[%s]' %
self.elements['sphinxpkgoptions'])
if self.elements['sphinxsetup']: if self.elements['sphinxsetup']:
self.elements['sphinxsetup'] = ('\\sphinxsetup{%s}' % self.elements['sphinxsetup'] = ('\\sphinxsetup{%s}' %
self.elements['sphinxsetup']) self.elements['sphinxsetup'])
@ -2313,11 +2134,18 @@ class LaTeXTranslator(SphinxTranslator):
# Import old modules here for compatibility # Import old modules here for compatibility
from sphinx.builders.latex import constants # NOQA
from sphinx.builders.latex.util import ExtBabel # NOQA from sphinx.builders.latex.util import ExtBabel # NOQA
deprecated_alias('sphinx.writers.latex', deprecated_alias('sphinx.writers.latex',
{ {
'ADDITIONAL_SETTINGS': constants.ADDITIONAL_SETTINGS,
'DEFAULT_SETTINGS': constants.DEFAULT_SETTINGS,
'LUALATEX_DEFAULT_FONTPKG': constants.LUALATEX_DEFAULT_FONTPKG,
'PDFLATEX_DEFAULT_FONTPKG': constants.PDFLATEX_DEFAULT_FONTPKG,
'XELATEX_DEFAULT_FONTPKG': constants.XELATEX_DEFAULT_FONTPKG,
'XELATEX_GREEK_DEFAULT_FONTPKG': constants.XELATEX_GREEK_DEFAULT_FONTPKG,
'ExtBabel': ExtBabel, 'ExtBabel': ExtBabel,
}, },
RemovedInSphinx40Warning) RemovedInSphinx40Warning)

View File

@ -408,11 +408,13 @@ def test_private(tempdir):
# without --private option # without --private option
apidoc_main(['-o', tempdir, tempdir]) apidoc_main(['-o', tempdir, tempdir])
assert (tempdir / 'hello.rst').exists() assert (tempdir / 'hello.rst').exists()
assert ':private-members:' not in (tempdir / 'hello.rst').text()
assert not (tempdir / '_world.rst').exists() assert not (tempdir / '_world.rst').exists()
# with --private option # with --private option
apidoc_main(['--private', '-o', tempdir, tempdir]) apidoc_main(['--private', '-f', '-o', tempdir, tempdir])
assert (tempdir / 'hello.rst').exists() assert (tempdir / 'hello.rst').exists()
assert ':private-members:' in (tempdir / 'hello.rst').text()
assert (tempdir / '_world.rst').exists() assert (tempdir / '_world.rst').exists()