diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 1c4c28ff..083dd1a4 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -100,6 +100,9 @@ up horizontal space for better rendering of content like tables (#2193). filtering for sections (#2203). * Official support for Python 3.9 has been added and support for Python 3.5 has been dropped. +* Structure Files object now has a `remove` method to help plugin developers + manipulate the Files tree. The corresponding `src_paths` has become a + property to accomodate this possible dynamic behavior. See #2305. ## Version 1.1.2 (2020-05-14) diff --git a/mkdocs/structure/files.py b/mkdocs/structure/files.py index 442845bf..42cab0b7 100644 --- a/mkdocs/structure/files.py +++ b/mkdocs/structure/files.py @@ -15,7 +15,6 @@ class Files: """ A collection of File objects. """ def __init__(self, files): self._files = files - self.src_paths = {file.src_path: file for file in files} def __iter__(self): return iter(self._files) @@ -26,6 +25,10 @@ class Files: def __contains__(self, path): return path in self.src_paths + @property + def src_paths(self): + return {file.src_path: file for file in self._files} + def get_file_from_path(self, path): """ Return a File instance with File.src_path equal to path. """ return self.src_paths.get(os.path.normpath(path)) @@ -33,7 +36,10 @@ class Files: def append(self, file): """ Append file to Files collection. """ self._files.append(file) - self.src_paths[file.src_path] = file + + def remove(self, file): + """ Remove file from Files collection. """ + self._files.remove(file) def copy_static_files(self, dirty=False): """ Copy static files from source to destination. """ diff --git a/mkdocs/tests/structure/file_tests.py b/mkdocs/tests/structure/file_tests.py index 8aa2e206..b1b399a0 100644 --- a/mkdocs/tests/structure/file_tests.py +++ b/mkdocs/tests/structure/file_tests.py @@ -674,3 +674,26 @@ class TestFiles(PathAssertionMixin, unittest.TestCase): self.assertPathIsFile(dest_path) with open(dest_path, 'r', encoding='utf-8') as f: self.assertEqual(f.read(), 'destination content') + + def test_files_append_remove_src_paths(self): + fs = [ + File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), + File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), + File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True), + File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True), + File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True), + File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True) + ] + files = Files(fs) + self.assertEqual(len(files), 6) + self.assertEqual(len(files.src_paths), 6) + extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) + self.assertFalse(extra_file.src_path in files) + files.append(extra_file) + self.assertEqual(len(files), 7) + self.assertEqual(len(files.src_paths), 7) + self.assertTrue(extra_file.src_path in files) + files.remove(extra_file) + self.assertEqual(len(files), 6) + self.assertEqual(len(files.src_paths), 6) + self.assertFalse(extra_file.src_path in files)