We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Relative links in pages below the top-level document folder point to the wrong path
Relative image links in pages below the top-level document folder seem to point to the wrong path.
## Reproduction

I've created a minimal reproduction case:
https://github.com/jdhoek/mkdocs-test-relative-image-links

The reproduction case contains this file structure:

```
├── docs
│   ├── index.md
│   ├── subdir
│   │   ├── sub.md
│   │   └── sub.png
│   └── toplevel.png
└── mkdocs.yml
```

`mkdocs serve` and `mkdocs build` correctly process the Markdown files in the top-level folder `docs_dir`, but with the Markdown file in the sub-folder the relative image links are broken.

![mkdocs-relative-image-links](https://cloud.githubusercontent.com/assets/683699/5486734/3fd98a18-86aa-11e4-9243-059b656efa19.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mkdocs/utils.py`
Content:
```
1 # coding: utf-8
2 
3 """
4 Standalone file utils.
5 
6 Nothing in this module should have an knowledge of config or the layout
7 and structure of the site and pages in the site.
8 """
9 
10 import os
11 import shutil
12 
13 from mkdocs.compat import urlparse
14 
15 
16 def copy_file(source_path, output_path):
17     """
18     Copy source_path to output_path, making sure any parent directories exist.
19     """
20     output_dir = os.path.dirname(output_path)
21     if not os.path.exists(output_dir):
22         os.makedirs(output_dir)
23     shutil.copy(source_path, output_path)
24 
25 
26 def write_file(content, output_path):
27     """
28     Write content to output_path, making sure any parent directories exist.
29     """
30     output_dir = os.path.dirname(output_path)
31     if not os.path.exists(output_dir):
32         os.makedirs(output_dir)
33     open(output_path, 'wb').write(content)
34 
35 
36 def clean_directory(directory):
37     """
38     Remove the content of a directory recursively but not the directory itself.
39     """
40     if os.path.exists(directory):
41         for entry in os.listdir(directory):
42             path = os.path.join(directory, entry)
43             if os.path.isdir(path):
44                 shutil.rmtree(path, True)
45             else:
46                 os.unlink(path)
47 
48 
49 def copy_media_files(from_dir, to_dir):
50     """
51     Recursively copy all files except markdown and HTML into another directory.
52     """
53     for (source_dir, dirnames, filenames) in os.walk(from_dir):
54         relative_path = os.path.relpath(source_dir, from_dir)
55         output_dir = os.path.normpath(os.path.join(to_dir, relative_path))
56 
57         # Filter filenames starting with a '.'
58         filenames = [f for f in filenames if not f.startswith('.')]
59 
60         # Filter the dirnames that start with a '.' and update the list in
61         # place to prevent us walking these.
62         dirnames[:] = [d for d in dirnames if not d.startswith('.')]
63 
64         for filename in filenames:
65             if not is_markdown_file(filename) and not is_html_file(filename):
66                 source_path = os.path.join(source_dir, filename)
67                 output_path = os.path.join(output_dir, filename)
68                 copy_file(source_path, output_path)
69 
70 
71 def get_html_path(path):
72     """
73     Map a source file path to an output html path.
74 
75     Paths like 'index.md' will be converted to 'index.html'
76     Paths like 'about.md' will be converted to 'about/index.html'
77     Paths like 'api-guide/core.md' will be converted to 'api-guide/core/index.html'
78     """
79     path = os.path.splitext(path)[0]
80     if os.path.basename(path) == 'index':
81         return path + '.html'
82     return "/".join((path, 'index.html'))
83 
84 
85 def get_url_path(path, use_directory_urls=True):
86     """
87     Map a source file path to an output html path.
88 
89     Paths like 'index.md' will be converted to '/'
90     Paths like 'about.md' will be converted to '/about/'
91     Paths like 'api-guide/core.md' will be converted to '/api-guide/core/'
92 
93     If `use_directory_urls` is `False`, returned URLs will include the a trailing
94     `index.html` rather than just returning the directory path.
95     """
96     path = get_html_path(path)
97     url = '/' + path.replace(os.path.sep, '/')
98     if use_directory_urls:
99         return url[:-len('index.html')]
100     return url
101 
102 
103 def is_homepage(path):
104     return os.path.splitext(path)[0] == 'index'
105 
106 
107 def is_markdown_file(path):
108     """
109     Return True if the given file path is a Markdown file.
110 
111     http://superuser.com/questions/249436/file-extension-for-markdown-files
112     """
113     ext = os.path.splitext(path)[1].lower()
114     return ext in [
115         '.markdown',
116         '.mdown',
117         '.mkdn',
118         '.mkd',
119         '.md',
120     ]
121 
122 
123 def is_css_file(path):
124     """
125     Return True if the given file path is a CSS file.
126     """
127     ext = os.path.splitext(path)[1].lower()
128     return ext in [
129         '.css',
130     ]
131 
132 
133 def is_javascript_file(path):
134     """
135     Return True if the given file path is a Javascript file.
136     """
137     ext = os.path.splitext(path)[1].lower()
138     return ext in [
139         '.js',
140         '.javascript'
141     ]
142 
143 
144 def is_html_file(path):
145     """
146     Return True if the given file path is an HTML file.
147     """
148     ext = os.path.splitext(path)[1].lower()
149     return ext in [
150         '.html',
151         '.htm',
152     ]
153 
154 
155 def create_media_urls(nav, url_list):
156     """
157     Return a list of URLs that have been processed correctly for inclusion in a page.
158     """
159     final_urls = []
160     for url in url_list:
161         # Allow links to fully qualified URL's
162         parsed = urlparse(url)
163         if parsed.netloc:
164             final_urls.append(url)
165         else:
166             relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url)
167             final_urls.append(relative_url)
168     return final_urls
169
```

Path: `mkdocs/relative_path_ext.py`
Content:
```
1 """
2 # Relative Path Markdown Extension
3 
4 During the MkDocs build we rewrite URLs that link to local
5 Markdown or media files. Using the following pages configuration
6 we can look at how the output is changed.
7 
8     pages:
9     - ['index.md']
10     - ['tutorial/install.md']
11     - ['tutorial/intro.md']
12 
13 ## Markdown URLs
14 
15 When linking from `install.md` to `intro.md` the link would
16 simply be `[intro](intro.md)`. However, when we build
17 `install.md` we place it in a directory to create nicer URLs.
18 This means that the path to `intro.md` becomes `../intro/`
19 
20 ## Media URLs
21 
22 To make it easier to work with media files and store them all
23 under one directory we re-write those to all be based on the
24 root. So, with the following markdown to add an image.
25 
26     ![The initial MkDocs layout](img/initial-layout.png)
27 
28 The output would depend on the location of the Markdown file it
29 was added too.
30 
31 Source file         | Generated Path    | Image Path                   |
32 ------------------- | ----------------- | ---------------------------- |
33 index.md            | /                 | ./img/initial-layout.png     |
34 tutorial/install.md | tutorial/install/ | ../img/initial-layout.png    |
35 tutorial/intro.md   | tutorial/intro/   | ../../img/initial-layout.png |
36 
37 """
38 from markdown.extensions import Extension
39 from markdown.treeprocessors import Treeprocessor
40 
41 from mkdocs import utils
42 from mkdocs.compat import urlparse, urlunparse
43 
44 
45 def _iter(node):
46     # TODO: Remove when dropping Python 2.6. Replace this
47     # function call with note.iter()
48     return [node] + node.findall('.//*')
49 
50 
51 def path_to_url(url, nav):
52     scheme, netloc, path, query, query, fragment = urlparse(url)
53 
54     if scheme or netloc or not path:
55         # Ignore URLs unless they are a relative link to a markdown file.
56         return url
57 
58     if nav and not utils.is_markdown_file(path):
59         path = utils.create_media_urls(nav, [path])[0]
60     elif nav:
61         # If the site navigation has been provided, then validate
62         # the internal hyperlink, making sure the target actually exists.
63         target_file = nav.file_context.make_absolute(path)
64         if target_file not in nav.source_files:
65             source_file = nav.file_context.current_file
66             msg = (
67                 'The page "%s" contained a hyperlink to "%s" which '
68                 'is not listed in the "pages" configuration.'
69             )
70             assert False, msg % (source_file, target_file)
71         path = utils.get_url_path(target_file, nav.use_directory_urls)
72         path = nav.url_context.make_relative(path)
73     else:
74         path = utils.get_url_path(path).lstrip('/')
75 
76     # Convert the .md hyperlink to a relative hyperlink to the HTML page.
77     url = urlunparse((scheme, netloc, path, query, query, fragment))
78     return url
79 
80 
81 class RelativePathTreeprocessor(Treeprocessor):
82 
83     def __init__(self, site_navigation):
84         self.site_navigation = site_navigation
85 
86     def run(self, root):
87         """Update urls on anchors and images to make them relative
88 
89         Iterates through the full document tree looking for specific
90         tags and then makes them relative based on the site navigation
91         """
92 
93         for element in _iter(root):
94 
95             if element.tag == 'a':
96                 key = 'href'
97             elif element.tag == 'img':
98                 key = 'src'
99             else:
100                 continue
101 
102             url = element.get(key)
103             new_url = path_to_url(url, self.site_navigation)
104             element.set(key, new_url)
105 
106         return root
107 
108 
109 class RelativePathExtension(Extension):
110     """
111     The Extension class is what we pass to markdown, it then
112     registers the Treeprocessor.
113     """
114 
115     def __init__(self, site_navigation):
116         self.site_navigation = site_navigation
117 
118     def extendMarkdown(self, md, md_globals):
119         relpath = RelativePathTreeprocessor(self.site_navigation)
120         md.treeprocessors.add("relpath", relpath, "_end")
121
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mkdocs/relative_path_ext.py b/mkdocs/relative_path_ext.py
--- a/mkdocs/relative_path_ext.py
+++ b/mkdocs/relative_path_ext.py
@@ -56,7 +56,7 @@
         return url
 
     if nav and not utils.is_markdown_file(path):
-        path = utils.create_media_urls(nav, [path])[0]
+        path = utils.create_relative_media_url(nav, path)
     elif nav:
         # If the site navigation has been provided, then validate
         # the internal hyperlink, making sure the target actually exists.
diff --git a/mkdocs/utils.py b/mkdocs/utils.py
--- a/mkdocs/utils.py
+++ b/mkdocs/utils.py
@@ -166,3 +166,41 @@
             relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url)
             final_urls.append(relative_url)
     return final_urls
+
+
+def create_relative_media_url(nav, url):
+    """
+    For a current page, create a relative url based on the given URL.
+
+    On index.md (which becomes /index.html):
+        image.png -> ./image.png
+        /image.png -> ./image.png
+
+    on sub/page.md (which becomes /sub/page/index.html):
+        image.png -> ../image.png
+        /image.png -> ../../image.png
+
+    """
+
+    # Allow links to fully qualified URL's
+    parsed = urlparse(url)
+    if parsed.netloc:
+        return url
+
+    # If the URL we are looking at starts with a /, then it should be
+    # considered as absolute and will be 'relative' to the root.
+    if url.startswith('/'):
+        base = '/'
+        url = url[1:]
+    else:
+        base = nav.url_context.base_path
+
+    relative_url = '%s/%s' % (nav.url_context.make_relative(base), url)
+
+    # TODO: Fix this, this is a hack. Relative urls are not being calculated
+    # correctly for images in the same directory as the markdown. I think this
+    # is due to us moving it into a directory with index.html, but I'm not sure
+    if nav.url_context.base_path is not '/' and relative_url.startswith("./"):
+        relative_url = ".%s" % relative_url
+
+    return relative_url

{"golden_diff": "diff --git a/mkdocs/relative_path_ext.py b/mkdocs/relative_path_ext.py\n--- a/mkdocs/relative_path_ext.py\n+++ b/mkdocs/relative_path_ext.py\n@@ -56,7 +56,7 @@\n         return url\n \n     if nav and not utils.is_markdown_file(path):\n-        path = utils.create_media_urls(nav, [path])[0]\n+        path = utils.create_relative_media_url(nav, path)\n     elif nav:\n         # If the site navigation has been provided, then validate\n         # the internal hyperlink, making sure the target actually exists.\ndiff --git a/mkdocs/utils.py b/mkdocs/utils.py\n--- a/mkdocs/utils.py\n+++ b/mkdocs/utils.py\n@@ -166,3 +166,41 @@\n             relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url)\n             final_urls.append(relative_url)\n     return final_urls\n+\n+\n+def create_relative_media_url(nav, url):\n+    \"\"\"\n+    For a current page, create a relative url based on the given URL.\n+\n+    On index.md (which becomes /index.html):\n+        image.png -> ./image.png\n+        /image.png -> ./image.png\n+\n+    on sub/page.md (which becomes /sub/page/index.html):\n+        image.png -> ../image.png\n+        /image.png -> ../../image.png\n+\n+    \"\"\"\n+\n+    # Allow links to fully qualified URL's\n+    parsed = urlparse(url)\n+    if parsed.netloc:\n+        return url\n+\n+    # If the URL we are looking at starts with a /, then it should be\n+    # considered as absolute and will be 'relative' to the root.\n+    if url.startswith('/'):\n+        base = '/'\n+        url = url[1:]\n+    else:\n+        base = nav.url_context.base_path\n+\n+    relative_url = '%s/%s' % (nav.url_context.make_relative(base), url)\n+\n+    # TODO: Fix this, this is a hack. Relative urls are not being calculated\n+    # correctly for images in the same directory as the markdown. I think this\n+    # is due to us moving it into a directory with index.html, but I'm not sure\n+    if nav.url_context.base_path is not '/' and relative_url.startswith(\"./\"):\n+        relative_url = \".%s\" % relative_url\n+\n+    return relative_url\n", "issue": "Relative links in pages below the top-level document folder point to the wrong path\nRelative image links in pages below the top-level document folder seem to point to the wrong path.\n## Reproduction\n\nI've created a minimal reproduction case:\nhttps://github.com/jdhoek/mkdocs-test-relative-image-links\n\nThe reproduction case contains this file structure:\n\n```\n\u251c\u2500\u2500 docs\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 index.md\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 subdir\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 sub.md\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 sub.png\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 toplevel.png\n\u2514\u2500\u2500 mkdocs.yml\n```\n\n`mkdocs serve` and `mkdocs build` correctly process the Markdown files in the top-level folder `docs_dir`, but with the Markdown file in the sub-folder the relative image links are broken.\n\n![mkdocs-relative-image-links](https://cloud.githubusercontent.com/assets/683699/5486734/3fd98a18-86aa-11e4-9243-059b656efa19.png)\n\n", "before_files": [{"content": "# coding: utf-8\n\n\"\"\"\nStandalone file utils.\n\nNothing in this module should have an knowledge of config or the layout\nand structure of the site and pages in the site.\n\"\"\"\n\nimport os\nimport shutil\n\nfrom mkdocs.compat import urlparse\n\n\ndef copy_file(source_path, output_path):\n    \"\"\"\n    Copy source_path to output_path, making sure any parent directories exist.\n    \"\"\"\n    output_dir = os.path.dirname(output_path)\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n    shutil.copy(source_path, output_path)\n\n\ndef write_file(content, output_path):\n    \"\"\"\n    Write content to output_path, making sure any parent directories exist.\n    \"\"\"\n    output_dir = os.path.dirname(output_path)\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n    open(output_path, 'wb').write(content)\n\n\ndef clean_directory(directory):\n    \"\"\"\n    Remove the content of a directory recursively but not the directory itself.\n    \"\"\"\n    if os.path.exists(directory):\n        for entry in os.listdir(directory):\n            path = os.path.join(directory, entry)\n            if os.path.isdir(path):\n                shutil.rmtree(path, True)\n            else:\n                os.unlink(path)\n\n\ndef copy_media_files(from_dir, to_dir):\n    \"\"\"\n    Recursively copy all files except markdown and HTML into another directory.\n    \"\"\"\n    for (source_dir, dirnames, filenames) in os.walk(from_dir):\n        relative_path = os.path.relpath(source_dir, from_dir)\n        output_dir = os.path.normpath(os.path.join(to_dir, relative_path))\n\n        # Filter filenames starting with a '.'\n        filenames = [f for f in filenames if not f.startswith('.')]\n\n        # Filter the dirnames that start with a '.' and update the list in\n        # place to prevent us walking these.\n        dirnames[:] = [d for d in dirnames if not d.startswith('.')]\n\n        for filename in filenames:\n            if not is_markdown_file(filename) and not is_html_file(filename):\n                source_path = os.path.join(source_dir, filename)\n                output_path = os.path.join(output_dir, filename)\n                copy_file(source_path, output_path)\n\n\ndef get_html_path(path):\n    \"\"\"\n    Map a source file path to an output html path.\n\n    Paths like 'index.md' will be converted to 'index.html'\n    Paths like 'about.md' will be converted to 'about/index.html'\n    Paths like 'api-guide/core.md' will be converted to 'api-guide/core/index.html'\n    \"\"\"\n    path = os.path.splitext(path)[0]\n    if os.path.basename(path) == 'index':\n        return path + '.html'\n    return \"/\".join((path, 'index.html'))\n\n\ndef get_url_path(path, use_directory_urls=True):\n    \"\"\"\n    Map a source file path to an output html path.\n\n    Paths like 'index.md' will be converted to '/'\n    Paths like 'about.md' will be converted to '/about/'\n    Paths like 'api-guide/core.md' will be converted to '/api-guide/core/'\n\n    If `use_directory_urls` is `False`, returned URLs will include the a trailing\n    `index.html` rather than just returning the directory path.\n    \"\"\"\n    path = get_html_path(path)\n    url = '/' + path.replace(os.path.sep, '/')\n    if use_directory_urls:\n        return url[:-len('index.html')]\n    return url\n\n\ndef is_homepage(path):\n    return os.path.splitext(path)[0] == 'index'\n\n\ndef is_markdown_file(path):\n    \"\"\"\n    Return True if the given file path is a Markdown file.\n\n    http://superuser.com/questions/249436/file-extension-for-markdown-files\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.markdown',\n        '.mdown',\n        '.mkdn',\n        '.mkd',\n        '.md',\n    ]\n\n\ndef is_css_file(path):\n    \"\"\"\n    Return True if the given file path is a CSS file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.css',\n    ]\n\n\ndef is_javascript_file(path):\n    \"\"\"\n    Return True if the given file path is a Javascript file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.js',\n        '.javascript'\n    ]\n\n\ndef is_html_file(path):\n    \"\"\"\n    Return True if the given file path is an HTML file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.html',\n        '.htm',\n    ]\n\n\ndef create_media_urls(nav, url_list):\n    \"\"\"\n    Return a list of URLs that have been processed correctly for inclusion in a page.\n    \"\"\"\n    final_urls = []\n    for url in url_list:\n        # Allow links to fully qualified URL's\n        parsed = urlparse(url)\n        if parsed.netloc:\n            final_urls.append(url)\n        else:\n            relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url)\n            final_urls.append(relative_url)\n    return final_urls\n", "path": "mkdocs/utils.py"}, {"content": "\"\"\"\n# Relative Path Markdown Extension\n\nDuring the MkDocs build we rewrite URLs that link to local\nMarkdown or media files. Using the following pages configuration\nwe can look at how the output is changed.\n\n    pages:\n    - ['index.md']\n    - ['tutorial/install.md']\n    - ['tutorial/intro.md']\n\n## Markdown URLs\n\nWhen linking from `install.md` to `intro.md` the link would\nsimply be `[intro](intro.md)`. However, when we build\n`install.md` we place it in a directory to create nicer URLs.\nThis means that the path to `intro.md` becomes `../intro/`\n\n## Media URLs\n\nTo make it easier to work with media files and store them all\nunder one directory we re-write those to all be based on the\nroot. So, with the following markdown to add an image.\n\n    ![The initial MkDocs layout](img/initial-layout.png)\n\nThe output would depend on the location of the Markdown file it\nwas added too.\n\nSource file         | Generated Path    | Image Path                   |\n------------------- | ----------------- | ---------------------------- |\nindex.md            | /                 | ./img/initial-layout.png     |\ntutorial/install.md | tutorial/install/ | ../img/initial-layout.png    |\ntutorial/intro.md   | tutorial/intro/   | ../../img/initial-layout.png |\n\n\"\"\"\nfrom markdown.extensions import Extension\nfrom markdown.treeprocessors import Treeprocessor\n\nfrom mkdocs import utils\nfrom mkdocs.compat import urlparse, urlunparse\n\n\ndef _iter(node):\n    # TODO: Remove when dropping Python 2.6. Replace this\n    # function call with note.iter()\n    return [node] + node.findall('.//*')\n\n\ndef path_to_url(url, nav):\n    scheme, netloc, path, query, query, fragment = urlparse(url)\n\n    if scheme or netloc or not path:\n        # Ignore URLs unless they are a relative link to a markdown file.\n        return url\n\n    if nav and not utils.is_markdown_file(path):\n        path = utils.create_media_urls(nav, [path])[0]\n    elif nav:\n        # If the site navigation has been provided, then validate\n        # the internal hyperlink, making sure the target actually exists.\n        target_file = nav.file_context.make_absolute(path)\n        if target_file not in nav.source_files:\n            source_file = nav.file_context.current_file\n            msg = (\n                'The page \"%s\" contained a hyperlink to \"%s\" which '\n                'is not listed in the \"pages\" configuration.'\n            )\n            assert False, msg % (source_file, target_file)\n        path = utils.get_url_path(target_file, nav.use_directory_urls)\n        path = nav.url_context.make_relative(path)\n    else:\n        path = utils.get_url_path(path).lstrip('/')\n\n    # Convert the .md hyperlink to a relative hyperlink to the HTML page.\n    url = urlunparse((scheme, netloc, path, query, query, fragment))\n    return url\n\n\nclass RelativePathTreeprocessor(Treeprocessor):\n\n    def __init__(self, site_navigation):\n        self.site_navigation = site_navigation\n\n    def run(self, root):\n        \"\"\"Update urls on anchors and images to make them relative\n\n        Iterates through the full document tree looking for specific\n        tags and then makes them relative based on the site navigation\n        \"\"\"\n\n        for element in _iter(root):\n\n            if element.tag == 'a':\n                key = 'href'\n            elif element.tag == 'img':\n                key = 'src'\n            else:\n                continue\n\n            url = element.get(key)\n            new_url = path_to_url(url, self.site_navigation)\n            element.set(key, new_url)\n\n        return root\n\n\nclass RelativePathExtension(Extension):\n    \"\"\"\n    The Extension class is what we pass to markdown, it then\n    registers the Treeprocessor.\n    \"\"\"\n\n    def __init__(self, site_navigation):\n        self.site_navigation = site_navigation\n\n    def extendMarkdown(self, md, md_globals):\n        relpath = RelativePathTreeprocessor(self.site_navigation)\n        md.treeprocessors.add(\"relpath\", relpath, \"_end\")\n", "path": "mkdocs/relative_path_ext.py"}], "after_files": [{"content": "# coding: utf-8\n\n\"\"\"\nStandalone file utils.\n\nNothing in this module should have an knowledge of config or the layout\nand structure of the site and pages in the site.\n\"\"\"\n\nimport os\nimport shutil\n\nfrom mkdocs.compat import urlparse\n\n\ndef copy_file(source_path, output_path):\n    \"\"\"\n    Copy source_path to output_path, making sure any parent directories exist.\n    \"\"\"\n    output_dir = os.path.dirname(output_path)\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n    shutil.copy(source_path, output_path)\n\n\ndef write_file(content, output_path):\n    \"\"\"\n    Write content to output_path, making sure any parent directories exist.\n    \"\"\"\n    output_dir = os.path.dirname(output_path)\n    if not os.path.exists(output_dir):\n        os.makedirs(output_dir)\n    open(output_path, 'wb').write(content)\n\n\ndef clean_directory(directory):\n    \"\"\"\n    Remove the content of a directory recursively but not the directory itself.\n    \"\"\"\n    if os.path.exists(directory):\n        for entry in os.listdir(directory):\n            path = os.path.join(directory, entry)\n            if os.path.isdir(path):\n                shutil.rmtree(path, True)\n            else:\n                os.unlink(path)\n\n\ndef copy_media_files(from_dir, to_dir):\n    \"\"\"\n    Recursively copy all files except markdown and HTML into another directory.\n    \"\"\"\n    for (source_dir, dirnames, filenames) in os.walk(from_dir):\n        relative_path = os.path.relpath(source_dir, from_dir)\n        output_dir = os.path.normpath(os.path.join(to_dir, relative_path))\n\n        # Filter filenames starting with a '.'\n        filenames = [f for f in filenames if not f.startswith('.')]\n\n        # Filter the dirnames that start with a '.' and update the list in\n        # place to prevent us walking these.\n        dirnames[:] = [d for d in dirnames if not d.startswith('.')]\n\n        for filename in filenames:\n            if not is_markdown_file(filename) and not is_html_file(filename):\n                source_path = os.path.join(source_dir, filename)\n                output_path = os.path.join(output_dir, filename)\n                copy_file(source_path, output_path)\n\n\ndef get_html_path(path):\n    \"\"\"\n    Map a source file path to an output html path.\n\n    Paths like 'index.md' will be converted to 'index.html'\n    Paths like 'about.md' will be converted to 'about/index.html'\n    Paths like 'api-guide/core.md' will be converted to 'api-guide/core/index.html'\n    \"\"\"\n    path = os.path.splitext(path)[0]\n    if os.path.basename(path) == 'index':\n        return path + '.html'\n    return \"/\".join((path, 'index.html'))\n\n\ndef get_url_path(path, use_directory_urls=True):\n    \"\"\"\n    Map a source file path to an output html path.\n\n    Paths like 'index.md' will be converted to '/'\n    Paths like 'about.md' will be converted to '/about/'\n    Paths like 'api-guide/core.md' will be converted to '/api-guide/core/'\n\n    If `use_directory_urls` is `False`, returned URLs will include the a trailing\n    `index.html` rather than just returning the directory path.\n    \"\"\"\n    path = get_html_path(path)\n    url = '/' + path.replace(os.path.sep, '/')\n    if use_directory_urls:\n        return url[:-len('index.html')]\n    return url\n\n\ndef is_homepage(path):\n    return os.path.splitext(path)[0] == 'index'\n\n\ndef is_markdown_file(path):\n    \"\"\"\n    Return True if the given file path is a Markdown file.\n\n    http://superuser.com/questions/249436/file-extension-for-markdown-files\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.markdown',\n        '.mdown',\n        '.mkdn',\n        '.mkd',\n        '.md',\n    ]\n\n\ndef is_css_file(path):\n    \"\"\"\n    Return True if the given file path is a CSS file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.css',\n    ]\n\n\ndef is_javascript_file(path):\n    \"\"\"\n    Return True if the given file path is a Javascript file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.js',\n        '.javascript'\n    ]\n\n\ndef is_html_file(path):\n    \"\"\"\n    Return True if the given file path is an HTML file.\n    \"\"\"\n    ext = os.path.splitext(path)[1].lower()\n    return ext in [\n        '.html',\n        '.htm',\n    ]\n\n\ndef create_media_urls(nav, url_list):\n    \"\"\"\n    Return a list of URLs that have been processed correctly for inclusion in a page.\n    \"\"\"\n    final_urls = []\n    for url in url_list:\n        # Allow links to fully qualified URL's\n        parsed = urlparse(url)\n        if parsed.netloc:\n            final_urls.append(url)\n        else:\n            relative_url = '%s/%s' % (nav.url_context.make_relative('/'), url)\n            final_urls.append(relative_url)\n    return final_urls\n\n\ndef create_relative_media_url(nav, url):\n    \"\"\"\n    For a current page, create a relative url based on the given URL.\n\n    On index.md (which becomes /index.html):\n        image.png -> ./image.png\n        /image.png -> ./image.png\n\n    on sub/page.md (which becomes /sub/page/index.html):\n        image.png -> ../image.png\n        /image.png -> ../../image.png\n\n    \"\"\"\n\n    # Allow links to fully qualified URL's\n    parsed = urlparse(url)\n    if parsed.netloc:\n        return url\n\n    # If the URL we are looking at starts with a /, then it should be\n    # considered as absolute and will be 'relative' to the root.\n    if url.startswith('/'):\n        base = '/'\n        url = url[1:]\n    else:\n        base = nav.url_context.base_path\n\n    relative_url = '%s/%s' % (nav.url_context.make_relative(base), url)\n\n    # TODO: Fix this, this is a hack. Relative urls are not being calculated\n    # correctly for images in the same directory as the markdown. I think this\n    # is due to us moving it into a directory with index.html, but I'm not sure\n    if nav.url_context.base_path is not '/' and relative_url.startswith(\"./\"):\n        relative_url = \".%s\" % relative_url\n\n    return relative_url\n", "path": "mkdocs/utils.py"}, {"content": "\"\"\"\n# Relative Path Markdown Extension\n\nDuring the MkDocs build we rewrite URLs that link to local\nMarkdown or media files. Using the following pages configuration\nwe can look at how the output is changed.\n\n    pages:\n    - ['index.md']\n    - ['tutorial/install.md']\n    - ['tutorial/intro.md']\n\n## Markdown URLs\n\nWhen linking from `install.md` to `intro.md` the link would\nsimply be `[intro](intro.md)`. However, when we build\n`install.md` we place it in a directory to create nicer URLs.\nThis means that the path to `intro.md` becomes `../intro/`\n\n## Media URLs\n\nTo make it easier to work with media files and store them all\nunder one directory we re-write those to all be based on the\nroot. So, with the following markdown to add an image.\n\n    ![The initial MkDocs layout](img/initial-layout.png)\n\nThe output would depend on the location of the Markdown file it\nwas added too.\n\nSource file         | Generated Path    | Image Path                   |\n------------------- | ----------------- | ---------------------------- |\nindex.md            | /                 | ./img/initial-layout.png     |\ntutorial/install.md | tutorial/install/ | ../img/initial-layout.png    |\ntutorial/intro.md   | tutorial/intro/   | ../../img/initial-layout.png |\n\n\"\"\"\nfrom markdown.extensions import Extension\nfrom markdown.treeprocessors import Treeprocessor\n\nfrom mkdocs import utils\nfrom mkdocs.compat import urlparse, urlunparse\n\n\ndef _iter(node):\n    # TODO: Remove when dropping Python 2.6. Replace this\n    # function call with note.iter()\n    return [node] + node.findall('.//*')\n\n\ndef path_to_url(url, nav):\n    scheme, netloc, path, query, query, fragment = urlparse(url)\n\n    if scheme or netloc or not path:\n        # Ignore URLs unless they are a relative link to a markdown file.\n        return url\n\n    if nav and not utils.is_markdown_file(path):\n        path = utils.create_relative_media_url(nav, path)\n    elif nav:\n        # If the site navigation has been provided, then validate\n        # the internal hyperlink, making sure the target actually exists.\n        target_file = nav.file_context.make_absolute(path)\n        if target_file not in nav.source_files:\n            source_file = nav.file_context.current_file\n            msg = (\n                'The page \"%s\" contained a hyperlink to \"%s\" which '\n                'is not listed in the \"pages\" configuration.'\n            )\n            assert False, msg % (source_file, target_file)\n        path = utils.get_url_path(target_file, nav.use_directory_urls)\n        path = nav.url_context.make_relative(path)\n    else:\n        path = utils.get_url_path(path).lstrip('/')\n\n    # Convert the .md hyperlink to a relative hyperlink to the HTML page.\n    url = urlunparse((scheme, netloc, path, query, query, fragment))\n    return url\n\n\nclass RelativePathTreeprocessor(Treeprocessor):\n\n    def __init__(self, site_navigation):\n        self.site_navigation = site_navigation\n\n    def run(self, root):\n        \"\"\"Update urls on anchors and images to make them relative\n\n        Iterates through the full document tree looking for specific\n        tags and then makes them relative based on the site navigation\n        \"\"\"\n\n        for element in _iter(root):\n\n            if element.tag == 'a':\n                key = 'href'\n            elif element.tag == 'img':\n                key = 'src'\n            else:\n                continue\n\n            url = element.get(key)\n            new_url = path_to_url(url, self.site_navigation)\n            element.set(key, new_url)\n\n        return root\n\n\nclass RelativePathExtension(Extension):\n    \"\"\"\n    The Extension class is what we pass to markdown, it then\n    registers the Treeprocessor.\n    \"\"\"\n\n    def __init__(self, site_navigation):\n        self.site_navigation = site_navigation\n\n    def extendMarkdown(self, md, md_globals):\n        relpath = RelativePathTreeprocessor(self.site_navigation)\n        md.treeprocessors.add(\"relpath\", relpath, \"_end\")\n", "path": "mkdocs/relative_path_ext.py"}]}