From 70f8d4ddfcd7ee0a1873ed5a9fbde283a74f818c Mon Sep 17 00:00:00 2001 From: jfbu Date: Sun, 10 Dec 2017 12:16:35 +0100 Subject: [PATCH] Support ``:emphasize-lines:`` in PDF output (closes #1238) --- doc/latex.rst | 5 +++++ doc/markup/code.rst | 3 +++ sphinx/texinputs/sphinx.sty | 18 +++++++++++++++++- sphinx/writers/latex.py | 3 +++ tests/roots/test-directive-code/emphasize.rst | 7 +++++++ .../expects/longtable_having_verbatim.tex | 1 + .../expects/table_having_verbatim.tex | 1 + tests/test_directive_code.py | 8 ++++++++ tests/test_markup.py | 3 ++- 9 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/roots/test-directive-code/emphasize.rst diff --git a/doc/latex.rst b/doc/latex.rst index 0cd91fa97..5c140d295 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -256,6 +256,11 @@ The available styling options ``VerbatimBorderColor`` default ``{rgb}{0,0,0}``. The frame color, defaults to black. +``VerbatimHighlightColor`` + default ``{rgb}{0.878,1,1}``. The color for highlighted lines. + + .. versionadded:: 1.6.6 + ``verbatimsep`` default ``\fboxsep``. The separation between code lines and the frame. diff --git a/doc/markup/code.rst b/doc/markup/code.rst index cb3e55bdc..9cb57129f 100644 --- a/doc/markup/code.rst +++ b/doc/markup/code.rst @@ -223,6 +223,9 @@ Includes .. versionchanged:: 1.6 With both ``start-after`` and ``lines`` in use, the first line as per ``start-after`` is considered to be with line number ``1`` for ``lines``. + .. versionchanged:: 1.6.6 + LaTeX supports the ``emphasize-lines`` option. + Caption and name ^^^^^^^^^^^^^^^^ diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 232a53b2f..b8412627b 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -159,6 +159,7 @@ % For highlighted code. \RequirePackage{fancyvrb} \fvset{fontsize=\small} +\define@key{FV}{hllines}{\def\sphinx@verbatim@checkifhl##1{\in@{, ##1,}{#1}}} % For hyperlinked footnotes in tables; also for gathering footnotes from % topic and warning blocks. Also to allow code-blocks in footnotes. \RequirePackage{footnotehyper-sphinx} @@ -299,6 +300,8 @@ \sphinxDeclareColorOption{OuterLinkColor}{{rgb}{0.216,0.439,0.388}} \sphinxDeclareColorOption{VerbatimColor}{{rgb}{1,1,1}} \sphinxDeclareColorOption{VerbatimBorderColor}{{rgb}{0,0,0}} +% also no prefix for this one, for consistency (sigh). Color as in minted! +\sphinxDeclareColorOption{VerbatimHighlightColor}{{rgb}{0.878,1,1}} % now the colours defined with "sphinx" prefix in their names \newcommand*{\sphinxDeclareSphinxColorOption}[2]{% % set the initial default @@ -886,11 +889,24 @@ \expandafter\def\expandafter\FV@SetupFont\expandafter {\FV@SetupFont\sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}% \sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}}% - \def\FancyVerbFormatLine ##1{\hsize\linewidth + \def\FancyVerbFormatLine ##1{% + \expandafter\sphinx@verbatim@checkifhl + \expandafter{\the\value{FancyVerbLine}}% + \edef\sphinx@restorefboxsep{\fboxsep\the\fboxsep\relax}% + \toks@{% + \hsize\linewidth \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@ \doublehyphendemerits\z@\finalhyphendemerits\z@ \strut ##1\strut}% }% + \ifin@ + \fboxsep0pt + \colorbox{VerbatimHighlightColor}{\sphinx@restorefboxsep\the\toks@}% + \sphinx@restorefboxsep + \else + \the\toks@ + \fi + }% \let\FV@Space\spx@verbatim@space % Allow breaks at special characters using \PYG... macros. \sphinxbreaksatspecials diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index df39c84fd..005f93a3d 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -2270,6 +2270,8 @@ class LaTeXTranslator(nodes.NodeVisitor): lang = self.hlsettingstack[-1][0] linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1 highlight_args = node.get('highlight_args', {}) + hllines = '\\fvset{hllines={, %s,}}%%' %\ + str(highlight_args.get('hl_lines', []))[1:-1] if 'language' in node: # code-block directives lang = node['language'] @@ -2308,6 +2310,7 @@ class LaTeXTranslator(nodes.NodeVisitor): hlcode += '\\end{sphinxVerbatimintable}' else: hlcode += '\\end{sphinxVerbatim}' + self.body.append('\n' + hllines) self.body.append('\n' + hlcode + '\n') if ids: self.body.append('\\let\\sphinxLiteralBlockLabel\\empty\n') diff --git a/tests/roots/test-directive-code/emphasize.rst b/tests/roots/test-directive-code/emphasize.rst new file mode 100644 index 000000000..95db574ce --- /dev/null +++ b/tests/roots/test-directive-code/emphasize.rst @@ -0,0 +1,7 @@ +Literal Includes with Highlighted Lines +======================================= + +.. literalinclude:: target.py + :language: python + :emphasize-lines: 5-6, 13-15, 24- + diff --git a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex index 979385785..7b4fb6964 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -27,6 +27,7 @@ header2 \endlastfoot +\fvset{hllines={, ,}}% \begin{sphinxVerbatimintable}[commandchars=\\\{\}] \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} diff --git a/tests/roots/test-latex-table/expects/table_having_verbatim.tex b/tests/roots/test-latex-table/expects/table_having_verbatim.tex index d8231817a..4a49e4cbb 100644 --- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex @@ -10,6 +10,7 @@ header1 header2 \unskip}\relax \\ \hline +\fvset{hllines={, ,}}% \begin{sphinxVerbatimintable}[commandchars=\\\{\}] \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py index 548a5d72c..e3069061b 100644 --- a/tests/test_directive_code.py +++ b/tests/test_directive_code.py @@ -349,6 +349,14 @@ def test_code_block_namedlink_latex(app, status, warning): assert link2 in latex +@pytest.mark.sphinx('latex', testroot='directive-code') +def test_code_block_emphasize_latex(app, status, warning): + app.builder.build(['emphasize']) + latex = (app.outdir / 'Python.tex').text(encoding='utf-8').replace('\r\n', '\n') + includes = '\\fvset{hllines={, 5, 6, 13, 14, 15, 24, 25, 26, 27,}}%\n' + assert includes in latex + + @pytest.mark.sphinx('xml', testroot='directive-code') def test_literal_include(app, status, warning): app.builder.build(['index']) diff --git a/tests/test_markup.py b/tests/test_markup.py index dfa4d74cf..9c41845fc 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -211,7 +211,8 @@ def get_verifier(verify, verify_re): 'verify', u'::\n\n @Γ\\∞${}', None, - (u'\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]\n' + (u'\\fvset{hllines={, ,}}%\n' + u'\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]\n' u'@\\(\\Gamma\\)\\PYGZbs{}\\(\\infty\\)\\PYGZdl{}\\PYGZob{}\\PYGZcb{}\n' u'\\end{sphinxVerbatim}'), ),