Skip to content

Commit

Permalink
Add new recursive argument to include directive (#208)
Browse files Browse the repository at this point in the history
* 'recursive' option added

* exclude directive now avoids processing the desired files all together

* add recursive description in README

* Add translations

* Add test

* Refactor

* Revert change in order of execution of directives

* Add recursive to global config in documentation

* Bump version

---------

Co-authored-by: Álvaro Mondéjar Rubio <mondejar1994@gmail.com>
  • Loading branch information
carlocastoldi and mondeja committed Jun 1, 2024
1 parent eb65645 commit 47f57fb
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 49 deletions.
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

0 comments on commit 47f57fb

Please sign in to comment.