If `:start-after: is used, make :lines:` relative (close: #3412)

This commit is contained in:
jfbu 2017-02-10 14:35:58 +01:00
parent 839e924808
commit a2338e4838
4 changed files with 57 additions and 32 deletions

View File

@ -182,13 +182,24 @@ Includes
``start-after`` is given as a string option, only lines that follow the first ``start-after`` is given as a string option, only lines that follow the first
line containing that string are included. If ``end-before`` is given as a line containing that string are included. If ``end-before`` is given as a
string option, only lines that precede the first lines containing that string string option, only lines that precede the first lines containing that string
are included. If used in combination with ``lines``, make sure the latter are included.
allows the lines (whose count start at ``1`` at top of file) containing the
looked-for strings. With lines selected this way it is still possible to use ``lines``, the
numbers being now interpreted relative to the already selected lines.
.. versionchanged:: 1.5.3
Formerly, ``lines`` still referred to the included file, and it was
needed that those lines containing the requested strings were among
the allowed ones.
When lines have been selected in any of the ways described above, the
line numbers in ``emphasize-lines`` refer to the selection, with the
line count starting at ``1``.
When specifying particular parts of a file to display, it can be useful to When specifying particular parts of a file to display, it can be useful to
display exactly which lines are being presented. display the original line numbers. This can be done using the
This can be done using the ``lineno-match`` option. ``lineno-match`` option, which is however allowed only when the selection
consists of contiguous lines.
You can prepend and/or append a line to the included code, using the You can prepend and/or append a line to the included code, using the
``prepend`` and ``append`` option, respectively. This is useful e.g. for ``prepend`` and ``append`` option, respectively. This is useful e.g. for

View File

@ -270,31 +270,6 @@ class LiteralInclude(Directive):
if 'lineno-match' in self.options: if 'lineno-match' in self.options:
linenostart = tags[objectname][1] linenostart = tags[objectname][1]
linespec = self.options.get('lines')
if linespec:
try:
linelist = parselinenos(linespec, len(lines))
except ValueError as err:
return [document.reporter.warning(str(err), line=self.lineno)]
if 'lineno-match' in self.options:
# make sure the line list is not "disjoint".
previous = linelist[0]
for line_number in linelist[1:]:
if line_number == previous + 1:
previous = line_number
continue
return [document.reporter.warning(
'Cannot use "lineno-match" with a disjoint set of '
'"lines"', line=self.lineno)]
linenostart = linelist[0] + 1
# just ignore non-existing lines
lines = [lines[i] for i in linelist if i < len(lines)]
if not lines:
return [document.reporter.warning(
'Line spec %r: no lines pulled from include file %r' %
(linespec, filename), line=self.lineno)]
linespec = self.options.get('emphasize-lines') linespec = self.options.get('emphasize-lines')
if linespec: if linespec:
try: try:
@ -320,10 +295,12 @@ class LiteralInclude(Directive):
for line_number, line in enumerate(lines): for line_number, line in enumerate(lines):
if not use and start_str and start_str in line: if not use and start_str and start_str in line:
if 'lineno-match' in self.options: if 'lineno-match' in self.options:
linenostart += line_number + 1 linenostart = line_number + 1
use = True
if start_inclusive: if start_inclusive:
res.append(line) res.append(line)
else:
linenostart +=1
use = True
elif use and end_str and end_str in line: elif use and end_str and end_str in line:
if end_inclusive: if end_inclusive:
res.append(line) res.append(line)
@ -332,6 +309,31 @@ class LiteralInclude(Directive):
res.append(line) res.append(line)
lines = res lines = res
linespec = self.options.get('lines')
if linespec:
try:
linelist = parselinenos(linespec, len(lines))
except ValueError as err:
return [document.reporter.warning(str(err), line=self.lineno)]
if 'lineno-match' in self.options:
# make sure the line list is not "disjoint".
previous = linelist[0]
for line_number in linelist[1:]:
if line_number == previous + 1:
previous = line_number
continue
return [document.reporter.warning(
'Cannot use "lineno-match" with a disjoint set of '
'"lines"', line=self.lineno)]
linenostart += linelist[0]
# just ignore non-existing lines
lines = [lines[i] for i in linelist if i < len(lines)]
if not lines:
return [document.reporter.warning(
'Line spec %r: no lines pulled from include file %r' %
(linespec, filename), line=self.lineno)]
prepend = self.options.get('prepend') prepend = self.options.get('prepend')
if prepend: if prepend:
lines.insert(0, prepend + '\n') lines.insert(0, prepend + '\n')

View File

@ -16,6 +16,12 @@ Literal Includes with Line Numbers Matching
:start-after: pass :start-after: pass
:lineno-match: :lineno-match:
.. literalinclude:: literal.inc
:language: python
:start-after: Literally
:lines: 1,2
:lineno-match:
.. literalinclude:: literal.inc .. literalinclude:: literal.inc
:language: python :language: python
:start-at: class Bar: :start-at: class Bar:

View File

@ -223,6 +223,12 @@ def test_literal_include_lineno_match(app, status, warning):
'14</pre></div></td>') '14</pre></div></td>')
assert start_after in html assert start_after in html
start_after_with_lines = (
'<td class="linenos"><div class="linenodiv"><pre>'
'2\n'
'3</pre></div></td>')
assert start_after_with_lines in html
start_at_end_at = ( start_at_end_at = (
'<td class="linenos"><div class="linenodiv"><pre>' '<td class="linenos"><div class="linenodiv"><pre>'
' 9\n' ' 9\n'