diff --git a/strictdoc/export/html/generators/source_file_view_generator.py b/strictdoc/export/html/generators/source_file_view_generator.py
index 37659bfa4..880fc5fc8 100644
--- a/strictdoc/export/html/generators/source_file_view_generator.py
+++ b/strictdoc/export/html/generators/source_file_view_generator.py
@@ -5,7 +5,7 @@
from pygments.formatters.html import HtmlFormatter
from pygments.lexers.c_cpp import CLexer, CppLexer
from pygments.lexers.data import YamlLexer
-from pygments.lexers.markup import TexLexer, RstLexer
+from pygments.lexers.markup import RstLexer, TexLexer
from pygments.lexers.python import PythonLexer
from pygments.lexers.templates import HtmlDjangoLexer
diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py
index e58fcb387..cefab4f64 100644
--- a/strictdoc/server/routers/main_router.py
+++ b/strictdoc/server/routers/main_router.py
@@ -90,6 +90,7 @@
from strictdoc.helpers.file_system import get_etag
from strictdoc.helpers.mid import MID
from strictdoc.helpers.parallelizer import NullParallelizer
+from strictdoc.helpers.path_filter import PathFilter
from strictdoc.helpers.string import (
create_safe_acronym,
is_safe_alphanumeric_string,
@@ -1591,6 +1592,33 @@ def document_tree__create_document(
),
)
+ if project_config.include_doc_paths is not None:
+ path_filter_includes = PathFilter(
+ project_config.include_doc_paths, positive_or_negative=True
+ )
+ if not path_filter_includes.match(document_path):
+ error_object.add_error(
+ "document_path",
+ (
+ "Document path is not a valid path according to "
+ "the project config's setting 'include_doc_paths': "
+ f"{project_config.include_doc_paths}."
+ ),
+ )
+ if project_config.exclude_doc_paths is not None:
+ path_filter_excludes = PathFilter(
+ project_config.exclude_doc_paths, positive_or_negative=False
+ )
+ if path_filter_excludes.match(document_path):
+ error_object.add_error(
+ "document_path",
+ (
+ "Document path is not a valid path according to "
+ "the project config's setting 'exclude_doc_paths': "
+ f"{project_config.exclude_doc_paths}."
+ ),
+ )
+
if error_object.any_errors():
template = env().get_template(
"actions/project_index/stream_new_document.jinja.html"
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/__init__.py b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/docs/document.sdoc b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/docs/document.sdoc
new file mode 100644
index 000000000..111cdb118
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/docs/document.sdoc
@@ -0,0 +1,2 @@
+[DOCUMENT]
+TITLE: Document 1
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/strictdoc.toml b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/strictdoc.toml
new file mode 100644
index 000000000..db1622190
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/expected_output/strictdoc.toml
@@ -0,0 +1,9 @@
+[project]
+
+features = [
+
+]
+
+exclude_doc_paths = [
+ "tests/**",
+]
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/input/strictdoc.toml b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/input/strictdoc.toml
new file mode 100644
index 000000000..db1622190
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/input/strictdoc.toml
@@ -0,0 +1,9 @@
+[project]
+
+features = [
+
+]
+
+exclude_doc_paths = [
+ "tests/**",
+]
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/test_case.py b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/test_case.py
new file mode 100644
index 000000000..c6a1f6643
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_inside_of_exclude_filter/test_case.py
@@ -0,0 +1,43 @@
+from tests.end2end.e2e_case import E2ECase
+from tests.end2end.end2end_test_setup import End2EndTestSetup
+from tests.end2end.helpers.screens.project_index.form_add_document import (
+ Form_AddDocument,
+)
+from tests.end2end.helpers.screens.project_index.screen_project_index import (
+ Screen_ProjectIndex,
+)
+from tests.end2end.server import SDocTestServer
+
+
+class Test(E2ECase):
+ def test(self):
+ test_setup = End2EndTestSetup(path_to_test_file=__file__)
+
+ with SDocTestServer(
+ input_path=test_setup.path_to_sandbox
+ ) as test_server:
+ self.open(test_server.get_host_and_port())
+
+ screen_project_index = Screen_ProjectIndex(self)
+ screen_project_index.assert_on_screen()
+ screen_project_index.assert_empty_tree()
+
+ form_add_document: Form_AddDocument = (
+ screen_project_index.do_open_modal_form_add_document()
+ )
+ form_add_document.do_fill_in_title("Document 1")
+
+ # First, fill in an invalid path.
+ form_add_document.do_fill_in_path("tests/document")
+ form_add_document.do_form_submit_and_catch_error(
+ "Document path is not a valid path according to the project "
+ "config's setting 'exclude_doc_paths': ['tests/**']."
+ )
+
+ # Then, fill in a valid path.
+ form_add_document.do_fill_in_path("docs/document")
+ form_add_document.do_form_submit()
+
+ screen_project_index.assert_contains_document("Document 1")
+
+ assert test_setup.compare_sandbox_and_expected_output()
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/__init__.py b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/docs/document.sdoc b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/docs/document.sdoc
new file mode 100644
index 000000000..111cdb118
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/docs/document.sdoc
@@ -0,0 +1,2 @@
+[DOCUMENT]
+TITLE: Document 1
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/strictdoc.toml b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/strictdoc.toml
new file mode 100644
index 000000000..ba7db255e
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/expected_output/strictdoc.toml
@@ -0,0 +1,9 @@
+[project]
+
+features = [
+
+]
+
+include_doc_paths = [
+ "docs/**",
+]
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/input/strictdoc.toml b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/input/strictdoc.toml
new file mode 100644
index 000000000..ba7db255e
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/input/strictdoc.toml
@@ -0,0 +1,9 @@
+[project]
+
+features = [
+
+]
+
+include_doc_paths = [
+ "docs/**",
+]
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/test_case.py b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/test_case.py
new file mode 100644
index 000000000..ef884e093
--- /dev/null
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_outside_of_include_filter/test_case.py
@@ -0,0 +1,43 @@
+from tests.end2end.e2e_case import E2ECase
+from tests.end2end.end2end_test_setup import End2EndTestSetup
+from tests.end2end.helpers.screens.project_index.form_add_document import (
+ Form_AddDocument,
+)
+from tests.end2end.helpers.screens.project_index.screen_project_index import (
+ Screen_ProjectIndex,
+)
+from tests.end2end.server import SDocTestServer
+
+
+class Test(E2ECase):
+ def test(self):
+ test_setup = End2EndTestSetup(path_to_test_file=__file__)
+
+ with SDocTestServer(
+ input_path=test_setup.path_to_sandbox
+ ) as test_server:
+ self.open(test_server.get_host_and_port())
+
+ screen_project_index = Screen_ProjectIndex(self)
+ screen_project_index.assert_on_screen()
+ screen_project_index.assert_empty_tree()
+
+ form_add_document: Form_AddDocument = (
+ screen_project_index.do_open_modal_form_add_document()
+ )
+ form_add_document.do_fill_in_title("Document 1")
+
+ # First, fill in an invalid path.
+ form_add_document.do_fill_in_path("document")
+ form_add_document.do_form_submit_and_catch_error(
+ "Document path is not a valid path according to the project "
+ "config's setting 'include_doc_paths': ['docs/**']."
+ )
+
+ # Then, fill in a valid path.
+ form_add_document.do_fill_in_path("docs/document")
+ form_add_document.do_form_submit()
+
+ screen_project_index.assert_contains_document("Document 1")
+
+ assert test_setup.compare_sandbox_and_expected_output()
diff --git a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_with_bad_chars/test_case.py b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_with_bad_chars/test_case.py
index 3cde27a01..d3edb7587 100644
--- a/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_with_bad_chars/test_case.py
+++ b/tests/end2end/project_index/create_document/_validation/create_document_validate_document_path_with_bad_chars/test_case.py
@@ -32,3 +32,10 @@ def test(self):
"Document path must be relative and only contain slashes, "
"alphanumeric characters, and underscore symbols."
)
+
+ form_add_document.do_fill_in_path("/test1.sdoc")
+ form_add_document.do_form_submit_and_catch_error(
+ "Document path must be relative and only contain slashes, "
+ "alphanumeric characters, and underscore symbols."
+ )
+ self.assert_text("/test1.sdoc")