Repository: mkdocs/mkdocs

Issue:
Absolute paths with backward slashes
@waylan Sorry you to bother you again on this, but I have one more small question.

On one of your postings you mentioned a difference between a path (all with "\\") and a link (all with "/").
In mkdocs I see now I've mixed them up completely for linking to -for example- local images. This has always worked without any issue.

However, there is a difference in link resolution between:

```markdown
[absolute url](/imgs/image.png)

[absolute path](\imgs\image.png)
```
First one results in a absolute html link. The second a relative one. 
Is is behaviour intentional ? I hope so as it will solve an issue I am having. If not I'd really like to know before building on it while running the risk of this behaviour being changed in the future.

I hope I am not asking the obvious. I've checked the docs but don't seem to find any mention of this.

Thanks. Sander.


Discussion:
Strictly speaking, we don't support using backslashes in links at all. Backslashes are only used in local paths by Windows. All other (popular) OSes (Mac, Linux, BSD, etc) all only use forward slashes. Therefore, if you want your site to be buildable on any platform, you should only use forward slashes. Of course, users don't always know or understand that, so the first thing MkDocs does when it receives a local path is convert all slashes to [os.sep][1]. When accessing the local file system, Python will convert any path to use `os.sep` automatically.

The one difference is that MkDocs does not make any changes to an absolute URL. The assumption is that the user carefully crafted that URL and we shouldn't muck it up. We determine that a URL is absolute by checking for `http...`, or a `/`. Of course, `\` isn't matched there (perhaps is should be -- see below).  The difference is that a path with a backslash can only ever be a local path, while a path with forward slashes could be either. Because the backward slash causes MkDocs to not see it as a absolute path, it gets processed (slashes are converted, ect).

Remember, we consider absolute paths to be web URLs, not local paths. The problem I'm having trouble reconciling is that the local path `\img\image.png` should resolve to `C:\\img\image.png` (or the local path `/img/image.png` on POSIX systems) which is almost certainly not what you want. So, yeah, this feels like a bug, but the correct behavior is not clear to me. I would strongly suggest you avoid relying on it as a workaround. The behavior is likely to change without notice at any time in the future.

[1]: https://docs.python.org/2/library/os.html#os.sep
I should clarify what appears to be a conflict between the terminology used in my comment and the original question. 

MkDocs considers all relative links in Markdown documents to be **local paths** and all absolute links in Markdown documents to be **URLs**. Both local paths and URLs contain a "path," so I use the term "path" when referring to both types of links. 

Of course, the issue is that MkDocs (incorrectly?) identifies links which start with a backward slash to be local paths. when they probably should be identified as absolute links. But it doesn't make sense to leave them unaltered as backslashes are not used in web URLs.  We have three options:

1. Consider them to be absolute links and convert them to absolute web URLs by replacing backslashes with forward slashes (no additional modifications would be done).
2. Consider them to be absolute local paths (this is the behavior we would get is we fixed the bug which is removing the opening slash).
3. Consider them to be relative local paths (current behavior).

I can see an argument for either 1 or 2, although, I'm having difficulty seeing a relevant use-case for option 2 even though is the least surprising behavior IMO. And option 3 seems non-sensical given how we treat all other links.
I'm reopening this as there is definitely a bug here.
On further reflection, it is possible that a backwards slash could legitimately exist in a path (just not as a separator). Therefore, doing a wholesale replacement of all backslashes with forward slashes could break some URLs. Therefore, we need to go with option 2: ignore paths which start with a backward slash.

Resolving patch:
diff --git a/mkdocs/structure/pages.py b/mkdocs/structure/pages.py
--- a/mkdocs/structure/pages.py
+++ b/mkdocs/structure/pages.py
@@ -213,7 +213,7 @@ def run(self, root):
     def path_to_url(self, url):
         scheme, netloc, path, params, query, fragment = urlparse(url)
 
-        if (scheme or netloc or not path or url.startswith('/')
+        if (scheme or netloc or not path or url.startswith('/') or url.startswith('\\')
                 or AMP_SUBSTITUTE in url or '.' not in os.path.split(path)[-1]):
             # Ignore URLs unless they are a relative link to a source file.
             # AMP_SUBSTITUTE is used internally by Markdown only for email.


Test patch:
diff --git a/mkdocs/tests/structure/page_tests.py b/mkdocs/tests/structure/page_tests.py
--- a/mkdocs/tests/structure/page_tests.py
+++ b/mkdocs/tests/structure/page_tests.py
@@ -833,6 +833,13 @@ def test_absolute_link(self):
             '<p><a href="/path/to/file.md">absolute link</a></p>'
         )
 
+    @mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[absolute local path](\\image.png)'))
+    def test_absolute_win_local_path(self):
+        self.assertEqual(
+            self.get_rendered_result(['index.md']),
+            '<p><a href="\\image.png">absolute local path</a></p>'
+        )
+
     @mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='<mail@example.com>'))
     def test_email_link(self):
         self.assertEqual(