Skip to content

Commit

Permalink
Merge pull request #9999 from jfbu/9985_latex_on_master
Browse files Browse the repository at this point in the history
LaTeX: separate terms from their definitions by a CR (close #9985)
  • Loading branch information
jfbu committed Dec 23, 2021
2 parents 4e8bca2 + 559e4d3 commit 468384f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 40 deletions.
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

0 comments on commit 468384f

Please sign in to comment.