Georg Brandl avatar Georg Brandl committed 207a982

Paths to literal include files and download files can now be absolute too.

Comments (0)

Files changed (9)

     the directive -- this allows you to define your document
     structure, but place the links yourself.
 
-  - Image paths can now be absolute (like ``/images/foo.png``).
-    They are treated as relative to the top source directory.
+  - Paths to images, literal include files and download files
+    can now be absolute (like ``/images/foo.png``).  They are
+    treated as relative to the top source directory.
 
   - #52: There is now a ``hlist`` directive, creating a compact
     list by placing distributing items into multiple columns.

doc/markup/code.rst

 
       .. literalinclude:: example.py
 
-   The file name is relative to the current file's path.
+   The file name is usually relative to the current file's path.  However, if it
+   is absolute (starting with ``/``), it is relative to the top source
+   directory.
 
    The directive also supports the ``linenos`` flag option to switch on line
    numbers, and a ``language`` option to select a language different from the
    .. versionadded:: 0.4.3
       The ``encoding`` option.
    .. versionadded:: 0.6
-      The ``pyobject``, ``lines``, ``start-after`` and ``end-before`` options.
+      The ``pyobject``, ``lines``, ``start-after`` and ``end-before`` options,
+      as well as support for absolute filenames.
 
 
 .. rubric:: Footnotes

doc/markup/inline.rst

 
       See :download:`this example script <../example.py>`.
 
-   The given filename is relative to the directory the current source file is
-   contained in.  The ``../example.py`` file will be copied to the output
-   directory, and a suitable link generated to it.
+   The given filename is usually relative to the directory the current source
+   file is contained in, but if it absolute (starting with ``/``), it is taken
+   as relative to the top source directory.
+
+   The ``example.py`` file will be copied to the output directory, and a
+   suitable link generated to it.
 
 
 Other semantic markup

sphinx/directives/code.py

     :license: BSD, see LICENSE for details.
 """
 
+import os
 import sys
 import codecs
 from os import path
             return [document.reporter.warning('File insertion disabled',
                                               line=self.lineno)]
         env = document.settings.env
-        rel_fn = filename
-        sourcename = self.state_machine.input_lines.source(
-            self.lineno - self.state_machine.input_offset - 1)
-        source_dir = path.dirname(path.abspath(sourcename))
-        fn = path.normpath(path.join(source_dir, rel_fn))
+        if filename.startswith('/') or filename.startswith(os.sep):
+            rel_fn = filename[1:]
+        else:
+            docdir = path.dirname(env.doc2path(env.docname, base=None))
+            rel_fn = path.normpath(path.join(docdir, filename))
+        fn = path.join(env.srcdir, rel_fn)
 
         if 'pyobject' in self.options and 'lines' in self.options:
             return [document.reporter.warning(

sphinx/environment.py

 from string import ascii_uppercase as uppercase
 from itertools import izip, groupby
 try:
-    import hashlib
-    md5 = hashlib.md5
+    from hashlib import md5
 except ImportError:
     # 2.4 compatibility
-    import md5
-    md5 = md5.new
+    from md5 import md5
 
 from docutils import nodes
 from docutils.io import FileInput, NullOutput
         """
         docdir = path.dirname(self.doc2path(docname, base=None))
         for node in doctree.traverse(addnodes.download_reference):
-            filepath = path.normpath(path.join(docdir, node['reftarget']))
+            targetname = node['reftarget']
+            if targetname.startswith('/') or targetname.startswith(os.sep):
+                # absolute
+                filepath = targetname[1:]
+            else:
+                filepath = path.normpath(path.join(docdir, node['reftarget']))
             self.dependencies.setdefault(docname, set()).add(filepath)
             if not os.access(path.join(self.srcdir, filepath), os.R_OK):
                 self.warn(docname, 'Download file not readable: %s' % filepath,
              node.astext()))
 
     def note_dependency(self, filename):
-        basename = path.dirname(self.doc2path(self.docname, base=None))
-        # this will do the right thing when filename is absolute too
-        filename = path.join(basename, filename)
         self.dependencies.setdefault(self.docname, set()).add(filename)
     # -------
 

tests/root/contents.txt

 
    images
    subdir/images
+   subdir/includes
    includes
    markup
    desc

tests/root/special/code.py

+print "line 1"
+print "line 2"

tests/root/subdir/includes.txt

+Including in subdir
+===================
+
+.. absolute filename
+.. literalinclude:: /special/code.py
+   :lines: 1
+
+.. relative filename
+.. literalinclude:: ../special/code.py
+   :lines: 2
+
+Absolute :download:`/img.png` download.

tests/test_build.py

         ".//img[@src='../_images/img1.png']": '',
         ".//img[@src='../_images/rimg.png']": '',
     },
+    'subdir/includes.html': {
+        ".//pre/span": 'line 1',
+        ".//pre/span": 'line 2',
+        ".//a[@href='../_downloads/img.png']": '',
+    },
     'includes.html': {
         ".//pre": u'Max Strauß',
         ".//a[@href='_downloads/img.png']": '',
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.