We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
README.md -> index.md should be optional
This is a really useful feature, but it should be optional.

I have a `README.md` file in my repository exclusively to render it on GitHub, indicating that the documentation uses format not compatible with GitHub, and that it should be viewed on the generated site.

See: https://github.com/Galarzaa90/NabBot/tree/master/docs

Now, I also have an `index.md` file in the `docs` folder, and that is the actual homepage of my site, and now it is getting overriden by `README.md` and there's no way to see the homepage anymore.

See:
- https://galarzaa90.github.io/NabBot/ - Generated Site
- https://github.com/Galarzaa90/NabBot/blob/master/docs/index.md  - My index.md file

And this is my `pages`/`nav` section:
```yml
nav:
    - Home: index.md
    - Changelog: changelog.md
    - Install Guide: install.md
    - Permissions: permissions.md
    - FAQ: faq.md
    - Features:
      - Overview: features/index.md
      - Autoroles: features/autoroles.md
      - Groups: features/groups.md
    - Commands:
      - Overview: commands/index.md
      - Admin commands: commands/admin.md
      - General commands: commands/general.md
      - Info commands: commands/info.md
      - Loot commands: commands/loot.md
      - Mod commands: commands/mod.md
      - Owner commands: commands/owner.md
      - Roles commands: commands/roles.md
      - Settings commands: commands/settings.md
      - Tibia commands: commands/tibia.md
      - TibiaWiki commands: commands/tibiawiki.md
      - Tracking commands: commands/tracking.md
    - Hosting:
      - Configuration: hosting/config.md
      - Messages: hosting/messages.md
      - Cogs: hosting/cogs.md
```

Full file: https://github.com/Galarzaa90/NabBot/blob/master/mkdocs.yml

--- 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/structure/files.py`
Content:
```
1 # coding: utf-8
2 
3 from __future__ import unicode_literals
4 import fnmatch
5 import os
6 import logging
7 from functools import cmp_to_key
8 
9 from mkdocs import utils
10 
11 
12 log = logging.getLogger(__name__)
13 
14 
15 class Files(object):
16     """ A collection of File objects. """
17     def __init__(self, files):
18         self._files = files
19         self.src_paths = {file.src_path: file for file in files}
20 
21     def __iter__(self):
22         return iter(self._files)
23 
24     def __len__(self):
25         return len(self._files)
26 
27     def __contains__(self, path):
28         return path in self.src_paths
29 
30     def get_file_from_path(self, path):
31         """ Return a File instance with File.src_path equal to path. """
32         return self.src_paths.get(os.path.normpath(path))
33 
34     def append(self, file):
35         """ Append file to Files collection. """
36         self._files.append(file)
37         self.src_paths[file.src_path] = file
38 
39     def copy_static_files(self, dirty=False):
40         """ Copy static files from source to destination. """
41         for file in self:
42             if not file.is_documentation_page():
43                 file.copy_file(dirty)
44 
45     def documentation_pages(self):
46         """ Return iterable of all Markdown page file objects. """
47         return [file for file in self if file.is_documentation_page()]
48 
49     def static_pages(self):
50         """ Return iterable of all static page file objects. """
51         return [file for file in self if file.is_static_page()]
52 
53     def media_files(self):
54         """ Return iterable of all file objects which are not documentation or static pages. """
55         return [file for file in self if file.is_media_file()]
56 
57     def javascript_files(self):
58         """ Return iterable of all javascript file objects. """
59         return [file for file in self if file.is_javascript()]
60 
61     def css_files(self):
62         """ Return iterable of all CSS file objects. """
63         return [file for file in self if file.is_css()]
64 
65     def add_files_from_theme(self, env, config):
66         """ Retrieve static files from Jinja environment and add to collection. """
67         def filter(name):
68             patterns = ['.*', '*.py', '*.pyc', '*.html', 'mkdocs_theme.yml']
69             patterns.extend(config['theme'].static_templates)
70             for pattern in patterns:
71                 if fnmatch.fnmatch(name, pattern):
72                     return False
73             return True
74         for path in env.list_templates(filter_func=filter):
75             for dir in config['theme'].dirs:
76                 # Find the first theme dir which contains path
77                 if os.path.isfile(os.path.join(dir, path)):
78                     self.append(File(path, dir, config['site_dir'], config['use_directory_urls']))
79                     break
80 
81 
82 class File(object):
83     """
84     A MkDocs File object.
85 
86     Points to the source and destination locations of a file.
87 
88     The `path` argument must be a path that exists relative to `src_dir`.
89 
90     The `src_dir` and `dest_dir` must be absolute paths on the local file system.
91 
92     The `use_directory_urls` argument controls how destination paths are generated. If `False`, a Markdown file is
93     mapped to an HTML file of the same name (the file extension is changed to `.html`). If True, a Markdown file is
94     mapped to an HTML index file (`index.html`) nested in a directory using the "name" of the file in `path`. The
95     `use_directory_urls` argument has no effect on non-Markdown files.
96 
97     File objects have the following properties, which are Unicode strings:
98 
99     File.src_path
100         The pure path of the source file relative to the source directory.
101 
102     File.abs_src_path
103         The absolute concrete path of the source file.
104 
105     File.dest_path
106         The pure path of the destination file relative to the destination directory.
107 
108     File.abs_dest_path
109         The absolute concrete path of the destination file.
110 
111     File.url
112         The url of the destination file relative to the destination directory as a string.
113     """
114     def __init__(self, path, src_dir, dest_dir, use_directory_urls):
115         self.page = None
116         self.src_path = os.path.normpath(path)
117         self.abs_src_path = os.path.normpath(os.path.join(src_dir, self.src_path))
118         self.name = self._get_stem()
119         self.dest_path = self._get_dest_path(use_directory_urls)
120         self.abs_dest_path = os.path.normpath(os.path.join(dest_dir, self.dest_path))
121         self.url = self._get_url(use_directory_urls)
122 
123     def __eq__(self, other):
124 
125         def sub_dict(d):
126             return dict((key, value) for key, value in d.items() if key in ['src_path', 'abs_src_path', 'url'])
127 
128         return (isinstance(other, self.__class__) and sub_dict(self.__dict__) == sub_dict(other.__dict__))
129 
130     def __ne__(self, other):
131         return not self.__eq__(other)
132 
133     def _get_stem(self):
134         """ Return the name of the file without it's extension. """
135         filename = os.path.basename(self.src_path)
136         stem, ext = os.path.splitext(filename)
137         return 'index' if stem in ('index', 'README') else stem
138 
139     def _get_dest_path(self, use_directory_urls):
140         """ Return destination path based on source path. """
141         if self.is_documentation_page():
142             if use_directory_urls:
143                 parent, filename = os.path.split(self.src_path)
144                 if self.name == 'index':
145                     # index.md or README.md => index.html
146                     return os.path.join(parent, 'index.html')
147                 else:
148                     # foo.md => foo/index.html
149                     return os.path.join(parent, self.name, 'index.html')
150             else:
151                 # foo.md => foo.html
152                 root, ext = os.path.splitext(self.src_path)
153                 return root + '.html'
154         return self.src_path
155 
156     def _get_url(self, use_directory_urls):
157         """ Return url based in destination path. """
158         url = self.dest_path.replace(os.path.sep, '/')
159         dirname, filename = os.path.split(url)
160         if use_directory_urls and filename == 'index.html':
161             if dirname == '':
162                 url = '.'
163             else:
164                 url = dirname + '/'
165         return url
166 
167     def url_relative_to(self, other):
168         """ Return url for file relative to other file. """
169         return utils.get_relative_url(self.url, other.url if isinstance(other, File) else other)
170 
171     def copy_file(self, dirty=False):
172         """ Copy source file to destination, ensuring parent directories exist. """
173         if dirty and not self.is_modified():
174             log.debug("Skip copying unmodified file: '{}'".format(self.src_path))
175         else:
176             log.debug("Copying media file: '{}'".format(self.src_path))
177             utils.copy_file(self.abs_src_path, self.abs_dest_path)
178 
179     def is_modified(self):
180         if os.path.isfile(self.abs_dest_path):
181             return os.path.getmtime(self.abs_dest_path) < os.path.getmtime(self.abs_src_path)
182         return True
183 
184     def is_documentation_page(self):
185         """ Return True if file is a Markdown page. """
186         return os.path.splitext(self.src_path)[1] in utils.markdown_extensions
187 
188     def is_static_page(self):
189         """ Return True if file is a static page (html, xml, json). """
190         return os.path.splitext(self.src_path)[1] in (
191             '.html',
192             '.htm',
193             '.xml',
194             '.json',
195         )
196 
197     def is_media_file(self):
198         """ Return True if file is not a documentation or static page. """
199         return not (self.is_documentation_page() or self.is_static_page())
200 
201     def is_javascript(self):
202         """ Return True if file is a JavaScript file. """
203         return os.path.splitext(self.src_path)[1] in (
204             '.js',
205             '.javascript',
206         )
207 
208     def is_css(self):
209         """ Return True if file is a CSS file. """
210         return os.path.splitext(self.src_path)[1] in (
211             '.css',
212         )
213 
214 
215 def get_files(config):
216     """ Walk the `docs_dir` and return a Files collection. """
217     files = []
218     exclude = ['.*', '/templates']
219 
220     for source_dir, dirnames, filenames in os.walk(config['docs_dir'], followlinks=True):
221         relative_dir = os.path.relpath(source_dir, config['docs_dir'])
222 
223         for dirname in list(dirnames):
224             path = os.path.normpath(os.path.join(relative_dir, dirname))
225             # Skip any excluded directories
226             if _filter_paths(basename=dirname, path=path, is_dir=True, exclude=exclude):
227                 dirnames.remove(dirname)
228         dirnames.sort()
229 
230         for filename in _sort_files(filenames):
231             path = os.path.normpath(os.path.join(relative_dir, filename))
232             # Skip any excluded files
233             if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):
234                 continue
235             files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))
236 
237     return Files(files)
238 
239 
240 def _sort_files(filenames):
241     """ Always sort `index` as first filename in list. """
242 
243     def compare(x, y):
244         if x == y:
245             return 0
246         if os.path.splitext(y)[0] == 'index':
247             return 1
248         if os.path.splitext(x)[0] == 'index' or x < y:
249             return -1
250         return 1
251 
252     return sorted(filenames, key=cmp_to_key(compare))
253 
254 
255 def _filter_paths(basename, path, is_dir, exclude):
256     """ .gitignore style file filtering. """
257     for item in exclude:
258         # Items ending in '/' apply only to directories.
259         if item.endswith('/') and not is_dir:
260             continue
261         # Items starting with '/' apply to the whole path.
262         # In any other cases just the basename is used.
263         match = path if item.startswith('/') else basename
264         if fnmatch.fnmatch(match, item.strip('/')):
265             return True
266     return False
267
```
--- 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/structure/files.py b/mkdocs/structure/files.py
--- a/mkdocs/structure/files.py
+++ b/mkdocs/structure/files.py
@@ -232,20 +232,23 @@
             # Skip any excluded files
             if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):
                 continue
+            # Skip README.md is an index file also exists in dir
+            if filename.lower() == 'readme.md' and 'index.md' in filenames:
+                continue
             files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))
 
     return Files(files)
 
 
 def _sort_files(filenames):
-    """ Always sort `index` as first filename in list. """
+    """ Always sort `index` or `README` as first filename in list. """
 
     def compare(x, y):
         if x == y:
             return 0
-        if os.path.splitext(y)[0] == 'index':
+        if os.path.splitext(y)[0] in ['index', 'README']:
             return 1
-        if os.path.splitext(x)[0] == 'index' or x < y:
+        if os.path.splitext(x)[0] in ['index', 'README'] or x < y:
             return -1
         return 1

{"golden_diff": "diff --git a/mkdocs/structure/files.py b/mkdocs/structure/files.py\n--- a/mkdocs/structure/files.py\n+++ b/mkdocs/structure/files.py\n@@ -232,20 +232,23 @@\n             # Skip any excluded files\n             if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):\n                 continue\n+            # Skip README.md is an index file also exists in dir\n+            if filename.lower() == 'readme.md' and 'index.md' in filenames:\n+                continue\n             files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))\n \n     return Files(files)\n \n \n def _sort_files(filenames):\n-    \"\"\" Always sort `index` as first filename in list. \"\"\"\n+    \"\"\" Always sort `index` or `README` as first filename in list. \"\"\"\n \n     def compare(x, y):\n         if x == y:\n             return 0\n-        if os.path.splitext(y)[0] == 'index':\n+        if os.path.splitext(y)[0] in ['index', 'README']:\n             return 1\n-        if os.path.splitext(x)[0] == 'index' or x < y:\n+        if os.path.splitext(x)[0] in ['index', 'README'] or x < y:\n             return -1\n         return 1\n", "issue": "README.md -> index.md should be optional\nThis is a really useful feature, but it should be optional.\r\n\r\nI have a `README.md` file in my repository exclusively to render it on GitHub, indicating that the documentation uses format not compatible with GitHub, and that it should be viewed on the generated site.\r\n\r\nSee: https://github.com/Galarzaa90/NabBot/tree/master/docs\r\n\r\nNow, I also have an `index.md` file in the `docs` folder, and that is the actual homepage of my site, and now it is getting overriden by `README.md` and there's no way to see the homepage anymore.\r\n\r\nSee:\r\n- https://galarzaa90.github.io/NabBot/ - Generated Site\r\n- https://github.com/Galarzaa90/NabBot/blob/master/docs/index.md  - My index.md file\r\n\r\nAnd this is my `pages`/`nav` section:\r\n```yml\r\nnav:\r\n    - Home: index.md\r\n    - Changelog: changelog.md\r\n    - Install Guide: install.md\r\n    - Permissions: permissions.md\r\n    - FAQ: faq.md\r\n    - Features:\r\n      - Overview: features/index.md\r\n      - Autoroles: features/autoroles.md\r\n      - Groups: features/groups.md\r\n    - Commands:\r\n      - Overview: commands/index.md\r\n      - Admin commands: commands/admin.md\r\n      - General commands: commands/general.md\r\n      - Info commands: commands/info.md\r\n      - Loot commands: commands/loot.md\r\n      - Mod commands: commands/mod.md\r\n      - Owner commands: commands/owner.md\r\n      - Roles commands: commands/roles.md\r\n      - Settings commands: commands/settings.md\r\n      - Tibia commands: commands/tibia.md\r\n      - TibiaWiki commands: commands/tibiawiki.md\r\n      - Tracking commands: commands/tracking.md\r\n    - Hosting:\r\n      - Configuration: hosting/config.md\r\n      - Messages: hosting/messages.md\r\n      - Cogs: hosting/cogs.md\r\n```\r\n\r\nFull file: https://github.com/Galarzaa90/NabBot/blob/master/mkdocs.yml\n", "before_files": [{"content": "# coding: utf-8\n\nfrom __future__ import unicode_literals\nimport fnmatch\nimport os\nimport logging\nfrom functools import cmp_to_key\n\nfrom mkdocs import utils\n\n\nlog = logging.getLogger(__name__)\n\n\nclass Files(object):\n    \"\"\" A collection of File objects. \"\"\"\n    def __init__(self, files):\n        self._files = files\n        self.src_paths = {file.src_path: file for file in files}\n\n    def __iter__(self):\n        return iter(self._files)\n\n    def __len__(self):\n        return len(self._files)\n\n    def __contains__(self, path):\n        return path in self.src_paths\n\n    def get_file_from_path(self, path):\n        \"\"\" Return a File instance with File.src_path equal to path. \"\"\"\n        return self.src_paths.get(os.path.normpath(path))\n\n    def append(self, file):\n        \"\"\" Append file to Files collection. \"\"\"\n        self._files.append(file)\n        self.src_paths[file.src_path] = file\n\n    def copy_static_files(self, dirty=False):\n        \"\"\" Copy static files from source to destination. \"\"\"\n        for file in self:\n            if not file.is_documentation_page():\n                file.copy_file(dirty)\n\n    def documentation_pages(self):\n        \"\"\" Return iterable of all Markdown page file objects. \"\"\"\n        return [file for file in self if file.is_documentation_page()]\n\n    def static_pages(self):\n        \"\"\" Return iterable of all static page file objects. \"\"\"\n        return [file for file in self if file.is_static_page()]\n\n    def media_files(self):\n        \"\"\" Return iterable of all file objects which are not documentation or static pages. \"\"\"\n        return [file for file in self if file.is_media_file()]\n\n    def javascript_files(self):\n        \"\"\" Return iterable of all javascript file objects. \"\"\"\n        return [file for file in self if file.is_javascript()]\n\n    def css_files(self):\n        \"\"\" Return iterable of all CSS file objects. \"\"\"\n        return [file for file in self if file.is_css()]\n\n    def add_files_from_theme(self, env, config):\n        \"\"\" Retrieve static files from Jinja environment and add to collection. \"\"\"\n        def filter(name):\n            patterns = ['.*', '*.py', '*.pyc', '*.html', 'mkdocs_theme.yml']\n            patterns.extend(config['theme'].static_templates)\n            for pattern in patterns:\n                if fnmatch.fnmatch(name, pattern):\n                    return False\n            return True\n        for path in env.list_templates(filter_func=filter):\n            for dir in config['theme'].dirs:\n                # Find the first theme dir which contains path\n                if os.path.isfile(os.path.join(dir, path)):\n                    self.append(File(path, dir, config['site_dir'], config['use_directory_urls']))\n                    break\n\n\nclass File(object):\n    \"\"\"\n    A MkDocs File object.\n\n    Points to the source and destination locations of a file.\n\n    The `path` argument must be a path that exists relative to `src_dir`.\n\n    The `src_dir` and `dest_dir` must be absolute paths on the local file system.\n\n    The `use_directory_urls` argument controls how destination paths are generated. If `False`, a Markdown file is\n    mapped to an HTML file of the same name (the file extension is changed to `.html`). If True, a Markdown file is\n    mapped to an HTML index file (`index.html`) nested in a directory using the \"name\" of the file in `path`. The\n    `use_directory_urls` argument has no effect on non-Markdown files.\n\n    File objects have the following properties, which are Unicode strings:\n\n    File.src_path\n        The pure path of the source file relative to the source directory.\n\n    File.abs_src_path\n        The absolute concrete path of the source file.\n\n    File.dest_path\n        The pure path of the destination file relative to the destination directory.\n\n    File.abs_dest_path\n        The absolute concrete path of the destination file.\n\n    File.url\n        The url of the destination file relative to the destination directory as a string.\n    \"\"\"\n    def __init__(self, path, src_dir, dest_dir, use_directory_urls):\n        self.page = None\n        self.src_path = os.path.normpath(path)\n        self.abs_src_path = os.path.normpath(os.path.join(src_dir, self.src_path))\n        self.name = self._get_stem()\n        self.dest_path = self._get_dest_path(use_directory_urls)\n        self.abs_dest_path = os.path.normpath(os.path.join(dest_dir, self.dest_path))\n        self.url = self._get_url(use_directory_urls)\n\n    def __eq__(self, other):\n\n        def sub_dict(d):\n            return dict((key, value) for key, value in d.items() if key in ['src_path', 'abs_src_path', 'url'])\n\n        return (isinstance(other, self.__class__) and sub_dict(self.__dict__) == sub_dict(other.__dict__))\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def _get_stem(self):\n        \"\"\" Return the name of the file without it's extension. \"\"\"\n        filename = os.path.basename(self.src_path)\n        stem, ext = os.path.splitext(filename)\n        return 'index' if stem in ('index', 'README') else stem\n\n    def _get_dest_path(self, use_directory_urls):\n        \"\"\" Return destination path based on source path. \"\"\"\n        if self.is_documentation_page():\n            if use_directory_urls:\n                parent, filename = os.path.split(self.src_path)\n                if self.name == 'index':\n                    # index.md or README.md => index.html\n                    return os.path.join(parent, 'index.html')\n                else:\n                    # foo.md => foo/index.html\n                    return os.path.join(parent, self.name, 'index.html')\n            else:\n                # foo.md => foo.html\n                root, ext = os.path.splitext(self.src_path)\n                return root + '.html'\n        return self.src_path\n\n    def _get_url(self, use_directory_urls):\n        \"\"\" Return url based in destination path. \"\"\"\n        url = self.dest_path.replace(os.path.sep, '/')\n        dirname, filename = os.path.split(url)\n        if use_directory_urls and filename == 'index.html':\n            if dirname == '':\n                url = '.'\n            else:\n                url = dirname + '/'\n        return url\n\n    def url_relative_to(self, other):\n        \"\"\" Return url for file relative to other file. \"\"\"\n        return utils.get_relative_url(self.url, other.url if isinstance(other, File) else other)\n\n    def copy_file(self, dirty=False):\n        \"\"\" Copy source file to destination, ensuring parent directories exist. \"\"\"\n        if dirty and not self.is_modified():\n            log.debug(\"Skip copying unmodified file: '{}'\".format(self.src_path))\n        else:\n            log.debug(\"Copying media file: '{}'\".format(self.src_path))\n            utils.copy_file(self.abs_src_path, self.abs_dest_path)\n\n    def is_modified(self):\n        if os.path.isfile(self.abs_dest_path):\n            return os.path.getmtime(self.abs_dest_path) < os.path.getmtime(self.abs_src_path)\n        return True\n\n    def is_documentation_page(self):\n        \"\"\" Return True if file is a Markdown page. \"\"\"\n        return os.path.splitext(self.src_path)[1] in utils.markdown_extensions\n\n    def is_static_page(self):\n        \"\"\" Return True if file is a static page (html, xml, json). \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.html',\n            '.htm',\n            '.xml',\n            '.json',\n        )\n\n    def is_media_file(self):\n        \"\"\" Return True if file is not a documentation or static page. \"\"\"\n        return not (self.is_documentation_page() or self.is_static_page())\n\n    def is_javascript(self):\n        \"\"\" Return True if file is a JavaScript file. \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.js',\n            '.javascript',\n        )\n\n    def is_css(self):\n        \"\"\" Return True if file is a CSS file. \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.css',\n        )\n\n\ndef get_files(config):\n    \"\"\" Walk the `docs_dir` and return a Files collection. \"\"\"\n    files = []\n    exclude = ['.*', '/templates']\n\n    for source_dir, dirnames, filenames in os.walk(config['docs_dir'], followlinks=True):\n        relative_dir = os.path.relpath(source_dir, config['docs_dir'])\n\n        for dirname in list(dirnames):\n            path = os.path.normpath(os.path.join(relative_dir, dirname))\n            # Skip any excluded directories\n            if _filter_paths(basename=dirname, path=path, is_dir=True, exclude=exclude):\n                dirnames.remove(dirname)\n        dirnames.sort()\n\n        for filename in _sort_files(filenames):\n            path = os.path.normpath(os.path.join(relative_dir, filename))\n            # Skip any excluded files\n            if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):\n                continue\n            files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))\n\n    return Files(files)\n\n\ndef _sort_files(filenames):\n    \"\"\" Always sort `index` as first filename in list. \"\"\"\n\n    def compare(x, y):\n        if x == y:\n            return 0\n        if os.path.splitext(y)[0] == 'index':\n            return 1\n        if os.path.splitext(x)[0] == 'index' or x < y:\n            return -1\n        return 1\n\n    return sorted(filenames, key=cmp_to_key(compare))\n\n\ndef _filter_paths(basename, path, is_dir, exclude):\n    \"\"\" .gitignore style file filtering. \"\"\"\n    for item in exclude:\n        # Items ending in '/' apply only to directories.\n        if item.endswith('/') and not is_dir:\n            continue\n        # Items starting with '/' apply to the whole path.\n        # In any other cases just the basename is used.\n        match = path if item.startswith('/') else basename\n        if fnmatch.fnmatch(match, item.strip('/')):\n            return True\n    return False\n", "path": "mkdocs/structure/files.py"}], "after_files": [{"content": "# coding: utf-8\n\nfrom __future__ import unicode_literals\nimport fnmatch\nimport os\nimport logging\nfrom functools import cmp_to_key\n\nfrom mkdocs import utils\n\n\nlog = logging.getLogger(__name__)\n\n\nclass Files(object):\n    \"\"\" A collection of File objects. \"\"\"\n    def __init__(self, files):\n        self._files = files\n        self.src_paths = {file.src_path: file for file in files}\n\n    def __iter__(self):\n        return iter(self._files)\n\n    def __len__(self):\n        return len(self._files)\n\n    def __contains__(self, path):\n        return path in self.src_paths\n\n    def get_file_from_path(self, path):\n        \"\"\" Return a File instance with File.src_path equal to path. \"\"\"\n        return self.src_paths.get(os.path.normpath(path))\n\n    def append(self, file):\n        \"\"\" Append file to Files collection. \"\"\"\n        self._files.append(file)\n        self.src_paths[file.src_path] = file\n\n    def copy_static_files(self, dirty=False):\n        \"\"\" Copy static files from source to destination. \"\"\"\n        for file in self:\n            if not file.is_documentation_page():\n                file.copy_file(dirty)\n\n    def documentation_pages(self):\n        \"\"\" Return iterable of all Markdown page file objects. \"\"\"\n        return [file for file in self if file.is_documentation_page()]\n\n    def static_pages(self):\n        \"\"\" Return iterable of all static page file objects. \"\"\"\n        return [file for file in self if file.is_static_page()]\n\n    def media_files(self):\n        \"\"\" Return iterable of all file objects which are not documentation or static pages. \"\"\"\n        return [file for file in self if file.is_media_file()]\n\n    def javascript_files(self):\n        \"\"\" Return iterable of all javascript file objects. \"\"\"\n        return [file for file in self if file.is_javascript()]\n\n    def css_files(self):\n        \"\"\" Return iterable of all CSS file objects. \"\"\"\n        return [file for file in self if file.is_css()]\n\n    def add_files_from_theme(self, env, config):\n        \"\"\" Retrieve static files from Jinja environment and add to collection. \"\"\"\n        def filter(name):\n            patterns = ['.*', '*.py', '*.pyc', '*.html', 'mkdocs_theme.yml']\n            patterns.extend(config['theme'].static_templates)\n            for pattern in patterns:\n                if fnmatch.fnmatch(name, pattern):\n                    return False\n            return True\n        for path in env.list_templates(filter_func=filter):\n            for dir in config['theme'].dirs:\n                # Find the first theme dir which contains path\n                if os.path.isfile(os.path.join(dir, path)):\n                    self.append(File(path, dir, config['site_dir'], config['use_directory_urls']))\n                    break\n\n\nclass File(object):\n    \"\"\"\n    A MkDocs File object.\n\n    Points to the source and destination locations of a file.\n\n    The `path` argument must be a path that exists relative to `src_dir`.\n\n    The `src_dir` and `dest_dir` must be absolute paths on the local file system.\n\n    The `use_directory_urls` argument controls how destination paths are generated. If `False`, a Markdown file is\n    mapped to an HTML file of the same name (the file extension is changed to `.html`). If True, a Markdown file is\n    mapped to an HTML index file (`index.html`) nested in a directory using the \"name\" of the file in `path`. The\n    `use_directory_urls` argument has no effect on non-Markdown files.\n\n    File objects have the following properties, which are Unicode strings:\n\n    File.src_path\n        The pure path of the source file relative to the source directory.\n\n    File.abs_src_path\n        The absolute concrete path of the source file.\n\n    File.dest_path\n        The pure path of the destination file relative to the destination directory.\n\n    File.abs_dest_path\n        The absolute concrete path of the destination file.\n\n    File.url\n        The url of the destination file relative to the destination directory as a string.\n    \"\"\"\n    def __init__(self, path, src_dir, dest_dir, use_directory_urls):\n        self.page = None\n        self.src_path = os.path.normpath(path)\n        self.abs_src_path = os.path.normpath(os.path.join(src_dir, self.src_path))\n        self.name = self._get_stem()\n        self.dest_path = self._get_dest_path(use_directory_urls)\n        self.abs_dest_path = os.path.normpath(os.path.join(dest_dir, self.dest_path))\n        self.url = self._get_url(use_directory_urls)\n\n    def __eq__(self, other):\n\n        def sub_dict(d):\n            return dict((key, value) for key, value in d.items() if key in ['src_path', 'abs_src_path', 'url'])\n\n        return (isinstance(other, self.__class__) and sub_dict(self.__dict__) == sub_dict(other.__dict__))\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def _get_stem(self):\n        \"\"\" Return the name of the file without it's extension. \"\"\"\n        filename = os.path.basename(self.src_path)\n        stem, ext = os.path.splitext(filename)\n        return 'index' if stem in ('index', 'README') else stem\n\n    def _get_dest_path(self, use_directory_urls):\n        \"\"\" Return destination path based on source path. \"\"\"\n        if self.is_documentation_page():\n            if use_directory_urls:\n                parent, filename = os.path.split(self.src_path)\n                if self.name == 'index':\n                    # index.md or README.md => index.html\n                    return os.path.join(parent, 'index.html')\n                else:\n                    # foo.md => foo/index.html\n                    return os.path.join(parent, self.name, 'index.html')\n            else:\n                # foo.md => foo.html\n                root, ext = os.path.splitext(self.src_path)\n                return root + '.html'\n        return self.src_path\n\n    def _get_url(self, use_directory_urls):\n        \"\"\" Return url based in destination path. \"\"\"\n        url = self.dest_path.replace(os.path.sep, '/')\n        dirname, filename = os.path.split(url)\n        if use_directory_urls and filename == 'index.html':\n            if dirname == '':\n                url = '.'\n            else:\n                url = dirname + '/'\n        return url\n\n    def url_relative_to(self, other):\n        \"\"\" Return url for file relative to other file. \"\"\"\n        return utils.get_relative_url(self.url, other.url if isinstance(other, File) else other)\n\n    def copy_file(self, dirty=False):\n        \"\"\" Copy source file to destination, ensuring parent directories exist. \"\"\"\n        if dirty and not self.is_modified():\n            log.debug(\"Skip copying unmodified file: '{}'\".format(self.src_path))\n        else:\n            log.debug(\"Copying media file: '{}'\".format(self.src_path))\n            utils.copy_file(self.abs_src_path, self.abs_dest_path)\n\n    def is_modified(self):\n        if os.path.isfile(self.abs_dest_path):\n            return os.path.getmtime(self.abs_dest_path) < os.path.getmtime(self.abs_src_path)\n        return True\n\n    def is_documentation_page(self):\n        \"\"\" Return True if file is a Markdown page. \"\"\"\n        return os.path.splitext(self.src_path)[1] in utils.markdown_extensions\n\n    def is_static_page(self):\n        \"\"\" Return True if file is a static page (html, xml, json). \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.html',\n            '.htm',\n            '.xml',\n            '.json',\n        )\n\n    def is_media_file(self):\n        \"\"\" Return True if file is not a documentation or static page. \"\"\"\n        return not (self.is_documentation_page() or self.is_static_page())\n\n    def is_javascript(self):\n        \"\"\" Return True if file is a JavaScript file. \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.js',\n            '.javascript',\n        )\n\n    def is_css(self):\n        \"\"\" Return True if file is a CSS file. \"\"\"\n        return os.path.splitext(self.src_path)[1] in (\n            '.css',\n        )\n\n\ndef get_files(config):\n    \"\"\" Walk the `docs_dir` and return a Files collection. \"\"\"\n    files = []\n    exclude = ['.*', '/templates']\n\n    for source_dir, dirnames, filenames in os.walk(config['docs_dir'], followlinks=True):\n        relative_dir = os.path.relpath(source_dir, config['docs_dir'])\n\n        for dirname in list(dirnames):\n            path = os.path.normpath(os.path.join(relative_dir, dirname))\n            # Skip any excluded directories\n            if _filter_paths(basename=dirname, path=path, is_dir=True, exclude=exclude):\n                dirnames.remove(dirname)\n        dirnames.sort()\n\n        for filename in _sort_files(filenames):\n            path = os.path.normpath(os.path.join(relative_dir, filename))\n            # Skip any excluded files\n            if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):\n                continue\n            # Skip README.md is an index file also exists in dir\n            if filename.lower() == 'readme.md' and 'index.md' in filenames:\n                continue\n            files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))\n\n    return Files(files)\n\n\ndef _sort_files(filenames):\n    \"\"\" Always sort `index` or `README` as first filename in list. \"\"\"\n\n    def compare(x, y):\n        if x == y:\n            return 0\n        if os.path.splitext(y)[0] in ['index', 'README']:\n            return 1\n        if os.path.splitext(x)[0] in ['index', 'README'] or x < y:\n            return -1\n        return 1\n\n    return sorted(filenames, key=cmp_to_key(compare))\n\n\ndef _filter_paths(basename, path, is_dir, exclude):\n    \"\"\" .gitignore style file filtering. \"\"\"\n    for item in exclude:\n        # Items ending in '/' apply only to directories.\n        if item.endswith('/') and not is_dir:\n            continue\n        # Items starting with '/' apply to the whole path.\n        # In any other cases just the basename is used.\n        match = path if item.startswith('/') else basename\n        if fnmatch.fnmatch(match, item.strip('/')):\n            return True\n    return False\n", "path": "mkdocs/structure/files.py"}]}