Georg Brandl avatar Georg Brandl committed 6f05edb

Add lines and start-after/end-before options to literalinclude.

Comments (0)

Files changed (2)

sphinx/directives/code.py

     sphinx.directives.code
     ~~~~~~~~~~~~~~~~~~~~~~
 
-    :copyright: 2007-2008 by Georg Brandl.
+    :copyright: 2007-2009 by Georg Brandl.
     :license: BSD, see LICENSE for details.
 """
 
 from docutils.parsers.rst import directives
 
 from sphinx import addnodes
+from sphinx.util import parselinenos
 
 
 # ------ highlight directive --------------------------------------------------------
         lineno - state_machine.input_offset - 1)))
     fn = path.normpath(path.join(source_dir, rel_fn))
 
-    fromline = toline = None
-    objectname = options.get('pyobject')
-    if objectname is not None:
-        from sphinx.pycode import ModuleAnalyzer
-        analyzer = ModuleAnalyzer.for_file(fn, '')
-        tags = analyzer.find_tags()
-        if objectname not in tags:
-            return [state.document.reporter.warning(
-                'Object named %r not found in include file %r' %
-                (objectname, arguments[0]), line=lineno)]
-        else:
-            fromline = tags[objectname][1] - 1
-            toline = tags[objectname][2] - 1
+    if 'pyobject' in options and 'lines' in options:
+        return [state.document.reporter.warning(
+            'Cannot use both "pyobject" and "lines" options', line=lineno)]
 
     encoding = options.get('encoding', env.config.source_encoding)
     try:
             'Encoding %r used for reading included file %r seems to '
             'be wrong, try giving an :encoding: option' %
             (encoding, arguments[0]))]
-    text = ''.join(lines[fromline:toline])
+
+    objectname = options.get('pyobject')
+    if objectname is not None:
+        from sphinx.pycode import ModuleAnalyzer
+        analyzer = ModuleAnalyzer.for_file(fn, '')
+        tags = analyzer.find_tags()
+        if objectname not in tags:
+            return [state.document.reporter.warning(
+                'Object named %r not found in include file %r' %
+                (objectname, arguments[0]), line=lineno)]
+        else:
+            lines = lines[tags[objectname][1] - 1 : tags[objectname][2]]
+
+    linespec = options.get('lines')
+    if linespec is not None:
+        try:
+            linelist = parselinenos(linespec, len(lines))
+        except ValueError, err:
+            return [state.document.reporter.warning(str(err), line=lineno)]
+        lines = [lines[i] for i in linelist]
+
+    startafter = options.get('start-after')
+    endbefore = options.get('end-before')
+    if startafter is not None or endbefore is not None:
+        use = not startafter
+        res = []
+        for line in lines:
+            if not use and startafter in line:
+                use = True
+            elif use and endbefore in line:
+                use = False
+                break
+            elif use:
+                res.append(line)
+        lines = res
+
+    text = ''.join(lines)
     retnode = nodes.literal_block(text, text, source=fn)
     retnode.line = 1
     if options.get('language', ''):
                                     'language': directives.unchanged_required,
                                     'encoding': directives.encoding,
                                     'pyobject': directives.unchanged_required,
-                                    #'lines': directives.unchanged_required,
-                                    #'start-after': directives.unchanged_required,
-                                    #'end-before': directives.unchanged_required,
+                                    'lines': directives.unchanged_required,
+                                    'start-after': directives.unchanged_required,
+                                    'end-before': directives.unchanged_required,
                                     }
 literalinclude_directive.content = 0
 literalinclude_directive.arguments = (1, 0, 0)

sphinx/util/__init__.py

 
     Utility functions for Sphinx.
 
-    :copyright: 2007-2008 by Georg Brandl.
+    :copyright: 2007-2009 by Georg Brandl.
     :license: BSD, see LICENSE for details.
 """
 
 
     def __setstate__(self, state):
         self._existing = state
+
+
+def parselinenos(spec, total):
+    """
+    Parse a line number spec (such as "1,2,4-6") and return a list of
+    wanted line numbers.
+    """
+    items = list()
+    parts = spec.split(',')
+    for part in parts:
+        try:
+            begend = part.strip().split('-')
+            if len(begend) > 2:
+                raise ValueError
+            if len(begend) == 1:
+                items.append(int(begend[0])-1)
+            else:
+                start = (begend[0] == '') and 0 or int(begend[0])-1
+                end = (begend[1] == '') and total or int(begend[1])
+                items.extend(xrange(start, end))
+        except Exception, err:
+            raise ValueError('invalid line number spec: %r' % spec)
+    return items
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.