diff --git a/CHANGES b/CHANGES index 82bd96d5a..5ae6b863e 100644 --- a/CHANGES +++ b/CHANGES @@ -85,6 +85,9 @@ Release 3.5.0 (in development) Dependencies ------------ +* LaTeX: ``multicol`` (it is anyhow a required part of the official latex2e + base distribution) + Incompatible changes -------------------- @@ -157,6 +160,7 @@ Bugs fixed * #8134: autodoc: crashes when mocked decorator takes arguments * #8306: autosummary: mocked modules are documented as empty page when using :recursive: option +* #8232: graphviz: Image node is not rendered if graph file is in subdirectory * #8618: html: kbd role produces incorrect HTML when compound-key separators (-, + or ^) are used as keystrokes * #8629: html: A type warning for html_use_opensearch is shown twice @@ -183,12 +187,14 @@ Bugs fixed specified * #7576: LaTeX with French babel and memoir crash: "Illegal parameter number in definition of ``\FNH@prefntext``" +* #8072: LaTeX: Directive :rst:dir:`hlist` not implemented in LaTeX * #8214: LaTeX: The :rst:role:`index` role and the glossary generate duplicate entries in the LaTeX index (if both used for same term) * #8735: LaTeX: wrong internal links in pdf to captioned code-blocks when :confval:`numfig` is not True * #8442: LaTeX: some indexed terms are ignored when using xelatex engine (or pdflatex and :confval:`latex_use_xindy` set to True) with memoir class +* #8780: LaTeX: long words in narrow columns may not be hyphenated Testing -------- diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index be085b357..117972a36 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -12,17 +12,13 @@ The following is a list of deprecated interfaces. .. tabularcolumns:: |>{\raggedright}\Y{.4}|>{\centering}\Y{.1}|>{\centering}\Y{.12}|>{\raggedright\arraybackslash}\Y{.38}| -.. |LaTeXHyphenate| raw:: latex - - \hspace{0pt} - .. list-table:: deprecated APIs :header-rows: 1 :class: deprecated :widths: 40, 10, 10, 40 * - Target - - |LaTeXHyphenate|\ Deprecated + - Deprecated - (will be) Removed - Alternatives diff --git a/doc/latex.rst b/doc/latex.rst index f3a99932f..81706d00f 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -1029,6 +1029,14 @@ Environments Miscellany ~~~~~~~~~~ +- Every text paragraph in document body starts with `\sphinxAtStartPar`. + Currently, this is used to insert a zero width horizontal skip which + is a trick to allow TeX hyphenation of the first word of a paragraph + in a narrow context (like a table cell). For ``'lualatex'`` which + does not need the trick, the `\sphinxAtStartPar` does nothing. + + .. versionadded:: 3.5.0 + - The section, subsection, ... headings are set using *titlesec*'s ``\titleformat`` command. diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 106303bd6..9a5ca6041 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -428,6 +428,8 @@ class CheckExternalLinksBuilder(DummyBuilder): self.write_entry('redirected ' + text, docname, filename, lineno, uri + ' to ' + info) self.write_linkstat(linkstat) + else: + raise ValueError("Unknown status %s." % status) def write_entry(self, what: str, docname: str, filename: str, line: int, uri: str) -> None: diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 038da99e1..7dd6252e2 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -280,6 +280,7 @@ class HList(SphinxDirective): npercol, nmore = divmod(len(fulllist), ncolumns) index = 0 newnode = addnodes.hlist() + newnode['ncolumns'] = str(ncolumns) for column in range(ncolumns): endindex = index + ((npercol + 1) if column < nmore else npercol) bullet_list = nodes.bullet_list() diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 402b7c990..f10285086 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -142,6 +142,7 @@ class Graphviz(SphinxDirective): 'it failed') % filename, line=self.lineno)] else: dotcode = '\n'.join(self.content) + rel_filename = None if not dotcode.strip(): return [self.state_machine.reporter.warning( __('Ignoring "graphviz" directive without content.'), @@ -160,6 +161,8 @@ class Graphviz(SphinxDirective): node['align'] = self.options['align'] if 'class' in self.options: node['classes'] = self.options['class'] + if rel_filename: + node['filename'] = rel_filename if 'caption' not in self.options: self.add_name(node) @@ -213,8 +216,8 @@ class GraphvizSimple(SphinxDirective): return [figure] -def render_dot(self: SphinxTranslator, code: str, options: Dict, - format: str, prefix: str = 'graphviz') -> Tuple[str, str]: +def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str, + prefix: str = 'graphviz', filename: str = None) -> Tuple[str, str]: """Render graphviz code into a PNG or PDF output file.""" graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot) hashkey = (code + str(options) + str(graphviz_dot) + @@ -238,7 +241,10 @@ def render_dot(self: SphinxTranslator, code: str, options: Dict, dot_args.extend(['-T' + format, '-o' + outfn]) docname = options.get('docname', 'index') - cwd = path.dirname(path.join(self.builder.srcdir, docname)) + if filename: + cwd = path.dirname(path.join(self.builder.srcdir, filename)) + else: + cwd = path.dirname(path.join(self.builder.srcdir, docname)) if format == 'png': dot_args.extend(['-Tcmapx', '-o%s.map' % outfn]) @@ -263,14 +269,14 @@ def render_dot(self: SphinxTranslator, code: str, options: Dict, def render_dot_html(self: HTMLTranslator, node: graphviz, code: str, options: Dict, - prefix: str = 'graphviz', imgcls: str = None, alt: str = None - ) -> Tuple[str, str]: + prefix: str = 'graphviz', imgcls: str = None, alt: str = None, + filename: str = None) -> Tuple[str, str]: format = self.builder.config.graphviz_output_format try: if format not in ('png', 'svg'): raise GraphvizError(__("graphviz_output_format must be one of 'png', " "'svg', but is %r") % format) - fname, outfn = render_dot(self, code, options, format, prefix) + fname, outfn = render_dot(self, code, options, format, prefix, filename) except GraphvizError as exc: logger.warning(__('dot code %r: %s'), code, exc) raise nodes.SkipNode from exc @@ -315,13 +321,14 @@ def render_dot_html(self: HTMLTranslator, node: graphviz, code: str, options: Di def html_visit_graphviz(self: HTMLTranslator, node: graphviz) -> None: - render_dot_html(self, node, node['code'], node['options']) + render_dot_html(self, node, node['code'], node['options'], filename=node.get('filename')) def render_dot_latex(self: LaTeXTranslator, node: graphviz, code: str, - options: Dict, prefix: str = 'graphviz') -> None: + options: Dict, prefix: str = 'graphviz', filename: str = None + ) -> None: try: - fname, outfn = render_dot(self, code, options, 'pdf', prefix) + fname, outfn = render_dot(self, code, options, 'pdf', prefix, filename) except GraphvizError as exc: logger.warning(__('dot code %r: %s'), code, exc) raise nodes.SkipNode from exc @@ -352,7 +359,7 @@ def render_dot_latex(self: LaTeXTranslator, node: graphviz, code: str, def latex_visit_graphviz(self: LaTeXTranslator, node: graphviz) -> None: - render_dot_latex(self, node, node['code'], node['options']) + render_dot_latex(self, node, node['code'], node['options'], filename=node.get('filename')) def render_dot_texinfo(self: TexinfoTranslator, node: graphviz, code: str, diff --git a/sphinx/texinputs/sphinxlatexoptionhandling.sty b/sphinx/texinputs/sphinxlatexoptionhandling.sty index d71be4f81..61362ff0b 100644 --- a/sphinx/texinputs/sphinxlatexoptionhandling.sty +++ b/sphinx/texinputs/sphinxlatexoptionhandling.sty @@ -128,7 +128,12 @@ \DisableKeyvalOption{sphinx}{numfigreset} \DisableKeyvalOption{sphinx}{nonumfigreset} \DisableKeyvalOption{sphinx}{mathnumfig} +% To allow hyphenation of first word in narrow contexts; no option, +% customization to be done via 'preamble' key +\newcommand*\sphinxAtStartPar{\nobreak\hskip\z@skip} +% No need for the \hspace{0pt} trick (\hskip\z@skip) with luatex +\ifdefined\directlua\let\sphinxAtStartPar\@empty\fi % user interface: options can be changed midway in a document! \newcommand\sphinxsetup[1]{\setkeys{sphinx}{#1}} -\endinput \ No newline at end of file +\endinput diff --git a/sphinx/texinputs/sphinxlatexrequirepackages.sty b/sphinx/texinputs/sphinxlatexrequirepackages.sty index 765e61e8c..c54fd2a67 100644 --- a/sphinx/texinputs/sphinxlatexrequirepackages.sty +++ b/sphinx/texinputs/sphinxlatexrequirepackages.sty @@ -208,6 +208,8 @@ \ltx@ifundefined{@removefromreset} {\RequirePackage{remreset}} {}% avoid warning +% To support hlist directive +\RequirePackage{multicol} % to make pdf with correct encoded bookmarks in Japanese % this should precede the hyperref package \ifx\kanjiskip\@undefined diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index fc597ec08..85fc7302b 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -1159,7 +1159,9 @@ class LaTeXTranslator(SphinxTranslator): # (first one is label node) pass else: - self.body.append('\n') + # the \sphinxAtStartPar is to allow hyphenation of first word of + # a paragraph in narrow contexts such as in a table cell + self.body.append('\n\\sphinxAtStartPar\n') def depart_paragraph(self, node: Element) -> None: self.body.append('\n') @@ -1173,9 +1175,11 @@ class LaTeXTranslator(SphinxTranslator): self.body.append('\n\\end{center}') def visit_hlist(self, node: Element) -> None: - # for now, we don't support a more compact list format - # don't add individual itemize environments, but one for all columns self.compact_list += 1 + ncolumns = node['ncolumns'] + if self.compact_list > 1: + self.body.append('\\setlength{\\multicolsep}{0pt}\n') + self.body.append('\\begin{multicols}{' + ncolumns + '}\\raggedright\n') self.body.append('\\begin{itemize}\\setlength{\\itemsep}{0pt}' '\\setlength{\\parskip}{0pt}\n') if self.table: @@ -1183,12 +1187,17 @@ class LaTeXTranslator(SphinxTranslator): def depart_hlist(self, node: Element) -> None: self.compact_list -= 1 - self.body.append('\\end{itemize}\n') + self.body.append('\\end{itemize}\\raggedcolumns\\end{multicols}\n') def visit_hlistcol(self, node: Element) -> None: pass def depart_hlistcol(self, node: Element) -> None: + # \columnbreak would guarantee same columns as in html ouput. But + # some testing with long items showed that columns may be too uneven. + # And in case only of short items, the automatic column breaks should + # match the ones pre-computed by the hlist() directive. + # self.body.append('\\columnbreak\n') pass def latex_image_length(self, width_str: str, scale: int = 100) -> str: diff --git a/tests/roots/test-latex-equations/expects/latex-equations.tex b/tests/roots/test-latex-equations/expects/latex-equations.tex index ce07a0128..5374a6721 100644 --- a/tests/roots/test-latex-equations/expects/latex-equations.tex +++ b/tests/roots/test-latex-equations/expects/latex-equations.tex @@ -1,13 +1,18 @@ + +\sphinxAtStartPar Equation without a label. \begin{equation*} \begin{split}E = mc^2\end{split} \end{equation*} +\sphinxAtStartPar Equation with label. \begin{equation}\label{equation:equations:test} \begin{split}E = hv\end{split} \end{equation} +\sphinxAtStartPar Second equation without label. \begin{equation*} \begin{split}c^2 = a^2 + b^2\end{split} \end{equation*} +\sphinxAtStartPar Equation with label \eqref{equation:equations:test} is important. diff --git a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex index 5d524c257..4d432f500 100644 --- a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex +++ b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex @@ -1,10 +1,13 @@ \label{\detokenize{complex:complex-spanning-cell}} +\sphinxAtStartPar table having … \begin{itemize} \item {} +\sphinxAtStartPar consecutive multirow at top of row (1\sphinxhyphen{}1 and 1\sphinxhyphen{}2) \item {} +\sphinxAtStartPar consecutive multirow at end of row (1\sphinxhyphen{}4 and 1\sphinxhyphen{}5) \end{itemize} @@ -16,26 +19,35 @@ consecutive multirow at end of row (1\sphinxhyphen{}4 and 1\sphinxhyphen{}5) \hline \sphinxmultirow{3}{1}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} + +\sphinxAtStartPar cell1\sphinxhyphen{}1 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxmultirow{3}{2}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} + +\sphinxAtStartPar cell1\sphinxhyphen{}2 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% & +\sphinxAtStartPar cell1\sphinxhyphen{}3 &\sphinxmultirow{3}{4}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} + +\sphinxAtStartPar cell1\sphinxhyphen{}4 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxmultirow{2}{5}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} + +\sphinxAtStartPar cell1\sphinxhyphen{}5 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% @@ -43,12 +55,15 @@ cell1\sphinxhyphen{}5 \\ \cline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} + +\sphinxAtStartPar cell2\sphinxhyphen{}3 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxtablestrut{4}&\sphinxtablestrut{5}\\ \cline{5-5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}& +\sphinxAtStartPar cell3\sphinxhyphen{}5 \\ \hline diff --git a/tests/roots/test-latex-table/expects/gridtable.tex b/tests/roots/test-latex-table/expects/gridtable.tex index 28b0b086b..fc5b757b9 100644 --- a/tests/roots/test-latex-table/expects/gridtable.tex +++ b/tests/roots/test-latex-table/expects/gridtable.tex @@ -5,35 +5,47 @@ \begin{tabulary}{\linewidth}[t]{|T|T|T|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 &\sphinxstyletheadfamily +\sphinxAtStartPar header3 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 &\sphinxmultirow{2}{5}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} + +\sphinxAtStartPar cell1\sphinxhyphen{}2 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% & +\sphinxAtStartPar cell1\sphinxhyphen{}3 \\ \cline{1-1}\cline{3-3}\sphinxmultirow{2}{7}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} + +\sphinxAtStartPar cell2\sphinxhyphen{}1 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxtablestrut{5}& +\sphinxAtStartPar cell2\sphinxhyphen{}3 \\ \cline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}% \sphinxmultirow{2}{9}{% \begin{varwidth}[t]{\sphinxcolwidth{2}{3}} + +\sphinxAtStartPar cell3\sphinxhyphen{}2 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% @@ -41,10 +53,13 @@ cell3\sphinxhyphen{}2 \sphinxstopmulticolumn \\ \cline{1-1} +\sphinxAtStartPar cell4\sphinxhyphen{}1 &\multicolumn{2}{l|}{\sphinxtablestrut{9}}\\ \hline\sphinxstartmulticolumn{3}% \begin{varwidth}[t]{\sphinxcolwidth{3}{3}} + +\sphinxAtStartPar cell5\sphinxhyphen{}1 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex index 9febfcef5..e2138ad58 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -27,18 +31,24 @@ header2 \endlastfoot +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_align.tex b/tests/roots/test-latex-table/expects/longtable_having_align.tex index 1969e19d2..764ef55f3 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[r]{|l|l|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -27,18 +31,24 @@ header2 \endlastfoot +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_caption.tex b/tests/roots/test-latex-table/expects/longtable_having_caption.tex index f0041e9ec..0ca5506be 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -5,8 +5,10 @@ \caption{caption for longtable\strut}\label{\detokenize{longtable:id1}}\\*[\sphinxlongtablecapskipadjust] \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -16,8 +18,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -29,18 +33,24 @@ header2 \endlastfoot +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex index 050527b69..9551a0a3b 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -28,23 +32,30 @@ header2 \endlastfoot \begin{itemize} \item {} +\sphinxAtStartPar item1 \item {} +\sphinxAtStartPar item2 \end{itemize} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex index 68e74c5f4..e54f8acec 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex @@ -3,10 +3,13 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{3}{\X{1}{3}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 &\sphinxstyletheadfamily +\sphinxAtStartPar header3 \\ \hline @@ -16,10 +19,13 @@ header3 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 &\sphinxstyletheadfamily +\sphinxAtStartPar header3 \\ \hline @@ -32,22 +38,29 @@ header3 \endlastfoot \sphinxstyletheadfamily \begin{itemize} \item {} +\sphinxAtStartPar instub1\sphinxhyphen{}1a \item {} +\sphinxAtStartPar instub1\sphinxhyphen{}1b \end{itemize} &\sphinxstyletheadfamily +\sphinxAtStartPar instub1\sphinxhyphen{}2 & +\sphinxAtStartPar notinstub1\sphinxhyphen{}3 \\ \hline\sphinxstyletheadfamily +\sphinxAtStartPar cell2\sphinxhyphen{}1 &\sphinxstyletheadfamily +\sphinxAtStartPar cell2\sphinxhyphen{}2 & +\sphinxAtStartPar cell2\sphinxhyphen{}3 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex index c7213b906..a0e7ecfcd 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -31,16 +35,21 @@ header2 \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths.tex b/tests/roots/test-latex-table/expects/longtable_having_widths.tex index 884fd9f8a..cdd0e7a2b 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|} \hline\noalign{\phantomsection\label{\detokenize{longtable:namedlongtable}}\label{\detokenize{longtable:mylongtable}}}% \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -27,21 +31,28 @@ header2 \endlastfoot +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline \end{longtable}\sphinxatlongtableend\end{savenotes} +\sphinxAtStartPar See {\hyperref[\detokenize{longtable:mylongtable}]{\sphinxcrossref{mylongtable}}}, same as {\hyperref[\detokenize{longtable:namedlongtable}]{\sphinxcrossref{\DUrole{std,std-ref}{this one}}}}. diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex index 17c5ec4cc..ea868ffe4 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -28,23 +32,30 @@ header2 \endlastfoot \begin{itemize} \item {} +\sphinxAtStartPar item1 \item {} +\sphinxAtStartPar item2 \end{itemize} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex index 2fbbbc4ef..426086de5 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -3,8 +3,10 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|c|c|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,8 +16,10 @@ header2 {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -27,18 +31,24 @@ header2 \endlastfoot +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/simple_table.tex b/tests/roots/test-latex-table/expects/simple_table.tex index 8044a6cc4..a06bfb1cf 100644 --- a/tests/roots/test-latex-table/expects/simple_table.tex +++ b/tests/roots/test-latex-table/expects/simple_table.tex @@ -5,23 +5,31 @@ \begin{tabulary}{\linewidth}[t]{|T|T|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_caption.tex b/tests/roots/test-latex-table/expects/table_having_caption.tex index d4423a05d..33a5f1d8f 100644 --- a/tests/roots/test-latex-table/expects/table_having_caption.tex +++ b/tests/roots/test-latex-table/expects/table_having_caption.tex @@ -9,23 +9,31 @@ \begin{tabulary}{\linewidth}[t]{|T|T|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex index 7a9b0f293..c5c57e2f7 100644 --- a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex @@ -5,29 +5,38 @@ \begin{tabular}[t]{|*{2}{\X{1}{2}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline\begin{itemize} \item {} +\sphinxAtStartPar item1 \item {} +\sphinxAtStartPar item2 \end{itemize} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex index 700fc4663..13c48a213 100644 --- a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex @@ -5,30 +5,40 @@ \begin{tabular}[t]{|*{3}{\X{1}{3}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 &\sphinxstyletheadfamily +\sphinxAtStartPar header3 \\ \hline\sphinxstyletheadfamily \begin{itemize} \item {} +\sphinxAtStartPar instub1\sphinxhyphen{}1a \item {} +\sphinxAtStartPar instub1\sphinxhyphen{}1b \end{itemize} &\sphinxstyletheadfamily +\sphinxAtStartPar instub1\sphinxhyphen{}2 & +\sphinxAtStartPar notinstub1\sphinxhyphen{}3 \\ \hline\sphinxstyletheadfamily +\sphinxAtStartPar cell2\sphinxhyphen{}1 &\sphinxstyletheadfamily +\sphinxAtStartPar cell2\sphinxhyphen{}2 & +\sphinxAtStartPar cell2\sphinxhyphen{}3 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex index 6d3e81021..c1a440558 100644 --- a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex +++ b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex @@ -5,13 +5,17 @@ \begin{tabulary}{\linewidth}[t]{|T|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par1 +\sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par2 +\sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par3 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_verbatim.tex b/tests/roots/test-latex-table/expects/table_having_verbatim.tex index f66bb8001..23faac55e 100644 --- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex @@ -5,8 +5,10 @@ \begin{tabular}[t]{|*{2}{\X{1}{2}|}} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline @@ -14,16 +16,21 @@ header2 \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/table_having_widths.tex b/tests/roots/test-latex-table/expects/table_having_widths.tex index 094596bec..d01a40576 100644 --- a/tests/roots/test-latex-table/expects/table_having_widths.tex +++ b/tests/roots/test-latex-table/expects/table_having_widths.tex @@ -6,23 +6,31 @@ \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline @@ -30,4 +38,5 @@ cell3\sphinxhyphen{}2 \par \sphinxattableend\end{savenotes} +\sphinxAtStartPar See {\hyperref[\detokenize{tabular:mytabular}]{\sphinxcrossref{\DUrole{std,std-ref}{this}}}}, same as {\hyperref[\detokenize{tabular:namedtabular}]{\sphinxcrossref{namedtabular}}}. diff --git a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex index a636b022e..ca6b697e5 100644 --- a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex @@ -5,29 +5,38 @@ \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline\begin{itemize} \item {} +\sphinxAtStartPar item1 \item {} +\sphinxAtStartPar item2 \end{itemize} & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/tabular_having_widths.tex b/tests/roots/test-latex-table/expects/tabular_having_widths.tex index 5ee1542d4..596ba4868 100644 --- a/tests/roots/test-latex-table/expects/tabular_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabular_having_widths.tex @@ -5,23 +5,31 @@ \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/tabularcolumn.tex b/tests/roots/test-latex-table/expects/tabularcolumn.tex index 02e9af440..c020e0cb4 100644 --- a/tests/roots/test-latex-table/expects/tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/tabularcolumn.tex @@ -5,23 +5,31 @@ \begin{tabulary}{\linewidth}[t]{|c|c|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex index 06d347fa3..0b42fb0cf 100644 --- a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex @@ -5,23 +5,31 @@ \begin{tabulary}{\linewidth}[t]{|T|T|} \hline \sphinxstyletheadfamily +\sphinxAtStartPar header1 &\sphinxstyletheadfamily +\sphinxAtStartPar header2 \\ \hline +\sphinxAtStartPar cell1\sphinxhyphen{}1 & +\sphinxAtStartPar cell1\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell2\sphinxhyphen{}1 & +\sphinxAtStartPar cell2\sphinxhyphen{}2 \\ \hline +\sphinxAtStartPar cell3\sphinxhyphen{}1 & +\sphinxAtStartPar cell3\sphinxhyphen{}2 \\ \hline diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index c4584a15e..5b1955a0f 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -729,13 +729,14 @@ def test_footnote(app, status, warning): '\\end{footnote}') in result assert '\\begin{footnote}[3]\\sphinxAtStartFootnote\nnamed\n%\n\\end{footnote}' in result assert '\\sphinxcite{footnote:bar}' in result - assert ('\\bibitem[bar]{footnote:bar}\ncite\n') in result + assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result assert '\\sphinxcaption{Table caption \\sphinxfootnotemark[4]' in result assert ('\\hline%\n\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n' 'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n' '\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n' - 'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces \n' - 'VIDIOC\\_CROPCAP\n&\n') in result + 'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces ' + '\n\\sphinxAtStartPar\n' + 'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result assert ('Information about VIDIOC\\_CROPCAP %\n' '\\begin{footnote}[6]\\sphinxAtStartFootnote\n' 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n\\hline\n' @@ -775,7 +776,7 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning): assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n' '{\\hyperref[\\detokenize{index:codeblockinfootnote}]' '{\\sphinxcrossref{\\DUrole{std,std-ref}{I am in a footnote}}}}') in result - assert ('&\nThis is one more footnote with some code in it %\n' + assert ('&\n\\sphinxAtStartPar\nThis is one more footnote with some code in it %\n' '\\begin{footnote}[11]\\sphinxAtStartFootnote\n' 'Third footnote in longtable\n') in result assert ('\\end{sphinxVerbatim}\n%\n\\end{footnote}.\n') in result @@ -815,13 +816,15 @@ def test_latex_show_urls_is_inline(app, status, warning): assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} ' '(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} ' - '(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\nDescription' in result) + '(http://sphinx\\sphinxhyphen{}doc.org/)}] ' + '\\leavevmode\n\\sphinxAtStartPar\nDescription' in result) assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' '\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n' - 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n' - 'Description') in result + 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' + '\n\\sphinxAtStartPar\nDescription') in result assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} ' - '(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\nDescription') in result + '(http://sphinx\\sphinxhyphen{}doc.org/)}] ' + '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result assert '\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' '{sphinx\\sphinxhyphen{}dev@googlegroups.com}') in result @@ -866,16 +869,16 @@ def test_latex_show_urls_is_footnote(app, status, warning): '{URL in term}\\sphinxfootnotemark[9]}] ' '\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n' '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' - '\\end{footnotetext}\\ignorespaces \nDescription') in result + '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] ' '\\leavevmode%\n\\begin{footnotetext}[11]\\sphinxAtStartFootnote\n' - 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n' - 'Description') in result + 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' + '\n\\sphinxAtStartPar\nDescription') in result assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}' '\\sphinxfootnotemark[10]}] ' '\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n' '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' - '\\end{footnotetext}\\ignorespaces \nDescription') in result + '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result) assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result @@ -912,13 +915,13 @@ def test_latex_show_urls_is_no(app, status, warning): 'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result assert '\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' in result assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}] ' - '\\leavevmode\nDescription') in result + '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' '\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n' - 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n' - 'Description') in result + 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' + '\n\\sphinxAtStartPar\nDescription') in result assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] ' - '\\leavevmode\nDescription') in result + '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result) assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result @@ -1347,7 +1350,7 @@ def test_latex_index(app, status, warning): '\\index{equation@\\spxentry{equation}}equation:\n' in result) assert ('\n\\index{Einstein@\\spxentry{Einstein}}' '\\index{relativity@\\spxentry{relativity}}' - '\\ignorespaces \nand') in result + '\\ignorespaces \n\\sphinxAtStartPar\nand') in result assert ('\n\\index{main \\sphinxleftcurlybrace{}@\\spxentry{' 'main \\sphinxleftcurlybrace{}}}\\ignorespaces ' in result) @@ -1396,7 +1399,7 @@ def test_latex_thebibliography(app, status, warning): result = (app.outdir / 'python.tex').read_text() print(result) assert ('\\begin{sphinxthebibliography}{AuthorYe}\n' - '\\bibitem[AuthorYear]{index:authoryear}\n' + '\\bibitem[AuthorYear]{index:authoryear}\n\\sphinxAtStartPar\n' 'Author, Title, Year\n' '\\end{sphinxthebibliography}\n' in result) assert '\\sphinxcite{index:authoryear}' in result @@ -1440,7 +1443,8 @@ def test_latex_labels(app, status, warning): r'\end{figure}' in result) assert (r'\caption{labeled figure}' '\\label{\\detokenize{index:figure3}}\n' - '\\begin{sphinxlegend}\nwith a legend\n\\end{sphinxlegend}\n' + '\\begin{sphinxlegend}\n\\sphinxAtStartPar\n' + 'with a legend\n\\end{sphinxlegend}\n' r'\end{figure}' in result) # code-blocks diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py index 55a2bf233..60b62435c 100644 --- a/tests/test_build_linkcheck.py +++ b/tests/test_build_linkcheck.py @@ -31,7 +31,7 @@ ts_re = re.compile(r".*\[(?P.*)\].*") @pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True) def test_defaults(app): - app.builder.build_all() + app.build() assert (app.outdir / 'output.txt').exists() content = (app.outdir / 'output.txt').read_text() @@ -52,7 +52,7 @@ def test_defaults(app): @pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True) def test_defaults_json(app): - app.builder.build_all() + app.build() assert (app.outdir / 'output.json').exists() content = (app.outdir / 'output.json').read_text() @@ -113,7 +113,7 @@ def test_defaults_json(app): 'path/to/notfound'] }) def test_anchors_ignored(app): - app.builder.build_all() + app.build() assert (app.outdir / 'output.txt').exists() content = (app.outdir / 'output.txt').read_text() @@ -129,7 +129,7 @@ def test_raises_for_invalid_status(app): self.send_error(500, "Internal Server Error") with http_server(InternalServerErrorHandler): - app.builder.build_all() + app.build() content = (app.outdir / 'output.txt').read_text() assert content == ( "index.rst:1: [broken] http://localhost:7777/#anchor: " @@ -157,7 +157,7 @@ class HeadersDumperHandler(http.server.BaseHTTPRequestHandler): ]}) def test_auth_header_uses_first_match(app, capsys): with http_server(HeadersDumperHandler): - app.builder.build_all() + app.build() stdout, stderr = capsys.readouterr() auth = requests.auth._basic_auth_str('user1', 'password') assert "Authorization: %s\n" % auth in stdout @@ -168,7 +168,7 @@ def test_auth_header_uses_first_match(app, capsys): confoverrides={'linkcheck_auth': [(r'^$', ('user1', 'password'))]}) def test_auth_header_no_match(app, capsys): with http_server(HeadersDumperHandler): - app.builder.build_all() + app.build() stdout, stderr = capsys.readouterr() assert "Authorization" not in stdout @@ -185,7 +185,7 @@ def test_auth_header_no_match(app, capsys): }}) def test_linkcheck_request_headers(app, capsys): with http_server(HeadersDumperHandler): - app.builder.build_all() + app.build() stdout, _stderr = capsys.readouterr() assert "Accept: text/html\n" in stdout @@ -201,7 +201,7 @@ def test_linkcheck_request_headers(app, capsys): }}) def test_linkcheck_request_headers_no_slash(app, capsys): with http_server(HeadersDumperHandler): - app.builder.build_all() + app.build() stdout, _stderr = capsys.readouterr() assert "Accept: application/json\n" in stdout @@ -217,7 +217,7 @@ def test_linkcheck_request_headers_no_slash(app, capsys): }}) def test_linkcheck_request_headers_default(app, capsys): with http_server(HeadersDumperHandler): - app.builder.build_all() + app.build() stdout, _stderr = capsys.readouterr() assert "Accepts: application/json\n" not in stdout @@ -251,7 +251,7 @@ def make_redirect_handler(*, support_head): @pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver', freshenv=True) def test_follows_redirects_on_HEAD(app, capsys): with http_server(make_redirect_handler(support_head=True)): - app.builder.build_all() + app.build() stdout, stderr = capsys.readouterr() content = (app.outdir / 'output.txt').read_text() assert content == ( @@ -269,7 +269,7 @@ def test_follows_redirects_on_HEAD(app, capsys): @pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver', freshenv=True) def test_follows_redirects_on_GET(app, capsys): with http_server(make_redirect_handler(support_head=False)): - app.builder.build_all() + app.build() stdout, stderr = capsys.readouterr() content = (app.outdir / 'output.txt').read_text() assert content == ( @@ -299,7 +299,7 @@ class OKHandler(http.server.BaseHTTPRequestHandler): def test_invalid_ssl(app): # Link indicates SSL should be used (https) but the server does not handle it. with http_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -313,7 +313,7 @@ def test_invalid_ssl(app): @pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver-https', freshenv=True) def test_connect_to_selfsigned_fails(app): with https_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -328,7 +328,7 @@ def test_connect_to_selfsigned_fails(app): def test_connect_to_selfsigned_with_tls_verify_false(app): app.config.tls_verify = False with https_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -346,7 +346,7 @@ def test_connect_to_selfsigned_with_tls_verify_false(app): def test_connect_to_selfsigned_with_tls_cacerts(app): app.config.tls_cacerts = CERT_FILE with https_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -364,7 +364,7 @@ def test_connect_to_selfsigned_with_tls_cacerts(app): def test_connect_to_selfsigned_with_requests_env_var(monkeypatch, app): monkeypatch.setenv("REQUESTS_CA_BUNDLE", CERT_FILE) with https_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -382,7 +382,7 @@ def test_connect_to_selfsigned_with_requests_env_var(monkeypatch, app): def test_connect_to_selfsigned_nonexistent_cert_file(app): app.config.tls_cacerts = "does/not/exist" with https_server(OKHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -410,7 +410,7 @@ def test_TooManyRedirects_on_HEAD(app): self.wfile.write(b"ok\n") with http_server(InfiniteRedirectOnHeadHandler): - app.builder.build_all() + app.build() with open(app.outdir / 'output.json') as fp: content = json.load(fp) @@ -445,7 +445,7 @@ def test_too_many_requests_retry_after_int_delay(app, capsys, status): with http_server(make_retry_after_handler([(429, "0"), (200, None)])), \ mock.patch("sphinx.builders.linkcheck.DEFAULT_DELAY", 0), \ mock.patch("sphinx.builders.linkcheck.QUEUE_POLL_SECS", 0.01): - app.builder.build_all() + app.build() content = (app.outdir / 'output.json').read_text() assert json.loads(content) == { "filename": "index.rst", @@ -471,7 +471,7 @@ def test_too_many_requests_retry_after_HTTP_date(app, capsys): now = datetime.now().timetuple() retry_after = wsgiref.handlers.format_date_time(time.mktime(now)) with http_server(make_retry_after_handler([(429, retry_after), (200, None)])): - app.builder.build_all() + app.build() content = (app.outdir / 'output.json').read_text() assert json.loads(content) == { "filename": "index.rst", @@ -494,7 +494,7 @@ def test_too_many_requests_retry_after_HTTP_date(app, capsys): def test_too_many_requests_retry_after_without_header(app, capsys): with http_server(make_retry_after_handler([(429, None), (200, None)])),\ mock.patch("sphinx.builders.linkcheck.DEFAULT_DELAY", 0): - app.builder.build_all() + app.build() content = (app.outdir / 'output.json').read_text() assert json.loads(content) == { "filename": "index.rst", @@ -517,7 +517,7 @@ def test_too_many_requests_retry_after_without_header(app, capsys): def test_too_many_requests_user_timeout(app, capsys): app.config.linkcheck_rate_limit_timeout = 0.0 with http_server(make_retry_after_handler([(429, None)])): - app.builder.build_all() + app.build() content = (app.outdir / 'output.json').read_text() assert json.loads(content) == { "filename": "index.rst", diff --git a/tests/test_markup.py b/tests/test_markup.py index 18c40ec1d..f8fff1c2d 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -158,7 +158,8 @@ def get_verifier(verify, verify_re): ':pep:`8`', ('

PEP 8

'), - ('\\index{Python Enhancement Proposals@\\spxentry{Python Enhancement Proposals}' + ('\\sphinxAtStartPar\n' + '\\index{Python Enhancement Proposals@\\spxentry{Python Enhancement Proposals}' '!PEP 8@\\spxentry{PEP 8}}\\sphinxhref{http://www.python.org/dev/peps/pep-0008}' '{\\sphinxstylestrong{PEP 8}}') ), @@ -169,7 +170,8 @@ def get_verifier(verify, verify_re): ('

' 'PEP 8#id1

'), - ('\\index{Python Enhancement Proposals@\\spxentry{Python Enhancement Proposals}' + ('\\sphinxAtStartPar\n' + '\\index{Python Enhancement Proposals@\\spxentry{Python Enhancement Proposals}' '!PEP 8\\#id1@\\spxentry{PEP 8\\#id1}}\\sphinxhref' '{http://www.python.org/dev/peps/pep-0008\\#id1}' '{\\sphinxstylestrong{PEP 8\\#id1}}') @@ -180,7 +182,8 @@ def get_verifier(verify, verify_re): ':rfc:`2324`', ('

RFC 2324

'), - ('\\index{RFC@\\spxentry{RFC}!RFC 2324@\\spxentry{RFC 2324}}' + ('\\sphinxAtStartPar\n' + '\\index{RFC@\\spxentry{RFC}!RFC 2324@\\spxentry{RFC 2324}}' '\\sphinxhref{http://tools.ietf.org/html/rfc2324.html}' '{\\sphinxstylestrong{RFC 2324}}') ), @@ -191,7 +194,8 @@ def get_verifier(verify, verify_re): ('

' 'RFC 2324#id1

'), - ('\\index{RFC@\\spxentry{RFC}!RFC 2324\\#id1@\\spxentry{RFC 2324\\#id1}}' + ('\\sphinxAtStartPar\n' + '\\index{RFC@\\spxentry{RFC}!RFC 2324\\#id1@\\spxentry{RFC 2324\\#id1}}' '\\sphinxhref{http://tools.ietf.org/html/rfc2324.html\\#id1}' '{\\sphinxstylestrong{RFC 2324\\#id1}}') ), @@ -201,14 +205,14 @@ def get_verifier(verify, verify_re): '``code sample``', ('

' 'code   sample

'), - r'\\sphinxcode{\\sphinxupquote{code sample}}', + r'\\sphinxAtStartPar\n\\sphinxcode{\\sphinxupquote{code sample}}', ), ( # interpolation of arrows in menuselection 'verify', ':menuselection:`a --> b`', ('

a \N{TRIANGULAR BULLET} b

'), - '\\sphinxmenuselection{a \\(\\rightarrow\\) b}', + '\\sphinxAtStartPar\n\\sphinxmenuselection{a \\(\\rightarrow\\) b}', ), ( # interpolation of ampersands in menuselection @@ -216,7 +220,9 @@ def get_verifier(verify, verify_re): ':menuselection:`&Foo -&&- &Bar`', ('

Foo ' '-&- Bar

'), - r'\sphinxmenuselection{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}', + ('\\sphinxAtStartPar\n' + r'\sphinxmenuselection{\sphinxaccelerator{F}oo \sphinxhyphen{}' + r'\&\sphinxhyphen{} \sphinxaccelerator{B}ar}'), ), ( # interpolation of ampersands in guilabel @@ -224,21 +230,22 @@ def get_verifier(verify, verify_re): ':guilabel:`&Foo -&&- &Bar`', ('

Foo ' '-&- Bar

'), - r'\sphinxguilabel{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}', + ('\\sphinxAtStartPar\n' + r'\sphinxguilabel{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}'), ), ( # no ampersands in guilabel 'verify', ':guilabel:`Foo`', '

Foo

', - r'\sphinxguilabel{Foo}', + '\\sphinxAtStartPar\n\\sphinxguilabel{Foo}', ), ( # kbd role 'verify', ':kbd:`space`', '

space

', - '\\sphinxkeyboard{\\sphinxupquote{space}}', + '\\sphinxAtStartPar\n\\sphinxkeyboard{\\sphinxupquote{space}}', ), ( # kbd role @@ -249,7 +256,7 @@ def get_verifier(verify, verify_re): '+' 'X' '

'), - '\\sphinxkeyboard{\\sphinxupquote{Control+X}}', + '\\sphinxAtStartPar\n\\sphinxkeyboard{\\sphinxupquote{Control+X}}', ), ( # kbd role @@ -260,7 +267,8 @@ def get_verifier(verify, verify_re): '+' '^' '

'), - '\\sphinxkeyboard{\\sphinxupquote{Alt+\\textasciicircum{}}}', + ('\\sphinxAtStartPar\n' + '\\sphinxkeyboard{\\sphinxupquote{Alt+\\textasciicircum{}}}'), ), ( # kbd role @@ -275,21 +283,24 @@ def get_verifier(verify, verify_re): '-' 's' '

'), - '\\sphinxkeyboard{\\sphinxupquote{M\\sphinxhyphen{}x M\\sphinxhyphen{}s}}', + ('\\sphinxAtStartPar\n' + '\\sphinxkeyboard{\\sphinxupquote{M\\sphinxhyphen{}x M\\sphinxhyphen{}s}}'), ), ( # kbd role 'verify', ':kbd:`-`', '

-

', - '\\sphinxkeyboard{\\sphinxupquote{\\sphinxhyphen{}}}', + ('\\sphinxAtStartPar\n' + '\\sphinxkeyboard{\\sphinxupquote{\\sphinxhyphen{}}}'), ), ( # kbd role 'verify', ':kbd:`Caps Lock`', '

Caps Lock

', - '\\sphinxkeyboard{\\sphinxupquote{Caps Lock}}', + ('\\sphinxAtStartPar\n' + '\\sphinxkeyboard{\\sphinxupquote{Caps Lock}}'), ), ( # non-interpolation of dashes in option role @@ -297,14 +308,15 @@ def get_verifier(verify, verify_re): ':option:`--with-option`', ('

' '--with-option

$'), - r'\\sphinxcode{\\sphinxupquote{\\sphinxhyphen{}\\sphinxhyphen{}with\\sphinxhyphen{}option}}$', + (r'\\sphinxAtStartPar\n' + r'\\sphinxcode{\\sphinxupquote{\\sphinxhyphen{}\\sphinxhyphen{}with\\sphinxhyphen{}option}}$'), ), ( # verify smarty-pants quotes 'verify', '"John"', '

“John”

', - "“John”", + "\\sphinxAtStartPar\n“John”", ), ( # ... but not in literal text @@ -312,21 +324,21 @@ def get_verifier(verify, verify_re): '``"John"``', ('

' '"John"

'), - '\\sphinxcode{\\sphinxupquote{"John"}}', + '\\sphinxAtStartPar\n\\sphinxcode{\\sphinxupquote{"John"}}', ), ( # verify classes for inline roles 'verify', ':manpage:`mp(1)`', '

mp(1)

', - '\\sphinxstyleliteralemphasis{\\sphinxupquote{mp(1)}}', + '\\sphinxAtStartPar\n\\sphinxstyleliteralemphasis{\\sphinxupquote{mp(1)}}', ), ( # correct escaping in normal mode 'verify', 'Γ\\\\∞$', None, - 'Γ\\textbackslash{}\\(\\infty\\)\\$', + '\\sphinxAtStartPar\nΓ\\textbackslash{}\\(\\infty\\)\\$', ), ( # in verbatim code fragments @@ -342,7 +354,7 @@ def get_verifier(verify, verify_re): 'verify_re', '`test `_', None, - r'\\sphinxhref{https://www.google.com/~me/}{test}.*', + r'\\sphinxAtStartPar\n\\sphinxhref{https://www.google.com/~me/}{test}.*', ), ( # description list: simple