Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new recursive argument to include directive #208

Merged
merged 10 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ plugins:
heading_offset: 0
start: <!--start-->
end: <!--end-->
recursive: true
```

#### `opening_tag` and `closing_tag`
Expand Down Expand Up @@ -245,6 +246,9 @@ Includes the content of a file or a group of files.
- <a name="include_encoding" href="#include_encoding">#</a>
**encoding** (_utf-8_): Specify the encoding of the included file.
If not defined `utf-8` will be used.
- <a name="recursive" href="#include_recursive">#</a>
**recursive** (_true_): When this option is disabled, included files are not
processed for recursive includes. Possible values are `true` and `false`.

##### Examples

Expand Down
5 changes: 5 additions & 0 deletions locale/es/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ plugins:
heading_offset: 0
start: <!--start-->
end: <!--end-->
recursive: true
```

#### `opening_tag` y `closing_tag`
Expand Down Expand Up @@ -236,6 +237,10 @@ Los valores posibles son `true` y `false`.
- <a name="include_encoding" href="#include_encoding">#</a> **encoding**
(*utf-8*): Especifica la codificación del archivo incluído. Si no se define,
se usará `utf-8`.
- <a name="recursive" href="#include_recursive">#</a> **recursive** (*true*):
Cuando esta opción está deshabilitada, los archivos incluidos no son
procesados para incluir de forma recursiva. Los valores posibles son `true` y
`false`.

##### Ejemplos

Expand Down
10 changes: 10 additions & 0 deletions locale/es/README.md.po
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,13 @@ msgstr ""

msgid "[pypi-link]: https://pypi.org/project/mkdocs-include-markdown-plugin"
msgstr "[pypi-link]: https://pypi.org/project/mkdocs-include-markdown-plugin"

msgid ""
"<a name=\"recursive\" href=\"#include_recursive\">#</a> **recursive** "
"(*true*): When this option is disabled, included files are not processed for"
" recursive includes. Possible values are `true` and `false`."
msgstr ""
"<a name=\"recursive\" href=\"#include_recursive\">#</a> **recursive** "
"(*true*): Cuando esta opción está deshabilitada, los archivos incluidos no "
"son procesados para incluir de forma recursiva. Los valores posibles son "
"`true` y `false`."
4 changes: 4 additions & 0 deletions locale/fr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ plugins:
heading_offset: 0
start: <!--start-->
end: <!--end-->
recursive: true
```

#### `opening_tag` et `closing_tag`
Expand Down Expand Up @@ -235,6 +236,9 @@ valeurs possibles sont `true` et `false`.
- <a name="include_encoding" href="#include_encoding">#</a> **encoding**
(*utf-8*): Spécifiez l'encodage du fichier inclus. S'il n'est pas défini,
`utf-8` sera utilisé.
- <a name="recursive" href="#include_recursive">#</a> **recursive** (*true*):
Lorsque cette option est désactivée, les fichiers inclus ne sont pas traités
pour des inclusions récursives. Les valeurs possibles sont `true` et `false`.

##### Exemples

Expand Down
11 changes: 10 additions & 1 deletion locale/fr/README.md.po
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,15 @@ msgid ""
msgstr ""
"[Globs génériques Bash]: https://facelessuser.github.io/wcmatch/glob/#syntax"

#, fuzzy
msgid "[pypi-link]: https://pypi.org/project/mkdocs-include-markdown-plugin"
msgstr "[pypi-link]: https://pypi.org/project/mkdocs-include-markdown-plugin"

msgid ""
"<a name=\"recursive\" href=\"#include_recursive\">#</a> **recursive** "
"(*true*): When this option is disabled, included files are not processed for"
" recursive includes. Possible values are `true` and `false`."
msgstr ""
"<a name=\"recursive\" href=\"#include_recursive\">#</a> **recursive** "
"(*true*): Lorsque cette option est désactivée, les fichiers inclus ne sont "
"pas traités pour des inclusions récursives. Les valeurs possibles sont "
"`true` et `false`."
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mkdocs-include-markdown-plugin"
version = "6.0.7"
version = "6.1.0"
description = "Mkdocs Markdown includer plugin."
readme = "README.md"
license = "Apache-2.0"
Expand Down
1 change: 1 addition & 0 deletions src/mkdocs_include_markdown_plugin/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ class PluginConfig(Config): # noqa: D101
end = Optional(MkType(str))
exclude = ListOfItems(MkType(str), default=[])
cache = MkType(int, default=0)
recursive = MkType(bool, default=True)
2 changes: 2 additions & 0 deletions src/mkdocs_include_markdown_plugin/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class DirectiveBoolArgument: # noqa: D101
'comments': bool,
'rewrite-relative-urls': bool,
'heading-offset': int,
'recursive': bool,
'start': str | None,
'end': str | None,
},
Expand Down Expand Up @@ -96,6 +97,7 @@ def str_arg(arg: str) -> re.Pattern[str]:
'dedent': arg('dedent'),
'trailing-newlines': arg('trailing-newlines'),
'rewrite-relative-urls': arg('rewrite-relative-urls'),
'recursive': arg('recursive'),

# int
'heading-offset': arg('heading-offset'),
Expand Down
87 changes: 40 additions & 47 deletions src/mkdocs_include_markdown_plugin/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ def get_file_content( # noqa: PLR0913, PLR0915
http_cache: Cache | None = None,
) -> str:
"""Return the content of the file to include."""
settings_ignore_paths = []
if settings.exclude is not None:
for path in glob.glob(
[
os.path.join(docs_dir, fp)
if not os.path.isabs(fp)
else fp for fp in settings.exclude
],
flags=GLOB_FLAGS,
root_dir=docs_dir,
):
if path not in settings_ignore_paths:
settings_ignore_paths.append(path)
if page_src_path in settings_ignore_paths:
return markdown

def found_include_tag( # noqa: PLR0912, PLR0915
match: re.Match[str],
) -> str:
Expand All @@ -125,19 +141,7 @@ def found_include_tag( # noqa: PLR0912, PLR0915
arguments_string = match['arguments']

exclude_match = ARGUMENT_REGEXES['exclude'].search(arguments_string)
ignore_paths = []
if settings.exclude:
ignore_paths.extend(
glob.glob(
[
os.path.join(docs_dir, fp)
if not os.path.isabs(fp)
else fp for fp in settings.exclude
],
flags=GLOB_FLAGS,
root_dir=docs_dir,
),
)
ignore_paths = [*settings_ignore_paths]
if exclude_match is not None:
exclude_string = parse_string_argument(exclude_match)
if exclude_string is None:
Expand All @@ -151,14 +155,13 @@ def found_include_tag( # noqa: PLR0912, PLR0915
f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
)

ignore_paths.extend(
resolve_file_paths_to_exclude(
for path in resolve_file_paths_to_exclude(
exclude_string,
page_src_path,
docs_dir,
),
)
ignore_paths = list(set(ignore_paths))
):
if path not in ignore_paths:
ignore_paths.append(path)

file_paths_to_include, is_url = resolve_file_paths_to_include(
filename,
Expand All @@ -181,7 +184,8 @@ def found_include_tag( # noqa: PLR0912, PLR0915
files_watcher.included_files.extend(file_paths_to_include)

bool_options, invalid_bool_args = parse_bool_options(
['preserve-includer-indent', 'dedent', 'trailing-newlines'],
['preserve-includer-indent', 'dedent',
'trailing-newlines', 'recursive'],
defaults,
arguments_string,
)
Expand Down Expand Up @@ -264,16 +268,17 @@ def found_include_tag( # noqa: PLR0912, PLR0915
expected_but_any_found[i] = False

# nested includes
new_text_to_include = get_file_content(
new_text_to_include,
file_path,
docs_dir,
tags,
defaults,
settings,
files_watcher=files_watcher,
http_cache=http_cache,
)
if bool_options['recursive'].value:
new_text_to_include = get_file_content(
new_text_to_include,
file_path,
docs_dir,
tags,
defaults,
settings,
files_watcher=files_watcher,
http_cache=http_cache,
)

# trailing newlines right stripping
if not bool_options['trailing-newlines'].value:
Expand Down Expand Up @@ -349,19 +354,7 @@ def found_include_markdown_tag( # noqa: PLR0912, PLR0915
arguments_string = match['arguments']

exclude_match = ARGUMENT_REGEXES['exclude'].search(arguments_string)
ignore_paths = []
if settings.exclude is not None:
ignore_paths.extend(
glob.glob(
[
os.path.join(docs_dir, fp)
if not os.path.isabs(fp)
else fp for fp in settings.exclude
],
flags=GLOB_FLAGS,
root_dir=docs_dir,
),
)
ignore_paths = [*settings_ignore_paths]
if exclude_match is not None:
exclude_string = parse_string_argument(exclude_match)
if exclude_string is None:
Expand All @@ -374,14 +367,13 @@ def found_include_markdown_tag( # noqa: PLR0912, PLR0915
f' directive at'
f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
)
ignore_paths.extend(
resolve_file_paths_to_exclude(
for path in resolve_file_paths_to_exclude(
exclude_string,
page_src_path,
docs_dir,
),
)
ignore_paths = list(set(ignore_paths))
):
if path not in ignore_paths:
ignore_paths.append(path)

file_paths_to_include, is_url = resolve_file_paths_to_include(
filename,
Expand Down Expand Up @@ -667,6 +659,7 @@ def on_page_markdown(
'comments': config.comments,
'rewrite-relative-urls': config.rewrite_relative_urls,
'heading-offset': config.heading_offset,
'recursive': config.recursive,
'start': config.start,
'end': config.end,
},
Expand Down
29 changes: 29 additions & 0 deletions tests/test_unit/test_nested_includes.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,32 @@
],
id='start-end-not-found (second-level)',
),
# recursive inclusion disabled with `include` directive
pytest.param(
'''# Header

{%
include "{filepath}"
comments=false
recursive=false
%}''',
'''# Header 2

{% include "{filepath}" %}
''',
'''# Header 3

This content must not be included.
''',
'''# Header

# Header 2

{% include "{filepath}" %}
''',
[],
id='include-recursive=false',
),
),
)
def test_nested_include(
Expand All @@ -249,6 +275,9 @@ def test_nested_include(
second_includer_content = second_includer_content.replace(
'{filepath}', included_file.as_posix(),
)
expected_result = expected_result.replace(
'{filepath}', included_file.as_posix(),
)

first_includer_file.write_text(first_includer_content)
second_includer_file.write_text(second_includer_content)
Expand Down
Loading