mkdocs-include-markdown-plugin 6.0.5__tar.gz → 6.0.7__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.5 → mkdocs_include_markdown_plugin-6.0.7}/PKG-INFO +1 -1
  2. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/pyproject.toml +3 -2
  3. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/directive.py +24 -11
  4. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/event.py +86 -44
  5. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/.gitignore +0 -0
  6. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/LICENSE +0 -0
  7. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/README.md +0 -0
  8. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/__init__.py +0 -0
  9. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/cache.py +0 -0
  10. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/config.py +0 -0
  11. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/files_watcher.py +0 -0
  12. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/plugin.py +0 -0
  13. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/src/mkdocs_include_markdown_plugin/process.py +0 -0
  14. {mkdocs_include_markdown_plugin-6.0.5 → mkdocs_include_markdown_plugin-6.0.7}/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.5
3
+ Version: 6.0.7
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mkdocs-include-markdown-plugin"
3
- version = "6.0.5"
3
+ version = "6.0.7"
4
4
  description = "Mkdocs Markdown includer plugin."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -74,7 +74,7 @@ dependencies = ["pytest~=7.0", "coverage~=6.4", "covdefaults"]
74
74
 
75
75
  [[tool.hatch.envs.tests.matrix]]
76
76
  python = ["py38", "py39", "py310", "py311", "py312"]
77
- mkdocs = ["1.4.0", "1.4.3", "1.5.0", "1.5.3"]
77
+ mkdocs = ["1.4.0", "1.4.3", "1.5.0", "1.5.3", "1.6.0"]
78
78
  cache = ["yes", "no"]
79
79
 
80
80
  [tool.hatch.envs.tests.overrides]
@@ -83,6 +83,7 @@ matrix.mkdocs.dependencies = [
83
83
  { value = "mkdocs==1.4.3", if = ["1.4.3"] },
84
84
  { value = "mkdocs==1.5.0", if = ["1.5.0"] },
85
85
  { value = "mkdocs==1.5.3", if = ["1.5.3"] },
86
+ { value = "mkdocs==1.6.0", if = ["1.6.0"] },
86
87
  ]
87
88
  matrix.cache.dependencies = [{ value = "platformdirs", if = ["yes"] }]
88
89
 
@@ -8,6 +8,7 @@ import string
8
8
  from dataclasses import dataclass
9
9
  from typing import TYPE_CHECKING
10
10
 
11
+ from mkdocs.exceptions import PluginError
11
12
  from wcmatch import glob
12
13
 
13
14
  from mkdocs_include_markdown_plugin import process
@@ -174,19 +175,19 @@ def parse_bool_options(
174
175
 
175
176
 
176
177
  def resolve_file_paths_to_include(
177
- filename_or_url: str,
178
- includer_page_src_path: str,
178
+ include_string: str,
179
+ includer_page_src_path: str | None,
179
180
  docs_dir: str,
180
181
  ignore_paths: list[str],
181
182
  ) -> tuple[list[str], bool]:
182
183
  """Resolve the file paths to include for a directive."""
183
- if process.is_url(filename_or_url):
184
- return [filename_or_url], True
184
+ if process.is_url(include_string):
185
+ return [include_string], True
185
186
 
186
- if process.is_absolute_path(filename_or_url):
187
+ if process.is_absolute_path(include_string):
187
188
  if os.name == 'nt': # pragma: nt cover
188
189
  # Windows
189
- fpath = os.path.normpath(filename_or_url)
190
+ fpath = os.path.normpath(include_string)
190
191
  if not os.path.isfile(fpath):
191
192
  return [], False
192
193
 
@@ -195,13 +196,19 @@ def resolve_file_paths_to_include(
195
196
  ), False
196
197
  return process.filter_paths(
197
198
  glob.iglob(
198
- os.path.normpath(filename_or_url),
199
+ os.path.normpath(include_string),
199
200
  flags=GLOB_FLAGS,
200
201
  ),
201
202
  ignore_paths,
202
203
  ), False
203
204
 
204
- if process.is_relative_path(filename_or_url):
205
+ if process.is_relative_path(include_string):
206
+ if includer_page_src_path is None: # pragma: no cover
207
+ raise PluginError(
208
+ 'Relative paths are not allowed when the includer page'
209
+ ' source path is not provided. The include string'
210
+ f" '{include_string}' is located inside a generated page.",
211
+ )
205
212
  root_dir = os.path.abspath(
206
213
  os.path.dirname(includer_page_src_path),
207
214
  )
@@ -209,7 +216,7 @@ def resolve_file_paths_to_include(
209
216
  (
210
217
  os.path.normpath(os.path.join(root_dir, fp))
211
218
  for fp in glob.iglob(
212
- filename_or_url,
219
+ include_string,
213
220
  flags=GLOB_FLAGS,
214
221
  root_dir=root_dir,
215
222
  )
@@ -221,7 +228,7 @@ def resolve_file_paths_to_include(
221
228
  (
222
229
  os.path.normpath(os.path.join(docs_dir, fp))
223
230
  for fp in glob.iglob(
224
- filename_or_url,
231
+ include_string,
225
232
  flags=GLOB_FLAGS,
226
233
  root_dir=docs_dir,
227
234
  )
@@ -232,7 +239,7 @@ def resolve_file_paths_to_include(
232
239
 
233
240
  def resolve_file_paths_to_exclude(
234
241
  exclude_string: str,
235
- includer_page_src_path: str,
242
+ includer_page_src_path: str | None,
236
243
  docs_dir: str,
237
244
  ) -> list[str]:
238
245
  """Resolve the file paths to exclude for a directive."""
@@ -241,6 +248,12 @@ def resolve_file_paths_to_exclude(
241
248
  return glob.glob(exclude_string, flags=GLOB_FLAGS)
242
249
 
243
250
  if process.is_relative_path(exclude_string):
251
+ if includer_page_src_path is None: # pragma: no cover
252
+ raise PluginError(
253
+ 'Relative paths are not allowed when the includer page'
254
+ ' source path is not provided. The exclude string'
255
+ f" '{exclude_string}' is located inside a generated page.",
256
+ )
244
257
  root_dir = os.path.abspath(
245
258
  os.path.dirname(includer_page_src_path),
246
259
  )
@@ -58,9 +58,42 @@ 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
+
77
+ def file_lineno_message(
78
+ page_src_path: str | None,
79
+ docs_dir: str,
80
+ lineno: int,
81
+ ) -> str:
82
+ """Return a message with the file path and line number."""
83
+ if page_src_path is None: # pragma: no cover
84
+ return f'generated page content (line {lineno})'
85
+ return (
86
+ f'{safe_os_path_relpath(page_src_path, docs_dir)}'
87
+ f':{lineno}'
88
+ )
89
+
90
+
61
91
  def get_file_content( # noqa: PLR0913, PLR0915
62
92
  markdown: str,
63
- page_src_path: str,
93
+ # Generated pages return `None` for `file.abs_src_path` because
94
+ # they are not read from a file. In this case, page_src_path is
95
+ # set to `None`.
96
+ page_src_path: str | None,
64
97
  docs_dir: str,
65
98
  tags: IncludeTags,
66
99
  defaults: DefaultValues,
@@ -85,8 +118,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
85
118
  )
86
119
  raise PluginError(
87
120
  "Found no path passed including with 'include'"
88
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
89
- f':{lineno}',
121
+ ' directive at'
122
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
90
123
  )
91
124
 
92
125
  arguments_string = match['arguments']
@@ -114,9 +147,10 @@ def get_file_content( # noqa: PLR0913, PLR0915
114
147
  )
115
148
  raise PluginError(
116
149
  "Invalid empty 'exclude' argument in 'include'"
117
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
118
- f':{lineno}',
150
+ ' directive at'
151
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
119
152
  )
153
+
120
154
  ignore_paths.extend(
121
155
  resolve_file_paths_to_exclude(
122
156
  exclude_string,
@@ -139,9 +173,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
139
173
  directive_match_start,
140
174
  )
141
175
  raise PluginError(
142
- f"No files found including '{raw_filename}'"
143
- f' at {os.path.relpath(page_src_path, docs_dir)}'
144
- f':{lineno}',
176
+ f"No files found including '{raw_filename}' at"
177
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
145
178
  )
146
179
 
147
180
  if files_watcher is not None and not is_url:
@@ -160,8 +193,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
160
193
  raise PluginError(
161
194
  f"Invalid value for '{invalid_bool_args[0]}' argument of"
162
195
  " 'include' directive at"
163
- f' {os.path.relpath(page_src_path, docs_dir)}'
164
- f':{lineno}. Possible values are true or false.',
196
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}.'
197
+ f' Possible values are true or false.',
165
198
  )
166
199
 
167
200
  start_match = ARGUMENT_REGEXES['start'].search(arguments_string)
@@ -173,8 +206,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
173
206
  directive_match_start,
174
207
  )
175
208
  raise PluginError(
176
- "Invalid empty 'start' argument in 'include' directive at "
177
- f'{os.path.relpath(page_src_path, docs_dir)}:{lineno}',
209
+ "Invalid empty 'start' argument in 'include' directive at"
210
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
178
211
  )
179
212
  else:
180
213
  start = defaults['start']
@@ -188,8 +221,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
188
221
  directive_match_start,
189
222
  )
190
223
  raise PluginError(
191
- "Invalid empty 'end' argument in 'include' directive at "
192
- f'{os.path.relpath(page_src_path, docs_dir)}:{lineno}',
224
+ "Invalid empty 'end' argument in 'include' directive at"
225
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
193
226
  )
194
227
  else:
195
228
  end = defaults['end']
@@ -204,8 +237,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
204
237
  )
205
238
  raise PluginError(
206
239
  "Invalid empty 'encoding' argument in 'include'"
207
- ' directive at '
208
- f'{os.path.relpath(page_src_path, docs_dir)}:{lineno}',
240
+ ' directive at'
241
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
209
242
  )
210
243
  else:
211
244
  encoding = defaults['encoding']
@@ -270,7 +303,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
270
303
  if expected_but_any_found[i]:
271
304
  delimiter_value = locals()[delimiter_name]
272
305
  readable_files_to_include = ', '.join([
273
- os.path.relpath(fpath, docs_dir)
306
+ safe_os_path_relpath(fpath, docs_dir)
274
307
  for fpath in file_paths_to_include
275
308
  ])
276
309
  plural_suffix = 's' if len(file_paths_to_include) > 1 else ''
@@ -278,12 +311,14 @@ def get_file_content( # noqa: PLR0913, PLR0915
278
311
  markdown,
279
312
  directive_match_start,
280
313
  )
281
- relative_path = os.path.relpath(page_src_path, docs_dir)
314
+ file_lineno = file_lineno_message(
315
+ page_src_path, docs_dir, lineno,
316
+ )
282
317
  logger.warning(
283
318
  (
284
319
  f"Delimiter {delimiter_name} '{delimiter_value}'"
285
320
  " of 'include' directive at"
286
- f' {relative_path}:{lineno}'
321
+ f' {file_lineno}'
287
322
  f' not detected in the file{plural_suffix}'
288
323
  f' {readable_files_to_include}'
289
324
  ),
@@ -307,8 +342,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
307
342
  )
308
343
  raise PluginError(
309
344
  "Found no path passed including with 'include-markdown'"
310
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
311
- f':{lineno}',
345
+ f' directive at'
346
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
312
347
  )
313
348
 
314
349
  arguments_string = match['arguments']
@@ -336,8 +371,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
336
371
  )
337
372
  raise PluginError(
338
373
  "Invalid empty 'exclude' argument in 'include-markdown'"
339
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
340
- f':{lineno}',
374
+ f' directive at'
375
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
341
376
  )
342
377
  ignore_paths.extend(
343
378
  resolve_file_paths_to_exclude(
@@ -362,8 +397,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
362
397
  )
363
398
  raise PluginError(
364
399
  f"No files found including '{raw_filename}' at"
365
- f' {os.path.relpath(page_src_path, docs_dir)}'
366
- f':{lineno}',
400
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
367
401
  )
368
402
 
369
403
  if files_watcher is not None and not is_url:
@@ -386,8 +420,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
386
420
  raise PluginError(
387
421
  f"Invalid value for '{invalid_bool_args[0]}' argument of"
388
422
  " 'include-markdown' directive at"
389
- f' {os.path.relpath(page_src_path, docs_dir)}'
390
- f':{lineno}. Possible values are true or false.',
423
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}.'
424
+ f' Possible values are true or false.',
391
425
  )
392
426
 
393
427
  # start and end arguments
@@ -401,8 +435,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
401
435
  )
402
436
  raise PluginError(
403
437
  "Invalid empty 'start' argument in 'include-markdown'"
404
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
405
- f':{lineno}',
438
+ f' directive at'
439
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
406
440
  )
407
441
  else:
408
442
  start = defaults['start']
@@ -417,8 +451,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
417
451
  )
418
452
  raise PluginError(
419
453
  "Invalid empty 'end' argument in 'include-markdown'"
420
- f' directive at {os.path.relpath(page_src_path, docs_dir)}'
421
- f':{lineno}',
454
+ f' directive at'
455
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
422
456
  )
423
457
  else:
424
458
  end = defaults['end']
@@ -433,8 +467,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
433
467
  )
434
468
  raise PluginError(
435
469
  "Invalid empty 'encoding' argument in 'include-markdown'"
436
- ' directive at '
437
- f'{os.path.relpath(page_src_path, docs_dir)}:{lineno}',
470
+ ' directive at'
471
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
438
472
  )
439
473
  else:
440
474
  encoding = defaults['encoding']
@@ -453,7 +487,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
453
487
  raise PluginError(
454
488
  "Invalid empty 'heading-offset' argument in"
455
489
  " 'include-markdown' directive at"
456
- f' {os.path.relpath(page_src_path, docs_dir)}:{lineno}',
490
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
457
491
  )
458
492
  try:
459
493
  offset = int(offset_raw_value)
@@ -464,8 +498,8 @@ def get_file_content( # noqa: PLR0913, PLR0915
464
498
  )
465
499
  raise PluginError(
466
500
  f"Invalid 'heading-offset' argument \"{offset_raw_value}\""
467
- " in 'include-markdown' directive at "
468
- f'{os.path.relpath(page_src_path, docs_dir)}:{lineno}',
501
+ " in 'include-markdown' directive at"
502
+ f' {file_lineno_message(page_src_path, docs_dir, lineno)}',
469
503
  ) from None
470
504
  else:
471
505
  offset = defaults['heading-offset']
@@ -523,11 +557,17 @@ def get_file_content( # noqa: PLR0913, PLR0915
523
557
 
524
558
  # relative URLs rewriting
525
559
  if bool_options['rewrite-relative-urls'].value:
526
- new_text_to_include = process.rewrite_relative_urls(
527
- new_text_to_include,
528
- source_path=file_path,
529
- destination_path=page_src_path,
530
- )
560
+ if page_src_path is None: # pragma: no cover
561
+ logger.warning(
562
+ 'Relative URLs rewriting is not supported in'
563
+ ' generated pages.',
564
+ )
565
+ else:
566
+ new_text_to_include = process.rewrite_relative_urls(
567
+ new_text_to_include,
568
+ source_path=file_path,
569
+ destination_path=page_src_path,
570
+ )
531
571
 
532
572
  # comments
533
573
  if bool_options['comments'].value:
@@ -569,7 +609,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
569
609
  if expected_but_any_found[i]:
570
610
  delimiter_value = locals()[delimiter_name]
571
611
  readable_files_to_include = ', '.join([
572
- os.path.relpath(fpath, docs_dir)
612
+ safe_os_path_relpath(fpath, docs_dir)
573
613
  for fpath in file_paths_to_include
574
614
  ])
575
615
  plural_suffix = 's' if len(file_paths_to_include) > 1 else ''
@@ -577,12 +617,14 @@ def get_file_content( # noqa: PLR0913, PLR0915
577
617
  markdown,
578
618
  directive_match_start,
579
619
  )
580
- relative_path = os.path.relpath(page_src_path, docs_dir)
620
+ file_lineno = file_lineno_message(
621
+ page_src_path, docs_dir, lineno,
622
+ )
581
623
  logger.warning(
582
624
  (
583
625
  f"Delimiter {delimiter_name} '{delimiter_value}' of"
584
626
  " 'include-markdown' directive at"
585
- f' {relative_path}:{lineno}'
627
+ f' {file_lineno}'
586
628
  f' not detected in the file{plural_suffix}'
587
629
  f' {readable_files_to_include}'
588
630
  ),