Skip to content

Commit e68d30f

Browse files
committed
added continue_linenos directive, doc updates, and tests
1 parent 693db1b commit e68d30f

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

doc/source/index.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,31 @@ produces:
193193
print('B')
194194
print('C')
195195

196+
You may also *continue line numbers* from the previous cell with ``:continue_linenos:``::
197+
198+
.. jupyter-execute::
199+
:linenos:
200+
201+
print('A')
202+
203+
.. jupyter-execute::
204+
:continue_linenos:
205+
206+
print('B')
207+
print('C')
208+
209+
produces:
210+
211+
.. jupyter-execute::
212+
:linenos:
213+
214+
print('A')
215+
216+
.. jupyter-execute::
217+
:continue_linenos:
218+
219+
print('B')
220+
print('C')
196221

197222
Controlling exceptions
198223
----------------------

jupyter_sphinx/execute.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class JupyterCell(Directive):
154154
'hide-output': directives.flag,
155155
'code-below': directives.flag,
156156
'linenos': directives.flag,
157+
'continue_linenos': directives.flag,
157158
'raises': csv_option,
158159
'stderr': directives.flag,
159160
}
@@ -189,6 +190,7 @@ def run(self):
189190
hide_output=('hide-output' in self.options),
190191
code_below=('code-below' in self.options),
191192
linenos=('linenos' in self.options),
193+
continue_linenos=('continue_linenos' in self.options),
192194
raises=self.options.get('raises'),
193195
stderr=('stderr' in self.options),
194196
)]
@@ -394,11 +396,23 @@ def apply(self):
394396
source = node.children[0]
395397
source.attributes['language'] = lexer
396398

397-
# Add line numbers
399+
# Add line numbers to code cells if linenos directive is set.
400+
# Continue line numbers from previous cell with line numbers
401+
# if continue_linenos directive is set.
402+
linenostart = 1
398403
for node in nodes:
399-
if node["linenos"]:
400-
source = node.children[0]
404+
source = node.children[0]
405+
if node["continue_linenos"]:
406+
source["linenos"] = True
407+
source["highlight_args"] = {'linenostart': linenostart}
408+
elif node["linenos"]:
409+
linenostart = 1
401410
source["linenos"] = True
411+
# Advance linenostart or reset it
412+
if node["continue_linenos"] or node["linenos"]:
413+
linenostart += len(source.rawsource.split("\n"))
414+
else:
415+
linenostart = 1
402416

403417
# Write certain cell outputs (e.g. images) to separate files, and
404418
# modify the metadata of the associated cells in 'notebook' to

tests/test_execute.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,90 @@ def test_linenos(doctree):
141141
assert cell.attributes['linenos'] is True
142142

143143

144+
def test_continue_linenos(doctree):
145+
source = '''
146+
.. jupyter-execute::
147+
:linenos:
148+
149+
2 + 2
150+
151+
.. jupyter-execute::
152+
:continue_linenos:
153+
154+
3 + 3
155+
'''
156+
tree = doctree(source)
157+
(cell0, cell1) = tree.traverse(JupyterCellNode)
158+
# :linenos:
159+
assert cell0.attributes['linenos']
160+
assert cell0.attributes['continue_linenos'] is False
161+
assert cell0.children[0].attributes['linenos']
162+
assert 'highlight_args' not in cell0.children[0].attributes
163+
assert cell0.children[0].rawsource.strip() == "2 + 2"
164+
assert cell0.children[1].rawsource.strip() == "4"
165+
# :continue_linenos:
166+
assert cell1.attributes['linenos'] is False
167+
assert cell1.attributes['continue_linenos']
168+
assert 'highlight_args' not in cell1.attributes
169+
assert cell1.children[0].attributes['linenos']
170+
assert cell1.children[0].attributes['highlight_args']['linenostart'] == 2
171+
assert cell1.children[0].rawsource.strip() == "3 + 3"
172+
assert cell1.children[1].rawsource.strip() == "6"
173+
174+
source2 = '''
175+
.. jupyter-execute::
176+
:linenos:
177+
178+
'cell0' # will be line number 1
179+
180+
.. jupyter-execute::
181+
:linenos:
182+
183+
'cell1' # should restart with line number 1
184+
185+
.. jupyter-execute::
186+
:continue_linenos:
187+
188+
'cell2' # should be line number 2
189+
190+
.. jupyter-execute::
191+
192+
'cell3' # no line number directive
193+
194+
.. jupyter-execute::
195+
:continue_linenos:
196+
197+
'cell4' # should restart at line number 1
198+
199+
.. jupyter-execute::
200+
:continue_linenos:
201+
202+
'cell5' # should continue with line number 2
203+
'''
204+
tree2 = doctree(source2)
205+
cells = tree2.traverse(JupyterCellNode)
206+
assert len(cells) == 6
207+
(cell0, cell1, cell2, cell3, cell4, cell5) = cells
208+
# :linenos:
209+
assert cell0.children[0].attributes["linenos"]
210+
assert "highlight_args" not in cell0.children[0].attributes
211+
# :linenos:
212+
assert cell1.children[0].attributes["linenos"]
213+
assert "highlight_args" not in cell1.children[0].attributes
214+
# :continue_linenos:
215+
assert cell2.children[0].attributes["linenos"]
216+
assert cell2.children[0].attributes["highlight_args"]["linenostart"] == 2
217+
# (No line number directive)
218+
assert "linenos" not in cell3.children[0].attributes
219+
assert "highlight_args" not in cell3.children[0].attributes
220+
# :continue_linenos:
221+
assert cell4.children[0].attributes["linenos"]
222+
assert cell4.children[0].attributes["highlight_args"]["linenostart"] == 1
223+
# :continue_linenos:
224+
assert cell5.children[0].attributes["linenos"]
225+
assert cell5.children[0].attributes["highlight_args"]["linenostart"] == 2
226+
227+
144228
def test_execution_environment_carries_over(doctree):
145229
source = '''
146230
.. jupyter-execute::

0 commit comments

Comments
 (0)