diff --git a/doc/conf.py b/doc/conf.py index 210d8f2b03f4..039f91cf1ecc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -342,33 +342,113 @@ def _check_dependencies(): # the title page. latex_logo = None +# Use Unicode aware LaTeX engine +latex_engine = 'xelatex' # or 'lualatex' + latex_elements = {} + +# Keep babel usage also with xelatex (Sphinx default is polyglossia) +# If this key is removed or changed, latex build directory must be cleaned +latex_elements['babel'] = r'\usepackage{babel}' + +# Font configuration +# Fix fontspec converting " into right curly quotes in PDF +# cf https://github.com/sphinx-doc/sphinx/pull/6888/ +latex_elements['fontenc'] = r''' +\usepackage{fontspec} +\defaultfontfeatures[\rmfamily,\sffamily,\ttfamily]{} +''' + +# Sphinx 2.0 adopts GNU FreeFont by default, but it does not have all +# the Unicode codepoints needed for the section about Mathtext +# "Writing mathematical expressions" +fontpkg = r""" +\IfFontExistsTF{XITS}{ + \setmainfont{XITS} +}{ + \setmainfont{XITS}[ + Extension = .otf, + UprightFont = *-Regular, + ItalicFont = *-Italic, + BoldFont = *-Bold, + BoldItalicFont = *-BoldItalic, +]} +\IfFontExistsTF{FreeSans}{ + \setsansfont{FreeSans} +}{ + \setsansfont{FreeSans}[ + Extension = .otf, + UprightFont = *, + ItalicFont = *Oblique, + BoldFont = *Bold, + BoldItalicFont = *BoldOblique, +]} +\IfFontExistsTF{FreeMono}{ + \setmonofont{FreeMono} +}{ + \setmonofont{FreeMono}[ + Extension = .otf, + UprightFont = *, + ItalicFont = *Oblique, + BoldFont = *Bold, + BoldItalicFont = *BoldOblique, +]} +% needed for \mathbb (blackboard alphabet) to actually work +\usepackage{unicode-math} +\IfFontExistsTF{XITS Math}{ + \setmathfont{XITS Math} +}{ + \setmathfont{XITSMath-Regular}[ + Extension = .otf, +]} +""" +latex_elements['fontpkg'] = fontpkg + +# Sphinx <1.8.0 or >=2.0.0 does this by default, but the 1.8.x series +# did not for latex_engine = 'xelatex' (as it used Latin Modern font). +# We need this for code-blocks as FreeMono has wide glyphs. +latex_elements['fvset'] = r'\fvset{fontsize=\small}' +# Fix fancyhdr complaining about \headheight being too small +latex_elements['passoptionstopackages'] = r""" + \PassOptionsToPackage{headheight=14pt}{geometry} +""" + # Additional stuff for the LaTeX preamble. latex_elements['preamble'] = r""" % One line per author on title page \DeclareRobustCommand{\and}% {\end{tabular}\kern-\tabcolsep\\\begin{tabular}[t]{c}}% - % In the parameters section, place a newline after the Parameters - % header. (This is stolen directly from Numpy's conf.py, since it - % affects Numpy-style docstrings). + \usepackage{etoolbox} + \AtBeginEnvironment{sphinxthebibliography}{\appendix\part{Appendices}} \usepackage{expdlist} \let\latexdescription=\description \def\description{\latexdescription{}{} \breaklabel} - - \usepackage{amsmath} - \usepackage{amsfonts} - \usepackage{amssymb} - \usepackage{txfonts} - - % The enumitem package provides unlimited nesting of lists and - % enums. Sphinx may use this in the future, in which case this can - % be removed. See - % https://bitbucket.org/birkenfeld/sphinx/issue/777/latex-output-too-deeply-nested - \usepackage{enumitem} - \setlistdepth{2048} + % But expdlist old LaTeX package requires fixes: + % 1) remove extra space + \makeatletter + \patchcmd\@item{{\@breaklabel} }{{\@breaklabel}}{}{} + \makeatother + % 2) fix bug in expdlist's way of breaking the line after long item label + \makeatletter + \def\breaklabel{% + \def\@breaklabel{% + \leavevmode\par + % now a hack because Sphinx inserts \leavevmode after term node + \def\leavevmode{\def\leavevmode{\unhbox\voidb@x}}% + }% + } + \makeatother """ +# Sphinx 1.5 provides this to avoid "too deeply nested" LaTeX error +# and usage of "enumitem" LaTeX package is unneeded. +# Value can be increased but do not set it to something such as 2048 +# which needlessly would trigger creation of thousands of TeX macros +latex_elements['maxlistdepth'] = '10' latex_elements['pointsize'] = '11pt' +# Better looking general index in PDF +latex_elements['printindex'] = r'\footnotesize\raggedright\printindex' + # Documents to append as an appendix to all manuals. latex_appendices = [] @@ -393,13 +473,6 @@ def _check_dependencies(): numpydoc_show_class_members = False -latex_engine = 'xelatex' # or 'lualatex' - -latex_elements = { - 'babel': r'\usepackage{babel}', - 'fontpkg': r'\setmainfont{DejaVu Serif}', -} - html4_writer = True inheritance_node_attrs = dict(fontsize=16) diff --git a/doc/sphinxext/math_symbol_table.py b/doc/sphinxext/math_symbol_table.py index f12b9887e349..3041b15b36a8 100644 --- a/doc/sphinxext/math_symbol_table.py +++ b/doc/sphinxext/math_symbol_table.py @@ -100,38 +100,28 @@ def run(state_machine): - def get_n(n, l): - part = [] - for x in l: - part.append(x) - if len(part) == n: - yield part - part = [] - yield part + def render_symbol(sym): + if sym.startswith("\\"): + sym = sym[1:] + if sym not in {*mathtext.Parser._overunder_functions, + *mathtext.Parser._function_names}: + sym = chr(mathtext.tex2uni[sym]) + return f'\\{sym}' if sym in ('\\', '|') else sym lines = [] for category, columns, syms in symbols: syms = sorted(syms.split()) + columns = min(columns, len(syms)) lines.append("**%s**" % category) lines.append('') max_width = max(map(len, syms)) * 2 + 16 header = " " + (('=' * max_width) + ' ') * columns lines.append(header) - for part in get_n(columns, syms): - line = ( - " " + - " ".join( - "{} ``{}``".format( - sym - if not sym.startswith("\\") - else sym[1:] - if (sym[1:] in mathtext.Parser._overunder_functions - or sym[1:] in mathtext.Parser._function_names) - else chr(mathtext.tex2uni[sym[1:]]), - sym) - .rjust(max_width) - for sym in part)) - lines.append(line) + for part in range(0, len(syms), columns): + row = " ".join( + f"{render_symbol(sym)} ``{sym}``".rjust(max_width) + for sym in syms[part:part + columns]) + lines.append(f" {row}") lines.append(header) lines.append('') diff --git a/tutorials/text/mathtext.py b/tutorials/text/mathtext.py index 8c67142e1dc5..3663d27f5f8b 100644 --- a/tutorials/text/mathtext.py +++ b/tutorials/text/mathtext.py @@ -94,7 +94,7 @@ .. math:: - \frac{3}{4} \binom{3}{4} \genfrac{}{}{0}{}{3}{4} + \frac{3}{4} \binom{3}{4} \genfrac{}{}{0pt}{}{3}{4} Fractions can be arbitrarily nested::