mkdocs-include-markdown-plugin 6.0.6__tar.gz → 6.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (14) hide show
  1. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/PKG-INFO +5 -1
  2. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/README.md +4 -0
  3. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/pyproject.toml +1 -1
  4. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/config.py +1 -0
  5. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/directive.py +2 -0
  6. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/event.py +59 -50
  7. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/.gitignore +0 -0
  8. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/LICENSE +0 -0
  9. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/__init__.py +0 -0
  10. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/cache.py +0 -0
  11. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/files_watcher.py +0 -0
  12. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/plugin.py +0 -0
  13. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/process.py +0 -0
  14. {mkdocs_include_markdown_plugin-6.0.6 → mkdocs_include_markdown_plugin-6.1.0}/src/mkdocs_include_markdown_plugin/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mkdocs-include-markdown-plugin
3
- Version: 6.0.6
3
+ Version: 6.1.0
4
4
  Summary: Mkdocs Markdown includer plugin.
5
5
  Project-URL: Source, https://github.com/mondeja/mkdocs-include-markdown-plugin
6
6
  Project-URL: Documentation, https://github.com/mondeja/mkdocs-include-markdown-plugin#documentation
@@ -94,6 +94,7 @@ plugins:
94
94
  heading_offset: 0
95
95
  start: <!--start-->
96
96
  end: <!--end-->
97
+ recursive: true
97
98
  ```
98
99
 
99
100
  #### `opening_tag` and `closing_tag`
@@ -280,6 +281,9 @@ Includes the content of a file or a group of files.
280
281
  - <a name="include_encoding" href="#include_encoding">#</a>
281
282
  **encoding** (_utf-8_): Specify the encoding of the included file.
282
283
  If not defined `utf-8` will be used.
284
+ - <a name="recursive" href="#include_recursive">#</a>
285
+ **recursive** (_true_): When this option is disabled, included files are not
286
+ processed for recursive includes. Possible values are `true` and `false`.
283
287
 
284
288
  ##### Examples
285
289
 
@@ -59,6 +59,7 @@ plugins:
59
59
  heading_offset: 0
60
60
  start: <!--start-->
61
61
  end: <!--end-->
62
+ recursive: true
62
63
  ```
63
64
 
64
65
  #### `opening_tag` and `closing_tag`
@@ -245,6 +246,9 @@ Includes the content of a file or a group of files.
245
246
  - <a name="include_encoding" href="#include_encoding">#</a>
246
247
  **encoding** (_utf-8_): Specify the encoding of the included file.
247
248
  If not defined `utf-8` will be used.
249
+ - <a name="recursive" href="#include_recursive">#</a>
250
+ **recursive** (_true_): When this option is disabled, included files are not
251
+ processed for recursive includes. Possible values are `true` and `false`.
248
252
 
249
253
  ##### Examples
250
254
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mkdocs-include-markdown-plugin"
3
- version = "6.0.6"
3
+ version = "6.1.0"
4
4
  description = "Mkdocs Markdown includer plugin."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -24,3 +24,4 @@ class PluginConfig(Config): # noqa: D101
24
24
  end = Optional(MkType(str))
25
25
  exclude = ListOfItems(MkType(str), default=[])
26
26
  cache = MkType(int, default=0)
27
+ recursive = MkType(bool, default=True)
@@ -34,6 +34,7 @@ if TYPE_CHECKING:
34
34
  'comments': bool,
35
35
  'rewrite-relative-urls': bool,
36
36
  'heading-offset': int,
37
+ 'recursive': bool,
37
38
  'start': str | None,
38
39
  'end': str | None,
39
40
  },
@@ -96,6 +97,7 @@ ARGUMENT_REGEXES = {
96
97
  'dedent': arg('dedent'),
97
98
  'trailing-newlines': arg('trailing-newlines'),
98
99
  'rewrite-relative-urls': arg('rewrite-relative-urls'),
100
+ 'recursive': arg('recursive'),
99
101
 
100
102
  # int
101
103
  'heading-offset': arg('heading-offset'),
@@ -58,6 +58,22 @@ def lineno_from_content_start(content: str, start: int) -> int:
58
58
  return content[:start].count('\n') + 1
59
59
 
60
60
 
61
+ def safe_os_path_relpath(path: str, start: str) -> str:
62
+ """Return the relative path of a file from a start directory.
63
+
64
+ Safe version of `os.path.relpath` that catches `ValueError` exceptions
65
+ on Windows and returns the original path in case of error.
66
+ On Windows, `ValueError` is raised when `path` and `start` are on
67
+ different drives.
68
+ """
69
+ if os.name != 'nt': # pragma: nt no cover
70
+ return os.path.relpath(path, start)
71
+ try: # pragma: nt cover
72
+ return os.path.relpath(path, start)
73
+ except ValueError: # pragma: no cover
74
+ return path
75
+
76
+
61
77
  def file_lineno_message(
62
78
  page_src_path: str | None,
63
79
  docs_dir: str,
@@ -67,7 +83,7 @@ def file_lineno_message(
67
83
  if page_src_path is None: # pragma: no cover
68
84
  return f'generated page content (line {lineno})'
69
85
  return (
70
- f'{os.path.relpath(page_src_path, docs_dir)}'
86
+ f'{safe_os_path_relpath(page_src_path, docs_dir)}'
71
87
  f':{lineno}'
72
88
  )
73
89
 
@@ -87,6 +103,22 @@ def get_file_content( # noqa: PLR0913, PLR0915
87
103
  http_cache: Cache | None = None,
88
104
  ) -> str:
89
105
  """Return the content of the file to include."""
106
+ settings_ignore_paths = []
107
+ if settings.exclude is not None:
108
+ for path in glob.glob(
109
+ [
110
+ os.path.join(docs_dir, fp)
111
+ if not os.path.isabs(fp)
112
+ else fp for fp in settings.exclude
113
+ ],
114
+ flags=GLOB_FLAGS,
115
+ root_dir=docs_dir,
116
+ ):
117
+ if path not in settings_ignore_paths:
118
+ settings_ignore_paths.append(path)
119
+ if page_src_path in settings_ignore_paths:
120
+ return markdown
121
+
90
122
  def found_include_tag( # noqa: PLR0912, PLR0915
91
123
  match: re.Match[str],
92
124
  ) -> str:
@@ -109,19 +141,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
109
141
  arguments_string = match['arguments']
110
142
 
111
143
  exclude_match = ARGUMENT_REGEXES['exclude'].search(arguments_string)
112
- ignore_paths = []
113
- if settings.exclude:
114
- ignore_paths.extend(
115
- glob.glob(
116
- [
117
- os.path.join(docs_dir, fp)
118
- if not os.path.isabs(fp)
119
- else fp for fp in settings.exclude
120
- ],
121
- flags=GLOB_FLAGS,
122
- root_dir=docs_dir,
123
- ),
124
- )
144
+ ignore_paths = [*settings_ignore_paths]
125
145
  if exclude_match is not None:
126
146
  exclude_string = parse_string_argument(exclude_match)
127
147
  if exclude_string is None:
@@ -135,14 +155,13 @@ def get_file_content( # noqa: PLR0913, PLR0915
135
155
  f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
136
156
  )
137
157
 
138
- ignore_paths.extend(
139
- resolve_file_paths_to_exclude(
158
+ for path in resolve_file_paths_to_exclude(
140
159
  exclude_string,
141
160
  page_src_path,
142
161
  docs_dir,
143
- ),
144
- )
145
- ignore_paths = list(set(ignore_paths))
162
+ ):
163
+ if path not in ignore_paths:
164
+ ignore_paths.append(path)
146
165
 
147
166
  file_paths_to_include, is_url = resolve_file_paths_to_include(
148
167
  filename,
@@ -165,7 +184,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
165
184
  files_watcher.included_files.extend(file_paths_to_include)
166
185
 
167
186
  bool_options, invalid_bool_args = parse_bool_options(
168
- ['preserve-includer-indent', 'dedent', 'trailing-newlines'],
187
+ ['preserve-includer-indent', 'dedent',
188
+ 'trailing-newlines', 'recursive'],
169
189
  defaults,
170
190
  arguments_string,
171
191
  )
@@ -248,16 +268,17 @@ def get_file_content( # noqa: PLR0913, PLR0915
248
268
  expected_but_any_found[i] = False
249
269
 
250
270
  # nested includes
251
- new_text_to_include = get_file_content(
252
- new_text_to_include,
253
- file_path,
254
- docs_dir,
255
- tags,
256
- defaults,
257
- settings,
258
- files_watcher=files_watcher,
259
- http_cache=http_cache,
260
- )
271
+ if bool_options['recursive'].value:
272
+ new_text_to_include = get_file_content(
273
+ new_text_to_include,
274
+ file_path,
275
+ docs_dir,
276
+ tags,
277
+ defaults,
278
+ settings,
279
+ files_watcher=files_watcher,
280
+ http_cache=http_cache,
281
+ )
261
282
 
262
283
  # trailing newlines right stripping
263
284
  if not bool_options['trailing-newlines'].value:
@@ -287,7 +308,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
287
308
  if expected_but_any_found[i]:
288
309
  delimiter_value = locals()[delimiter_name]
289
310
  readable_files_to_include = ', '.join([
290
- os.path.relpath(fpath, docs_dir)
311
+ safe_os_path_relpath(fpath, docs_dir)
291
312
  for fpath in file_paths_to_include
292
313
  ])
293
314
  plural_suffix = 's' if len(file_paths_to_include) > 1 else ''
@@ -333,19 +354,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
333
354
  arguments_string = match['arguments']
334
355
 
335
356
  exclude_match = ARGUMENT_REGEXES['exclude'].search(arguments_string)
336
- ignore_paths = []
337
- if settings.exclude is not None:
338
- ignore_paths.extend(
339
- glob.glob(
340
- [
341
- os.path.join(docs_dir, fp)
342
- if not os.path.isabs(fp)
343
- else fp for fp in settings.exclude
344
- ],
345
- flags=GLOB_FLAGS,
346
- root_dir=docs_dir,
347
- ),
348
- )
357
+ ignore_paths = [*settings_ignore_paths]
349
358
  if exclude_match is not None:
350
359
  exclude_string = parse_string_argument(exclude_match)
351
360
  if exclude_string is None:
@@ -358,14 +367,13 @@ def get_file_content( # noqa: PLR0913, PLR0915
358
367
  f' directive at'
359
368
  f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
360
369
  )
361
- ignore_paths.extend(
362
- resolve_file_paths_to_exclude(
370
+ for path in resolve_file_paths_to_exclude(
363
371
  exclude_string,
364
372
  page_src_path,
365
373
  docs_dir,
366
- ),
367
- )
368
- ignore_paths = list(set(ignore_paths))
374
+ ):
375
+ if path not in ignore_paths:
376
+ ignore_paths.append(path)
369
377
 
370
378
  file_paths_to_include, is_url = resolve_file_paths_to_include(
371
379
  filename,
@@ -593,7 +601,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
593
601
  if expected_but_any_found[i]:
594
602
  delimiter_value = locals()[delimiter_name]
595
603
  readable_files_to_include = ', '.join([
596
- os.path.relpath(fpath, docs_dir)
604
+ safe_os_path_relpath(fpath, docs_dir)
597
605
  for fpath in file_paths_to_include
598
606
  ])
599
607
  plural_suffix = 's' if len(file_paths_to_include) > 1 else ''
@@ -651,6 +659,7 @@ def on_page_markdown(
651
659
  'comments': config.comments,
652
660
  'rewrite-relative-urls': config.rewrite_relative_urls,
653
661
  'heading-offset': config.heading_offset,
662
+ 'recursive': config.recursive,
654
663
  'start': config.start,
655
664
  'end': config.end,
656
665
  },