diff --git a/docs/options.md b/docs/options.md index a8b6293..bb66197 100644 --- a/docs/options.md +++ b/docs/options.md @@ -95,4 +95,4 @@ plugins: ``` `exclude` -: Default is empty. Allows to specify a list of page source paths that should not be included in the print page. See [Do Not Print](how-to/do_not_print.md#ignoring-an-entire-page) for more info. \ No newline at end of file +: Default is empty. Allows to specify a list of page source paths that should not be included in the print page. Supports [glob](https://docs.python.org/3/library/glob.html)-like syntax such as `folder/` or `folder/*`. See [Do Not Print](how-to/do_not_print.md#ignoring-an-entire-page) for more info on excluding pages. \ No newline at end of file diff --git a/src/mkdocs_print_site_plugin/__init__.py b/src/mkdocs_print_site_plugin/__init__.py index 2614ce9..7a38ae0 100644 --- a/src/mkdocs_print_site_plugin/__init__.py +++ b/src/mkdocs_print_site_plugin/__init__.py @@ -1 +1 @@ -__version__ = "2.7.0" +__version__ = "2.7.1" diff --git a/src/mkdocs_print_site_plugin/exclude.py b/src/mkdocs_print_site_plugin/exclude.py index a5d91d0..3490e10 100644 --- a/src/mkdocs_print_site_plugin/exclude.py +++ b/src/mkdocs_print_site_plugin/exclude.py @@ -8,40 +8,48 @@ import fnmatch from typing import List + +import fnmatch +import os +from typing import List -def exclude(src_path: str, globs: List[str]) -> bool: +def exclude(path: str, exclude_patterns: List[str]) -> bool: """ - Determine if a src_path should be excluded. - - Supports globs (e.g. folder/* or *.md). - Credits: code inspired by / adapted from - https://github.com/apenwarr/mkdocs-exclude/blob/master/mkdocs_exclude/plugin.py - + Check if a path should be excluded based on a list of patterns. + Args: - src_path (src): Path of file - globs (list): list of globs + path: The path to check + exclude_patterns: List of glob patterns to exclude + Returns: - (bool): whether src_path should be excluded + True if the path should be excluded, False otherwise """ - assert isinstance(src_path, str) - assert isinstance(globs, list) - - for g in globs: - if fnmatch.fnmatchcase(src_path, g): - return True - - # Windows reports filenames as eg. a\\b\\c instead of a/b/c. - # To make the same globs/regexes match filenames on Windows and - # other OSes, let's try matching against converted filenames. - # On the other hand, Unix actually allows filenames to contain - # literal \\ characters (although it is rare), so we won't - # always convert them. We only convert if os.sep reports - # something unusual. Conversely, some future mkdocs might - # report Windows filenames using / separators regardless of - # os.sep, so we *always* test with / above. - if os.sep != "/": - src_path_fix = src_path.replace(os.sep, "/") - if fnmatch.fnmatchcase(src_path_fix, g): + assert isinstance(path, str) + assert isinstance(exclude_patterns, list) + + if not exclude_patterns: + return False + + # Normalize path separators to handle both Windows and Unix paths + path = path.replace('\\', '/') + + for pattern in exclude_patterns: + # Normalize pattern separators + pattern = pattern.replace('\\', '/') + + # Check for directory patterns (ending with /) + if pattern.endswith('/'): + if path.startswith(pattern) or path.startswith(pattern[:-1] + '/'): return True - - return False + # Regular glob pattern matching + elif fnmatch.fnmatch(path, pattern): + return True + # Check if path is in a directory that matches the pattern + elif '/' in path: + path_parts = path.split('/') + for i in range(1, len(path_parts)): + partial_path = '/'.join(path_parts[:i]) + if fnmatch.fnmatch(partial_path, pattern) or partial_path == pattern: + return True + + return False \ No newline at end of file diff --git a/tests/fixtures/projects/basic/docs/subfolder/anotherpage.md b/tests/fixtures/projects/basic/docs/subfolder/anotherpage.md new file mode 100644 index 0000000..15c7ad6 --- /dev/null +++ b/tests/fixtures/projects/basic/docs/subfolder/anotherpage.md @@ -0,0 +1,3 @@ +# Page in subfolder + +unique code we can search for during unit tests: d1231dct9dkqwn2 \ No newline at end of file diff --git a/tests/fixtures/projects/basic/mkdocs_do_not_print.yml b/tests/fixtures/projects/basic/mkdocs_do_not_print.yml index 442d267..9728cd9 100644 --- a/tests/fixtures/projects/basic/mkdocs_do_not_print.yml +++ b/tests/fixtures/projects/basic/mkdocs_do_not_print.yml @@ -4,7 +4,8 @@ plugins: - print-site: exclude: - z.md - - subsection1.md + - subsection1.md + - subfolder/ markdown_extensions: - attr_list diff --git a/tests/test_building.py b/tests/test_building.py index 4c1b7bf..e17f6c8 100644 --- a/tests/test_building.py +++ b/tests/test_building.py @@ -308,6 +308,10 @@ def test_exclude_page(tmp_path): '
This paragraph is ignored, this unique code should not be found: V5lI1bUdnUI9
', # noqa ) + # Test that globs also work for entire directories + # subfolder/another_page.md has a code 'd1231dct9dkqwn2' that should not be present because we excluded the subfolder/ directory + assert not text_in_page(prj_path, "print_page/index.html", "d1231dct9dkqwn2") + def test_basic_build99(tmp_path): """ diff --git a/tests/test_exclude.py b/tests/test_exclude.py index 3502189..1f0a83d 100644 --- a/tests/test_exclude.py +++ b/tests/test_exclude.py @@ -17,4 +17,6 @@ def test_exclude(): globs = ["folder/*"] assert exclude("folder/index.md", globs) + assert exclude("folder/index.md", ["folder"]) assert not exclude("subfolder/index.md", globs) + assert not exclude("subfolder", globs)