LaTeX: avoid quotes and TeX ligature replacements in PDF output

Refs: #6890

The comma character is not TeX-escaped because it is frequent in general
text and escaping it would make the LaTeX output larger for only dealing
with the problem of the LaTeX-ligature of ,, into a single character.
And one there is problem with the commas in options to Verbatim from
PygmentsBridge.

The hyphen character is escaped (not in ids and URIs!) to
\sphinxhyphen{} for both Unicode and non-Unicode engines. This is needed
to work around hyperref transforming -- and --- from section titles into
EN DASH resp. EM DASH in PDF bookmarks.

https://github.com/latex3/hyperref/issues/112

Note to expert LaTeX users: if Sphinx latex user with xelatex has

- turned off Smart Quotes for some reason,

- but does want TeX ligatures and thus overrode Sphinx
latex_elements['fontenc'] default (since #6888) to this effect,

then this should be added to LaTeX preamble:

    \def\sphinxhyphen#1{-}% (\protected is now not needed)
    \let\sphinxhyphenforbookmarks\sphinxhyphen
This commit is contained in:
jfbu 2019-12-05 18:19:38 +01:00
parent 2ec6ce85ef
commit 30b26dd6a1
30 changed files with 227 additions and 178 deletions

View File

@ -51,6 +51,11 @@ The following is a list of deprecated interfaces.
- 4.0
- ``sphinx.util.texescape.hlescape()``
* - ``sphinx.writers.latex.LaTeXTranslator.no_contractions``
- 2.3
- 4.0
- N/A
* - ``sphinx.domains.math.MathDomain.add_equation()``
- 2.2
- 4.0

View File

@ -193,6 +193,7 @@ class PygmentsBridge:
if self.dest == 'html':
return hlsource
else:
# MEMO: this is done to escape Unicode chars with non-Unicode engines
return texescape.hlescape(hlsource, self.latex_engine)
def get_stylesheet(self):

View File

@ -1078,7 +1078,7 @@
}
\def\sphinx@verbatim@nolig@list {\do \`}%
% Some characters . , ; ? ! / are not pygmentized.
% Some characters . , ; ? ! / are neither pygmentized nor "tex-escaped".
% This macro makes them "active" and they will insert potential linebreaks.
% Not compatible with math mode (cf \sphinxunactivateextras).
\newcommand*\sphinxbreaksbeforeactivelist {}% none
@ -1369,7 +1369,6 @@
}
\newcommand*\sphinxbreaksviaactiveinparsedliteral{%
\sphinxbreaksviaactive % by default handles . , ; ? ! /
\do\-% we need also the hyphen character (ends up "as is" in parsed-literal)
\lccode`\~`\~ %
% update \dospecials as it is used by \url
% but deactivation will already have been done hence this is unneeded:
@ -1380,7 +1379,7 @@
\lccode`~32 \lowercase{\let~}\spx@verbatim@space\lccode`\~`\~
}
\newcommand*{\sphinxunactivateextras}{\let\do\@makeother
\sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}%
\sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist}%
% the \catcode13=5\relax (deactivate end of input lines) is left to callers
\newcommand*{\sphinxunactivateextrasandspace}{\catcode32=10\relax
\sphinxunactivateextras}%
@ -1805,12 +1804,20 @@
% break also at \
\let\sphinx@textbackslash\textbackslash
\let\textbackslash\sphinxtextbackslash
% do not typeset a continuation symbol on next line
% by default, no continuation symbol on next line but may be added
\let\sphinxafterbreak\sphinxafterbreakofinlineliteral
% do not overwrite the comma set-up
\let\verbatim@nolig@list\sphinx@literal@nolig@list
\fi
% fix a space-gobbling issue due to LaTeX's original \do@noligs
% TODO: using \@noligs as patched by upquote.sty is now unneeded because
% either ` and ' are escaped (non-unicode engines) or they don't build
% ligatures (unicode engines). Thus remove this and unify handling of `, <, >,
% ' and - with the characters . , ; ? ! / as handled via
% \sphinxbreaksviaactive.
% Hence \sphinx@do@noligs will be removed, or rather replaced with code
% inserting discretionaries, as they allow a continuation symbol on start of
% next line to achieve common design with code-blocks.
\let\do@noligs\sphinx@do@noligs
\@noligs\endlinechar\m@ne\everyeof{}% (<- in case inside \sphinxhref)
\expandafter\scantokens
@ -1866,6 +1873,7 @@
% reduce hyperref "Token not allowed in a PDF string" warnings on PDF builds
\AtBeginDocument{\pdfstringdefDisableCommands{%
% all "protected" macros possibly ending up in section titles should be here
% TODO: examine if \sphinxhref, \sphinxurl, \sphinnolinkurl should be handled
\let\sphinxstyleemphasis \@firstofone
\let\sphinxstyleliteralemphasis \@firstofone
\let\sphinxstylestrong \@firstofone
@ -1879,8 +1887,20 @@
\let\sphinxemail \@firstofone
\let\sphinxcrossref \@firstofone
\let\sphinxtermref \@firstofone
\let\sphinxhyphen\sphinxhyphenforbookmarks
}}
% Special characters
%
% This definition prevents en-dash and em-dash TeX ligatures.
%
% It inserts a potential breakpoint after the hyphen. This is to keep in sync
% with behavior in code-blocks, parsed and inline literals. For a breakpoint
% before the hyphen use \leavevmode\kern\z@- (within \makeatletter/\makeatother)
\protected\def\sphinxhyphen#1{-\kern\z@}
% The {} from texescape mark-up is kept, else -- gives en-dash in PDF bookmark
\def\sphinxhyphenforbookmarks{-}
% For curly braces inside \index macro
\def\sphinxleftcurlybrace{\{}
\def\sphinxrightcurlybrace{\}}

View File

@ -112,12 +112,14 @@
(merge-rule "\_" "_" :string)
(merge-rule "{[}" "[" :string)
(merge-rule "{]}" "]" :string)
(merge-rule "{}`" "`" :string)
(merge-rule "\textbackslash{}" "\" :string) ; " for Emacs syntax highlighting
(merge-rule "\textasciitilde{}" "~~" :string); the ~~ escape is needed here
(merge-rule "\textasciicircum{}" "^" :string)
(merge-rule "\sphinxhyphen{}" "-" :string)
(merge-rule "\textquotesingle{}" "'" :string)
(merge-rule "\textasciigrave{}" "`" :string)
(merge-rule "\textless{}" "<" :string)
(merge-rule "\textgreater{}" ">" :string)
(merge-rule "\textasciicircum{}" "^" :string)
(merge-rule "\P{}" "¶" :string)
(merge-rule "\S{}" "§" :string)
(merge-rule "\texteuro{}" "€" :string)

View File

@ -29,12 +29,6 @@ tex_replacements = [
# map chars to avoid mis-interpretation in LaTeX
('[', r'{[}'),
(']', r'{]}'),
# map chars to avoid TeX ligatures
# 1. ' - and , not here for some legacy reason
# 2. no effect with lualatex (done otherwise: #5790)
('`', r'{}`'),
('<', r'\textless{}'),
('>', r'\textgreater{}'),
# map special Unicode characters to TeX commands
('', r'\(\checkmark\)'),
('', r'\(\pmb{\checkmark}\)'),
@ -49,6 +43,23 @@ tex_replacements = [
# OHM SIGN U+2126 is handled by LaTeX textcomp package
]
# A map to avoid TeX ligatures or character replacements in PDF output
# xelatex/lualatex/uplatex are handled differently (#5790, #6888)
ascii_tex_replacements = [
# Note: the " renders curly in OT1 encoding but straight in T1, T2A, LY1...
# escaping it to \textquotedbl would break documents using OT1
# Sphinx does \shorthandoff{"} to avoid problems with some languages
# There is no \text... LaTeX escape for the hyphen character -
('-', r'\sphinxhyphen{}'), # -- and --- are TeX ligatures
# ,, is a TeX ligature in T1 encoding, but escaping the comma adds
# complications (whether by {}, or a macro) and is not done
# the next two require textcomp package
("'", r'\textquotesingle{}'), # else ' renders curly, and '' is a ligature
('`', r'\textasciigrave{}'), # else \` and \`\` render curly
('<', r'\textless{}'), # < is inv. exclam in OT1, << is a T1-ligature
('>', r'\textgreater{}'), # > is inv. quest. mark in 0T1, >> a T1-ligature
]
# A map Unicode characters to LaTeX representation
# (for LaTeX engines which don't support unicode)
unicode_tex_replacements = [
@ -85,6 +96,11 @@ unicode_tex_replacements = [
('', r'\(\sb{\text{9}}\)'),
]
# TODO: this should be called tex_idescape_map because its only use is in
# sphinx.writers.latex.LaTeXTranslator.idescape()
# %, {, }, \, #, and ~ are the only ones which must be replaced by _ character
# It would be simpler to define it entirely here rather than in init().
# Unicode replacements are superfluous, as idescape() uses backslashreplace
tex_replace_map = {} # type: Dict[int, str]
_tex_escape_map = {} # type: Dict[int, str]
@ -130,8 +146,17 @@ def init() -> None:
_tex_escape_map_without_unicode[ord(a)] = b
tex_replace_map[ord(a)] = '_'
# no reason to do this for _tex_escape_map_without_unicode
for a, b in ascii_tex_replacements:
_tex_escape_map[ord(a)] = b
# but the hyphen has a specific PDF bookmark problem
# https://github.com/latex3/hyperref/issues/112
_tex_escape_map_without_unicode[ord('-')] = r'\sphinxhyphen{}'
for a, b in unicode_tex_replacements:
_tex_escape_map[ord(a)] = b
# This is actually unneeded:
tex_replace_map[ord(a)] = '_'
for a, b in tex_replacements:

View File

@ -488,7 +488,6 @@ class LaTeXTranslator(SphinxTranslator):
self.first_document = 1
self.this_is_the_title = 1
self.literal_whitespace = 0
self.no_contractions = 0
self.in_parsed_literal = 0
self.compact_list = 0
self.first_param = 0
@ -992,13 +991,11 @@ class LaTeXTranslator(SphinxTranslator):
def visit_desc_name(self, node: Element) -> None:
self.body.append(r'\sphinxbfcode{\sphinxupquote{')
self.no_contractions += 1
self.literal_whitespace += 1
def depart_desc_name(self, node: Element) -> None:
self.body.append('}}')
self.literal_whitespace -= 1
self.no_contractions -= 1
def visit_desc_parameterlist(self, node: Element) -> None:
# close name, open parameterlist
@ -1844,11 +1841,9 @@ class LaTeXTranslator(SphinxTranslator):
def visit_literal_emphasis(self, node: Element) -> None:
self.body.append(r'\sphinxstyleliteralemphasis{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_emphasis(self, node: Element) -> None:
self.body.append('}}')
self.no_contractions -= 1
def visit_strong(self, node: Element) -> None:
self.body.append(r'\sphinxstylestrong{')
@ -1858,11 +1853,9 @@ class LaTeXTranslator(SphinxTranslator):
def visit_literal_strong(self, node: Element) -> None:
self.body.append(r'\sphinxstyleliteralstrong{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_strong(self, node: Element) -> None:
self.body.append('}}')
self.no_contractions -= 1
def visit_abbreviation(self, node: Element) -> None:
abbr = node.astext()
@ -1922,14 +1915,12 @@ class LaTeXTranslator(SphinxTranslator):
pass
def visit_literal(self, node: Element) -> None:
self.no_contractions += 1
if self.in_title:
self.body.append(r'\sphinxstyleliteralintitle{\sphinxupquote{')
else:
self.body.append(r'\sphinxcode{\sphinxupquote{')
def depart_literal(self, node: Element) -> None:
self.no_contractions -= 1
self.body.append('}}')
def visit_footnote_reference(self, node: Element) -> None:
@ -2103,9 +2094,7 @@ class LaTeXTranslator(SphinxTranslator):
def visit_option_string(self, node: Element) -> None:
ostring = node.astext()
self.no_contractions += 1
self.body.append(self.encode(ostring))
self.no_contractions -= 1
raise nodes.SkipNode
def visit_description(self, node: Element) -> None:
@ -2189,14 +2178,15 @@ class LaTeXTranslator(SphinxTranslator):
# Insert a blank before the newline, to avoid
# ! LaTeX Error: There's no line here to end.
text = text.replace('\n', '~\\\\\n').replace(' ', '~')
if self.no_contractions:
text = text.replace('--', '-{-}')
text = text.replace("''", "'{'}")
return text
def encode_uri(self, text: str) -> str:
# TODO: it is probably wrong that this uses texescape.escape()
# this must be checked against hyperref package exact dealings
# mainly, %, #, {, } and \ need escaping via a \ escape
# in \href, the tilde is allowed and must be represented literally
return self.encode(text).replace('\\textasciitilde{}', '~')
return self.encode(text).replace('\\textasciitilde{}', '~').\
replace('\\sphinxhyphen{}', '-')
def visit_Text(self, node: Text) -> None:
text = self.encode(node.astext())
@ -2285,6 +2275,12 @@ class LaTeXTranslator(SphinxTranslator):
fnotes[num] = [newnode, False]
return fnotes
@property
def no_contractions(self) -> int:
warnings.warn('LaTeXTranslator.no_contractions is deprecated.',
RemovedInSphinx40Warning, stacklevel=2)
return 0
@property
def footnotestack(self) -> List[Dict[str, List[Union[collected_footnote, bool]]]]:
warnings.warn('LaTeXWriter.footnotestack is deprecated.',

View File

@ -2,10 +2,10 @@
table having …
\begin{itemize}
\item {}
consecutive multirow at top of row (1-1 and 1-2)
consecutive multirow at top of row (1\sphinxhyphen{}1 and 1\sphinxhyphen{}2)
\item {}
consecutive multirow at end of row (1-4 and 1-5)
consecutive multirow at end of row (1\sphinxhyphen{}4 and 1\sphinxhyphen{}5)
\end{itemize}
@ -16,40 +16,40 @@ consecutive multirow at end of row (1-4 and 1-5)
\hline
\sphinxmultirow{3}{1}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
cell1-1
cell1\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxmultirow{3}{2}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
cell1-2
cell1\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&
cell1-3
cell1\sphinxhyphen{}3
&\sphinxmultirow{3}{4}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
cell1-4
cell1\sphinxhyphen{}4
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxmultirow{2}{5}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
cell1-5
cell1\sphinxhyphen{}5
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
\\
\cline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
cell2-3
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}&
cell3-5
cell3\sphinxhyphen{}5
\\
\hline
\end{tabulary}

View File

@ -12,40 +12,40 @@ header2
header3
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&\sphinxmultirow{2}{5}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
cell1-2
cell1\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&
cell1-3
cell1\sphinxhyphen{}3
\\
\cline{1-1}\cline{3-3}\sphinxmultirow{2}{7}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
cell2-1
cell2\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxtablestrut{5}&
cell2-3
cell2\sphinxhyphen{}3
\\
\cline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}%
\sphinxmultirow{2}{9}{%
\begin{varwidth}[t]{\sphinxcolwidth{2}{3}}
cell3-2
cell3\sphinxhyphen{}2
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
\sphinxstopmulticolumn
\\
\cline{1-1}
cell4-1
cell4\sphinxhyphen{}1
&\multicolumn{2}{l|}{\sphinxtablestrut{9}}\\
\hline\sphinxstartmulticolumn{3}%
\begin{varwidth}[t]{\sphinxcolwidth{3}{3}}
cell5-1
cell5\sphinxhyphen{}1
\par
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
\sphinxstopmulticolumn

View File

@ -27,19 +27,19 @@ header2
\endlastfoot
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -27,19 +27,19 @@ header2
\endlastfoot
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -29,19 +29,19 @@ header2
\endlastfoot
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -35,17 +35,17 @@ item2
\end{itemize}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -32,23 +32,23 @@ header3
\endlastfoot
\sphinxstyletheadfamily \begin{itemize}
\item {}
instub1-1a
instub1\sphinxhyphen{}1a
\item {}
instub1-1b
instub1\sphinxhyphen{}1b
\end{itemize}
&\sphinxstyletheadfamily
instub1-2
instub1\sphinxhyphen{}2
&
notinstub1-3
notinstub1\sphinxhyphen{}3
\\
\hline\sphinxstyletheadfamily
cell2-1
cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
cell2-2
cell2\sphinxhyphen{}2
&
cell2-3
cell2\sphinxhyphen{}3
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -31,17 +31,17 @@ header2
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -27,19 +27,19 @@ header2
\endlastfoot
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -35,17 +35,17 @@ item2
\end{itemize}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -27,19 +27,19 @@ header2
\endlastfoot
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{longtable}\sphinxatlongtableend\end{savenotes}

View File

@ -10,19 +10,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}

View File

@ -14,19 +14,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}

View File

@ -18,17 +18,17 @@ item2
\end{itemize}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}

View File

@ -13,23 +13,23 @@ header3
\\
\hline\sphinxstyletheadfamily \begin{itemize}
\item {}
instub1-1a
instub1\sphinxhyphen{}1a
\item {}
instub1-1b
instub1\sphinxhyphen{}1b
\end{itemize}
&\sphinxstyletheadfamily
instub1-2
instub1\sphinxhyphen{}2
&
notinstub1-3
notinstub1\sphinxhyphen{}3
\\
\hline\sphinxstyletheadfamily
cell2-1
cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
cell2-2
cell2\sphinxhyphen{}2
&
cell2-3
cell2\sphinxhyphen{}3
\\
\hline
\end{tabular}

View File

@ -8,11 +8,11 @@
header1
\\
\hline
cell1-1-par1
cell1\sphinxhyphen{}1\sphinxhyphen{}par1
cell1-1-par2
cell1\sphinxhyphen{}1\sphinxhyphen{}par2
cell1-1-par3
cell1\sphinxhyphen{}1\sphinxhyphen{}par3
\\
\hline
\end{tabulary}

View File

@ -14,17 +14,17 @@ header2
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}

View File

@ -11,19 +11,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}

View File

@ -18,17 +18,17 @@ item2
\end{itemize}
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}

View File

@ -10,19 +10,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabular}

View File

@ -10,19 +10,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}

View File

@ -10,19 +10,19 @@ header1
header2
\\
\hline
cell1-1
cell1\sphinxhyphen{}1
&
cell1-2
cell1\sphinxhyphen{}2
\\
\hline
cell2-1
cell2\sphinxhyphen{}1
&
cell2-2
cell2\sphinxhyphen{}2
\\
\hline
cell3-1
cell3\sphinxhyphen{}1
&
cell3-2
cell3\sphinxhyphen{}2
\\
\hline
\end{tabulary}

View File

@ -193,7 +193,7 @@ def test_latex_title_after_admonitions(app, status, warning):
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\title{test-latex-title}' in result
assert '\\title{test\\sphinxhyphen{}latex\\sphinxhyphen{}title}' in result
@pytest.mark.sphinx('latex', testroot='basic',
@ -227,7 +227,7 @@ def test_numref(app, status, warning):
assert ('\\hyperref[\\detokenize{index:code-1}]'
'{Listing \\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
'{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{Section \\ref{\\detokenize{foo:foo}}}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@ -273,13 +273,13 @@ def test_numref_with_prefix1(app, status, warning):
assert ('\\hyperref[\\detokenize{baz:table22}]'
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
assert ('\\hyperref[\\detokenize{index:code-1}]'
'{Code-\\ref{\\detokenize{index:code-1}}}') in result
'{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
'{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{SECTION-\\ref{\\detokenize{foo:foo}}}') in result
'{SECTION\\sphinxhyphen{}\\ref{\\detokenize{foo:foo}}}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
'{SECTION-\\ref{\\detokenize{bar:bar-a}}}') in result
'{SECTION\\sphinxhyphen{}\\ref{\\detokenize{bar:bar-a}}}') in result
assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} '
'\\nameref{\\detokenize{index:fig1}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} '
@ -314,10 +314,10 @@ def test_numref_with_prefix2(app, status, warning):
'{Tab\\_\\ref{\\detokenize{index:table-1}}:}') in result
assert ('\\hyperref[\\detokenize{baz:table22}]'
'{Table:\\ref{\\detokenize{baz:table22}}}') in result
assert ('\\hyperref[\\detokenize{index:code-1}]{Code-\\ref{\\detokenize{index:code-1}} '
assert ('\\hyperref[\\detokenize{index:code-1}]{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}} '
'| }') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
'{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{SECTION\\_\\ref{\\detokenize{foo:foo}}\\_}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@ -357,7 +357,7 @@ def test_numref_with_language_ja(app, status, warning):
assert ('\\hyperref[\\detokenize{index:code-1}]'
'{\u30ea\u30b9\u30c8 \\ref{\\detokenize{index:code-1}}}') in result
assert ('\\hyperref[\\detokenize{baz:code22}]'
'{Code-\\ref{\\detokenize{baz:code22}}}') in result
'{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result
assert ('\\hyperref[\\detokenize{foo:foo}]'
'{\\ref{\\detokenize{foo:foo}} \u7ae0}') in result
assert ('\\hyperref[\\detokenize{bar:bar-a}]'
@ -692,7 +692,7 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result
assert ('This is a reference to the code-block in the footnote:\n'
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'
@ -727,24 +727,24 @@ 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 '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx-doc.org/\\textasciitilde{}test/)') in result
'(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
'(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\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
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription') in result
'(http://sphinx\\sphinxhyphen{}doc.org/)}] \\leavevmode\nDescription') in result
assert '\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result
assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}'
'{sphinx-dev@googlegroups.com}') in result
'{sphinx\\sphinxhyphen{}dev@googlegroups.com}') in result
@pytest.mark.sphinx(
@ -798,7 +798,7 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'\\end{footnotetext}\\ignorespaces \nDescription') in result
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
'{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result
@pytest.mark.sphinx(
@ -841,7 +841,7 @@ def test_latex_show_urls_is_no(app, status, warning):
'\\leavevmode\nDescription') in result
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
'{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result
@pytest.mark.sphinx(
@ -1416,7 +1416,7 @@ def test_default_latex_documents():
config.init_values()
config.add('latex_engine', None, True, None)
expected = [('index', 'stasi.tex', 'STASI™ Documentation',
r"Wolfgang Schäuble \& G'Beckstein.\@{}", 'manual')]
r"Wolfgang Schäuble \& G\textquotesingle{}Beckstein.\@{}", 'manual')]
assert default_latex_documents(config) == expected

View File

@ -213,7 +213,7 @@ def get_verifier(verify, verify_re):
':menuselection:`&Foo -&&- &Bar`',
('<p><span class="menuselection"><span class="accelerator">F</span>oo '
'-&amp;- <span class="accelerator">B</span>ar</span></p>'),
r'\sphinxmenuselection{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}',
r'\sphinxmenuselection{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}',
),
(
# interpolation of ampersands in guilabel
@ -221,7 +221,7 @@ def get_verifier(verify, verify_re):
':guilabel:`&Foo -&&- &Bar`',
('<p><span class="guilabel"><span class="accelerator">F</span>oo '
'-&amp;- <span class="accelerator">B</span>ar</span></p>'),
r'\sphinxguilabel{\sphinxaccelerator{F}oo -\&- \sphinxaccelerator{B}ar}',
r'\sphinxguilabel{\sphinxaccelerator{F}oo \sphinxhyphen{}\&\sphinxhyphen{} \sphinxaccelerator{B}ar}',
),
(
# no ampersands in guilabel
@ -236,7 +236,7 @@ def get_verifier(verify, verify_re):
':option:`--with-option`',
('<p><code( class="xref std std-option docutils literal notranslate")?>'
'<span class="pre">--with-option</span></code></p>$'),
r'\\sphinxcode{\\sphinxupquote{-{-}with-option}}$',
r'\\sphinxcode{\\sphinxupquote{\\sphinxhyphen{}\\sphinxhyphen{}with\\sphinxhyphen{}option}}$',
),
(
# verify smarty-pants quotes