Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LaTeX: separate terms from their definitions by a CR (close #9985) #9999

Merged
merged 3 commits into from Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 36 additions & 2 deletions sphinx/texinputs/sphinxlatexlists.sty
@@ -1,13 +1,47 @@
%% ALPHANUMERIC LIST ITEMS
%
% change this info string if making any custom modification
\ProvidesFile{sphinxlatexlists.sty}[2021/01/27 lists]
\ProvidesFile{sphinxlatexlists.sty}[2021/12/20 lists]

% Provides support for this output mark-up from Sphinx latex writer:
% - \sphinxsetlistlabels

% - \sphinxlineitem
% and for the maxlistdepth key of sphinxsetup
% Dependencies: the \spx@opt@maxlistdepth from sphinx.sty

% We need some helpers macros
\newtoks\spx@lineitemlabel
\long\def\sphinx@gobto@sphinxlineitem#1\sphinxlineitem{}
% TeX/LaTeX has no (easy to use) built-in "peek-ahead" mechanism, but
% we would like to know if next token is another \sphinxlineitem (this
% can happen in glossary entries with multiple terms for same definition)
% so we simply grab next token (assuming it is not {tokens} originally)
\newcommand\sphinxlineitem[2]{%
% safe test of whether #2 is \sphinxlineitem
\sphinx@gobto@sphinxlineitem#2\@gobbletwo\sphinxlineitem\unless
\iftrue
% case with sphinxlineitem immediately followed by another \sphinxlineitem:
% accumulate successive terms until actual definition or sub-list is found
\spx@lineitemlabel\expandafter{\the\spx@lineitemlabel\strut#1\\}%
\else
% now issue the \item command with possibly multi-line contents
% these weird incantations with \kern are related to how LaTeX
% handles \item generally
\item[\kern\labelwidth\kern-\itemindent\kern-\leftmargin
{\parbox[t]{\dimexpr\linewidth+\leftmargin\relax}{%
\raggedright
\the\spx@lineitemlabel% accumulated terms before this one, CR separated
\strut#1}}% due to LaTeX internals no \par token allowed here,
% but the \parbox will insert one tacitly at end
\kern-\labelsep]%
\spx@lineitemlabel{}%
% this causes the label to be typeset (filling up the line), clearing up
% things in case a nested list follows.
\leavevmode
\fi #2%
}%


\newcommand\sphinxsetlistlabels[5]
{% #1 = style, #2 = enum, #3 = enumnext, #4 = prefix, #5 = suffix
% #2 and #3 are counters used by enumerate environment e.g. enumi, enumii.
Expand Down
4 changes: 2 additions & 2 deletions sphinx/writers/latex.py
Expand Up @@ -1092,8 +1092,8 @@ def visit_term(self, node: Element) -> None:
ctx = r'\phantomsection'
for node_id in node['ids']:
ctx += self.hypertarget(node_id, anchor=False)
ctx += r'}] \leavevmode'
self.body.append(r'\item[{')
ctx += r'}'
self.body.append(r'\sphinxlineitem{')
self.context.append(ctx)

def depart_term(self, node: Element) -> None:
Expand Down
72 changes: 36 additions & 36 deletions tests/test_build_latex.py
Expand Up @@ -834,18 +834,18 @@ def test_latex_show_urls_is_inline(app, status, warning):
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
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\n\\sphinxAtStartPar\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]'
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}{URL in term} '
'(http://sphinx\\sphinxhyphen{}doc.org/)}'
'\n\\sphinxAtStartPar\nDescription' in result)
assert ('\\sphinxlineitem{Footnote in term \\sphinxfootnotemark[6]}'
'%\n\\begin{footnotetext}[6]'
'\\phantomsection\\label{\\thesphinxscope.6}%\n'
'\\sphinxAtStartFootnote\n'
'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\n\\sphinxAtStartPar\nDescription') in result
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
'(http://sphinx\\sphinxhyphen{}doc.org/)}'
'\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
Expand Down Expand Up @@ -893,22 +893,22 @@ def test_latex_show_urls_is_footnote(app, status, warning):
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}'
'%\n\\begin{footnote}[5]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]'
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[9]}'
'%\n\\begin{footnotetext}[9]'
'\\phantomsection\\label{\\thesphinxscope.9}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] '
'\\leavevmode%\n\\begin{footnotetext}[11]'
assert ('\\sphinxlineitem{Footnote in term \\sphinxfootnotemark[11]}'
'%\n\\begin{footnotetext}[11]'
'\\phantomsection\\label{\\thesphinxscope.11}%\n'
'\\sphinxAtStartFootnote\n'
'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]'
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}'
'\\sphinxfootnotemark[10]}'
'%\n\\begin{footnotetext}[10]'
'\\phantomsection\\label{\\thesphinxscope.10}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
Expand Down Expand Up @@ -955,16 +955,16 @@ def test_latex_show_urls_is_no(app, status, warning):
'\\sphinxAtStartFootnote\n'
'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\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]'
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}'
'\n\\sphinxAtStartPar\nDescription') in result
assert ('\\sphinxlineitem{Footnote in term \\sphinxfootnotemark[6]}'
'%\n\\begin{footnotetext}[6]'
'\\phantomsection\\label{\\thesphinxscope.6}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] '
'\\leavevmode\n\\sphinxAtStartPar\nDescription') in result
assert ('\\sphinxlineitem{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}'
'\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
Expand Down Expand Up @@ -1454,23 +1454,23 @@ def test_latex_glossary(app, status, warning):
app.builder.build_all()

result = (app.outdir / 'python.tex').read_text()
assert ('\\item[{ähnlich\\index{ähnlich@\\spxentry{ähnlich}|spxpagem}'
assert (r'\sphinxlineitem{ähnlich\index{ähnlich@\spxentry{ähnlich}|spxpagem}'
r'\phantomsection'
r'\label{\detokenize{index:term-ahnlich}}}] \leavevmode' in result)
assert (r'\item[{boson\index{boson@\spxentry{boson}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-boson}}}] \leavevmode' in result)
assert (r'\item[{\sphinxstyleemphasis{fermion}'
r'\label{\detokenize{index:term-ahnlich}}}' in result)
assert (r'\sphinxlineitem{boson\index{boson@\spxentry{boson}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-boson}}}' in result)
assert (r'\sphinxlineitem{\sphinxstyleemphasis{fermion}'
r'\index{fermion@\spxentry{fermion}|spxpagem}'
r'\phantomsection'
r'\label{\detokenize{index:term-fermion}}}] \leavevmode' in result)
assert (r'\item[{tauon\index{tauon@\spxentry{tauon}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-tauon}}}] \leavevmode'
r'\item[{myon\index{myon@\spxentry{myon}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-myon}}}] \leavevmode'
r'\item[{electron\index{electron@\spxentry{electron}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-electron}}}] \leavevmode' in result)
assert ('\\item[{über\\index{über@\\spxentry{über}|spxpagem}\\phantomsection'
r'\label{\detokenize{index:term-uber}}}] \leavevmode' in result)
r'\label{\detokenize{index:term-fermion}}}' in result)
assert (r'\sphinxlineitem{tauon\index{tauon@\spxentry{tauon}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-tauon}}}'
r'\sphinxlineitem{myon\index{myon@\spxentry{myon}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-myon}}}'
r'\sphinxlineitem{electron\index{electron@\spxentry{electron}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-electron}}}' in result)
assert (r'\sphinxlineitem{über\index{über@\spxentry{über}|spxpagem}\phantomsection'
r'\label{\detokenize{index:term-uber}}}' in result)


@pytest.mark.sphinx('latex', testroot='latex-labels')
Expand Down