Skip to content

Commit 808177f

Browse files
committed
add emphasize-lines option to sphinx-execute directive
1 parent b14e20a commit 808177f

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

jupyter_sphinx/execute.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
import os
44
from itertools import groupby, count
5-
from operator import itemgetter
65
import json
76

8-
import sphinx
9-
from sphinx.util import logging
7+
from sphinx.util import logging, parselinenos
108
from sphinx.util.fileutil import copy_asset
119
from sphinx.transforms import SphinxTransform
1210
from sphinx.errors import ExtensionError
@@ -26,7 +24,6 @@
2624

2725
import nbformat
2826

29-
from ipywidgets import Widget
3027
import ipywidgets.embed
3128

3229
from ._version import __version__
@@ -136,6 +133,8 @@ class JupyterCell(Directive):
136133
If provided, the code will be shown below the cell output.
137134
linenos : bool
138135
If provided, the code will be shown with line numbering.
136+
emphasize-lines : comma separated list of line numbers
137+
If provided, the specified lines will be highlighted.
139138
raises : comma separated list of exception types
140139
If provided, a comma-separated list of exception type names that
141140
the cell may raise. If one of the listed execption types is raised
@@ -159,11 +158,14 @@ class JupyterCell(Directive):
159158
'hide-output': directives.flag,
160159
'code-below': directives.flag,
161160
'linenos': directives.flag,
161+
'emphasize-lines': directives.unchanged_required,
162162
'raises': csv_option,
163163
'stderr': directives.flag,
164164
}
165165

166166
def run(self):
167+
location = self.state_machine.get_source_and_line(self.lineno)
168+
167169
if self.arguments:
168170
# As per 'sphinx.directives.code.LiteralInclude'
169171
env = self.state.document.settings.env
@@ -172,7 +174,7 @@ def run(self):
172174
if self.content:
173175
logger.warning(
174176
'Ignoring inline code in Jupyter cell included from "{}"'
175-
.format(rel_filename)
177+
.format(rel_filename), location=location
176178
)
177179
try:
178180
with open(filename) as f:
@@ -194,8 +196,10 @@ def run(self):
194196
hide_output=('hide-output' in self.options),
195197
code_below=('code-below' in self.options),
196198
linenos=('linenos' in self.options),
199+
emphasize_lines=self.options.get('emphasize-lines'),
197200
raises=self.options.get('raises'),
198201
stderr=('stderr' in self.options),
202+
_location=location,
199203
)]
200204

201205

@@ -408,12 +412,26 @@ def apply(self):
408412
linenostart = 1
409413
for node in nodes:
410414
source = node.children[0]
415+
nlines = source.rawsource.count("\n") + 1
416+
411417
if linenos_config or continue_linenos or node["linenos"]:
412418
source["linenos"] = True
413-
if continue_linenos:
414-
source["highlight_args"] = {'linenostart': linenostart}
415-
linenostart += source.rawsource.count("\n") + 1
416419

420+
highlight_args = source['highlight_args'] = {}
421+
422+
if continue_linenos:
423+
highlight_args['linenostart'] = linenostart
424+
linenostart += nlines
425+
426+
emphasize_linespec = node['emphasize_lines']
427+
if emphasize_linespec:
428+
hl_lines = parselinenos(emphasize_linespec, nlines)
429+
if any(i >= nlines for i in hl_lines):
430+
logger.warning(
431+
'Line number spec is out of range(1-{}): {}'.format(
432+
nlines, emphasize_linespec), location=node['_location'])
433+
hl_lines = [i + 1 for i in hl_lines if i < nlines]
434+
highlight_args['hl_lines'] = hl_lines
417435

418436
# Add code cell CSS class
419437
for node in nodes:

tests/test_execute.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ def test_continue_linenos_conf_option(doctree):
180180
assert cell1.children[1].rawsource.strip() == "6"
181181

182182

183+
def test_emphasize_lines(doctree):
184+
source = '''
185+
.. jupyter-execute::
186+
:emphasize-lines: 1,3-5
187+
188+
1 + 1
189+
2 + 2
190+
3 + 3
191+
4 + 4
192+
5 + 5
193+
'''
194+
tree = doctree(source)
195+
cell, = tree.traverse(JupyterCellNode)
196+
assert cell.attributes['emphasize_lines'] == '1,3-5'
197+
198+
183199
def test_execution_environment_carries_over(doctree):
184200
source = '''
185201
.. jupyter-execute::

0 commit comments

Comments
 (0)