Repository: timvink/mkdocs-print-site-plugin

Issue:
Excluding directory does not exclude submenu
If you exclude a directory, it's pages will still show up on the heading 1 right menu on the print page.

Hints from issue comments:
@weyCC81: I am experiencing the same issue, is there a workaround for this?@timvink: Fix found by @bobneuman here: https://github.com/timvink/mkdocs-print-site-plugin/pull/108/files#r1986891761

Will work on getting to master and a release soon@timvink: So #128 will fix this issue also, because the toc is generated differently.@timvink: This should be fixed by #128, released in [v2.7.0](https://github.com/timvink/mkdocs-print-site-plugin/releases/tag/v2.7.0)@weyCC81: I am still seeing this issue with 2.7.0 for excluded directories …

```
      exclude:
        - labs
        - labs/*
```@timvink: I was able to reproduce the error, indeed folders were not properly ignored. Fixed now in https://github.com/timvink/mkdocs-print-site-plugin/releases/tag/v2.7.1, should be on pypi shortly

Solution patch:
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 os
 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


Test patch:
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):
         '<p class="print-site-plugin-ignore">This paragraph is ignored, this unique code should not be found: V5lI1bUdnUI9</p>',  # 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)