mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Enable pdf hyperlinks to named literal-blocks without caption.
This is tango between latex.py and sphinx.sty to handle PDF hyperlinks to literal-blocks (both code-block and literalinclude) either with name or caption (then numref can be used) or both. modified: sphinx/texinputs/sphinx.sty modified: sphinx/writers/latex.py This test file is now back to original. modified: tests/test_directive_code.py
This commit is contained in:
@@ -186,8 +186,11 @@
|
||||
\newcommand*\SphinxVerbatimTitle {}
|
||||
\newcommand*\SphinxSetupCaptionForVerbatim [2]
|
||||
{%
|
||||
\def\SphinxVerbatimTitle{\captionof{#1}{#2}\smallskip }%
|
||||
\needspace{\literalblockneedspace}\vspace{\literalblockcaptiontopvspace}%
|
||||
\def\SphinxVerbatimTitle
|
||||
{\captionof{#1}{\SphinxLiteralBlockLabel #2}\smallskip }%
|
||||
}
|
||||
\newcommand*\SphinxLiteralBlockLabel {}
|
||||
|
||||
% \SphinxCustomFBox is copied from framed.sty's \CustomFBox, but
|
||||
% #1=title/caption is to be set _above_ the top rule, not _below_
|
||||
@@ -246,6 +249,16 @@
|
||||
\bgroup\parskip\z@skip
|
||||
\smallskip
|
||||
% use customized framed environment
|
||||
% first, check if has caption
|
||||
\ifx\SphinxVerbatimTitle\empty
|
||||
% no caption. Require space if at bottom of page
|
||||
\needspace{\literalblockwithoutcaptionneedspace}%
|
||||
% if there is a label insert hypertarget.
|
||||
\ifx\SphinxLiteralBlockLabel\empty\else
|
||||
\phantomsection\SphinxLiteralBlockLabel
|
||||
\fi
|
||||
\fi
|
||||
% non empty \SphinxVerbatimTitle has label inside if there is one.
|
||||
\let\SphinxFrameTitle\SphinxVerbatimTitle
|
||||
\global\Sphinx@myfirstframedpasstrue
|
||||
% The list environement is needed to control perfectly the vertical
|
||||
@@ -625,5 +638,6 @@
|
||||
\RequirePackage{needspace}
|
||||
% if the left page space is less than \literalblockneedsapce, insert page-break
|
||||
\newcommand{\literalblockneedspace}{5\baselineskip}
|
||||
\newcommand{\literalblockwithoutcaptionneedspace}{1.5\baselineskip}
|
||||
% margin before the caption of literal-block
|
||||
\newcommand{\literalblockcaptiontopvspace}{0.5\baselineskip}
|
||||
|
||||
@@ -1443,10 +1443,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
def visit_caption(self, node):
|
||||
self.in_caption += 1
|
||||
if self.in_container_literal_block:
|
||||
self.body.append('\\needspace{\\literalblockneedspace}')
|
||||
self.body.append('\\vspace{\\literalblockcaptiontopvspace}\n')
|
||||
self.body.append('\\SphinxSetupCaptionForVerbatim{literal-block}{'
|
||||
'' + self.context.pop())
|
||||
self.body.append('\\SphinxSetupCaptionForVerbatim{literal-block}{')
|
||||
elif self.in_minipage and isinstance(node.parent, nodes.figure):
|
||||
self.body.append('\\captionof{figure}{')
|
||||
else:
|
||||
@@ -1801,6 +1798,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
# most probably a parsed-literal block -- don't highlight
|
||||
self.body.append('\\begin{alltt}\n')
|
||||
else:
|
||||
ids = ''
|
||||
for id in self.pop_hyperlink_ids('code-block'):
|
||||
ids += self.hypertarget(id, anchor=False)
|
||||
if node['ids']:
|
||||
# suppress with anchor=False \phantomsection insertion
|
||||
ids += self.hypertarget(node['ids'][0], anchor=False)
|
||||
# define label for use in caption, or directly if none exist.
|
||||
# LaTeX code will add the \phantomsection in latter case.
|
||||
if ids:
|
||||
self.body.append('\n\\def\\SphinxLiteralBlockLabel{' + ids + '}')
|
||||
code = node.astext()
|
||||
lang = self.hlsettingstack[-1][0]
|
||||
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
|
||||
@@ -1834,6 +1841,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
|
||||
self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
|
||||
(self.table and 'Original' or ''))
|
||||
if ids:
|
||||
self.body.append('\\let\\SphinxLiteralBlockLabel\empty\n')
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_literal_block(self, node):
|
||||
@@ -1992,15 +2001,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
for id in self.pop_hyperlink_ids('code-block'):
|
||||
ids += self.hypertarget(id, anchor=False)
|
||||
if node['ids']:
|
||||
# suppress with anchor=False \phantomsection generation
|
||||
# suppress with anchor=False \phantomsection insertion
|
||||
ids += self.hypertarget(node['ids'][0], anchor=False)
|
||||
self.body.append('\n')
|
||||
# context.pop will be done in visit_caption
|
||||
self.context.append(ids)
|
||||
# define label for use in caption.
|
||||
if ids:
|
||||
self.body.append('\n\\def\\SphinxLiteralBlockLabel{' + ids + '}\n')
|
||||
|
||||
def depart_container(self, node):
|
||||
if node.get('literal_block'):
|
||||
self.in_container_literal_block -= 1
|
||||
self.body.append('\\let\\SphinxLiteralBlockLabel\\empty\n')
|
||||
|
||||
def visit_decoration(self, node):
|
||||
pass
|
||||
|
||||
@@ -64,7 +64,7 @@ def test_code_block_caption_html(app, status, warning):
|
||||
def test_code_block_caption_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{\label{caption:caption-test-rb}caption \\emph{test} rb}'
|
||||
caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{caption \\emph{test} rb}'
|
||||
assert caption in latex
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ def test_literalinclude_caption_html(app, status, warning):
|
||||
def test_literalinclude_caption_latex(app, status, warning):
|
||||
app.builder.build('index')
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8')
|
||||
caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{\label{caption:caption-test-py}caption \\textbf{test} py}'
|
||||
caption = '\\SphinxSetupCaptionForVerbatim{literal-block}{caption \\textbf{test} py}'
|
||||
assert caption in latex
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user