More robust hyperlink macros in LaTeX output (refs #3317, #3340, #3533) (#3538)

More robust hyperlink macros in LaTeX output (refs #3317, #3340, #3533)
This commit is contained in:
Jean-François B 2017-03-11 16:53:53 +01:00 committed by GitHub
parent 448dc08924
commit 3128a4327d
4 changed files with 45 additions and 45 deletions

View File

@ -287,7 +287,7 @@
\fi
% fix a space-gobbling issue due to LaTeX's original \do@noligs
\let\do@noligs\sphinx@do@noligs
\@noligs\endlinechar\m@ne\everyeof{\noexpand}%
\@noligs\endlinechar\m@ne
\expandafter\scantokens
\fi {\texttt{#1}}}}
\def\sphinx@do@noligs #1{\catcode`#1\active\begingroup\lccode`\~`#1\relax
@ -592,22 +592,6 @@
\newcommand*\sphinxbreaksatspaceinparsedliteral{%
\lccode`~32 \lowercase{\let~}\spx@verbatim@space\lccode`\~`\~
}
% now the hack for \url to work (hyperref is assumed in use):
% the aim it to deactivate - . , ; ? ! / in \url's argument.
% also the space token, but not end of lines which we assume don't arise there.
\def\spx@hack@hyper@normalise {%
\expandafter\spx@hack@hyper@normalise@aux\hyper@normalise
\spx@hack@hyper@normalise@aux\hyper@n@rmalise\relax\spx@undefined
}%
\long\def\spx@hack@hyper@normalise@aux#1\hyper@n@rmalise#2#3\spx@undefined{%
\ifx\spx@hack@hyper@normalise@aux#2%
\def\hyper@normalise{#1\sphinxunactivateextrasandspace\hyper@n@rmalise}%
\else
\PackageWarning{sphinx}{Could not patch \string\url\space command.%
^^J Not using extra active characters in alltt environment}%
\sphinxunactivateextras
\fi
}%
\newcommand*{\sphinxunactivateextras}{\let\do\@makeother
\sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}%
% the \catcode13=5\relax (deactivate end of input lines) is left to callers
@ -623,17 +607,33 @@
\sphinxbreaksattexescapedchars
\sphinxbreaksviaactiveinparsedliteral
\sphinxbreaksatspaceinparsedliteral
\spx@hack@hyper@normalise
% alltt takes care of the ' as derivative ("prime") in math mode
\everymath\expandafter{\the\everymath\sphinxunactivateextrasandspace
\catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }%
% not sure if displayed math (align,...) can end up in parsed-literal, anyway
\everydisplay\expandafter{\the\everydisplay
\catcode13=5\sphinxunactivateextrasandspace
\catcode13=5 \sphinxunactivateextrasandspace
\catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }%
\fi }
{\end{alltt}}
% Protect \href's first argument in contexts such as sphinxalltt (or
% \sphinxcode). Sphinx uses \#, \%, \& ... always inside \sphinxhref.
\protected\def\sphinxhref#1#2{{%
\sphinxunactivateextrasandspace % never do \scantokens with active space!
\endlinechar\m@ne\everyeof{{#2}}% keep catcode regime for #2
\scantokens{\href{#1}}% normalise it for #1 during \href expansion
}}
% Same for \url. And also \nolinkurl for coherence.
\protected\def\sphinxurl#1{{%
\sphinxunactivateextrasandspace
\endlinechar\m@ne\scantokens{\url{#1}}%
}}
\protected\def\sphinxnolinkurl#1{{%
\sphinxunactivateextrasandspace
\endlinechar\m@ne\scantokens{\nolinkurl{#1}}%
}}
% Topic boxes
% Again based on use of "framed.sty", this allows breakable framed boxes.

View File

@ -1755,12 +1755,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
elif uri.startswith(URI_SCHEMES):
if len(node) == 1 and uri == node[0]:
if node.get('nolinkurl'):
self.body.append('\\nolinkurl{%s}' % self.encode_uri(uri))
self.body.append('\\sphinxnolinkurl{%s}' % self.encode_uri(uri))
else:
self.body.append('\\url{%s}' % self.encode_uri(uri))
self.body.append('\\sphinxurl{%s}' % self.encode_uri(uri))
raise nodes.SkipNode
else:
self.body.append('\\href{%s}{' % self.encode_uri(uri))
self.body.append('\\sphinxhref{%s}{' % self.encode_uri(uri))
self.context.append('}')
elif uri.startswith('#'):
# references to labels in the same document

View File

@ -551,20 +551,20 @@ def test_latex_show_urls_is_inline(app, status, warning):
'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result
assert '\\href{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde} '
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx-doc.org/\\textasciitilde{}test/)') in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term} '
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[5]}] '
'\\leavevmode%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\nDescription') in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist} '
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription') in result
assert '\\url{https://github.com/sphinx-doc/sphinx}\n' in result
assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
assert '\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}') in result
@ -594,29 +594,29 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result
assert ('\\href{http://sphinx-doc.org/}{Sphinx}'
assert ('\\sphinxhref{http://sphinx-doc.org/}{Sphinx}'
'%\n\\begin{footnote}[4]\\sphinxAtStartFootnote\n'
'\\nolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result
assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
assert ('\\href{http://sphinx-doc.org/~test/}{URL including tilde}'
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}'
'%\n\\begin{footnote}[5]\\sphinxAtStartFootnote\n'
'\\nolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\href{http://sphinx-doc.org/}'
'\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[8]}] '
'\\leavevmode%\n\\begin{footnotetext}[8]\\sphinxAtStartFootnote\n'
'\\nolinkurl{http://sphinx-doc.org/}\n%\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[10]}] '
'\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\nDescription') in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}'
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}'
'\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
'\\nolinkurl{http://sphinx-doc.org/}\n%\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\nDescription') in result
assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}\n') in result
@ -646,19 +646,19 @@ def test_latex_show_urls_is_no(app, status, warning):
'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result
assert '\\href{http://sphinx-doc.org/}{Sphinx}' in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
assert '\\href{http://sphinx-doc.org/~test/}{URL including tilde}' in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{URL in term}}] '
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
assert ('\\item[{Footnote in term \\sphinxfootnotemark[5]}] '
'\\leavevmode%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\nDescription') in result
assert ('\\item[{\\href{http://sphinx-doc.org/}{Term in deflist}}] '
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] '
'\\leavevmode\nDescription') in result
assert ('\\url{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\href{mailto:sphinx-dev@googlegroups.com}'
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}\n') in result

View File

@ -217,7 +217,7 @@ def get_verifier(verify, verify_re):
'verify_re',
u'`test <http://example.com/~me/>`_',
None,
r'\\href{http://example.com/~me/}{test}.*',
r'\\sphinxhref{http://example.com/~me/}{test}.*',
),
])
def test_inline(get_verifier, type, rst, html_expected, latex_expected):