mkdocs-include-markdown-plugin 7.1.8__tar.gz → 7.2.1__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.
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/LICENSE +1 -1
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/PKG-INFO +54 -40
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/README.md +53 -39
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/pyproject.toml +2 -2
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/config.py +1 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/directive.py +100 -22
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/event.py +71 -6
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/plugin.py +12 -1
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/process.py +70 -20
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/.gitignore +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/__init__.py +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/cache.py +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/files_watcher.py +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/logger.py +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/placeholders.py +0 -0
- {mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/src/mkdocs_include_markdown_plugin/py.typed +0 -0
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright 2017-
|
|
190
|
+
Copyright 2017-2026 Joe Rickerby and contributors
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-include-markdown-plugin
|
|
3
|
-
Version: 7.1
|
|
3
|
+
Version: 7.2.1
|
|
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
|
|
@@ -181,6 +181,8 @@ plugins:
|
|
|
181
181
|
This plugin provides two directives, one to include Markdown files and another
|
|
182
182
|
to include files of any type.
|
|
183
183
|
|
|
184
|
+
#### Common arguments
|
|
185
|
+
|
|
184
186
|
Paths of included files can be either:
|
|
185
187
|
|
|
186
188
|
- URLs to include remote content.
|
|
@@ -199,36 +201,63 @@ single `'` quotes, which can be escaped prepending them a `\` character as
|
|
|
199
201
|
The arguments **start** and **end** may contain usual (Python-style) escape
|
|
200
202
|
sequences like `\n` to match against newlines.
|
|
201
203
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
#### **`include-markdown`**
|
|
205
|
-
|
|
206
|
-
Includes Markdown files content, optionally using two delimiters to filter the
|
|
207
|
-
content to include.
|
|
208
|
-
|
|
209
|
-
- <a name="include-markdown_start" href="#include-markdown_start">#</a>
|
|
204
|
+
- <a name="include_start" href="#include_start">#</a>
|
|
210
205
|
**start**: Delimiter that marks the beginning of the content to include.
|
|
211
|
-
- <a name="
|
|
206
|
+
- <a name="include_end" href="#include_end">#</a>
|
|
212
207
|
**end**: Delimiter that marks the end of the content to include.
|
|
213
|
-
- <a name="
|
|
208
|
+
- <a name="include_preserve-includer-indent" href="#include_preserve-includer-indent">#</a>
|
|
214
209
|
**preserve-includer-indent** (_true_): When this option is enabled (default),
|
|
215
210
|
every line of the content to include is indented with the same number of
|
|
216
211
|
spaces used to indent the includer `{% %}` template. Possible values are
|
|
217
212
|
`true` and `false`.
|
|
218
|
-
- <a name="
|
|
213
|
+
- <a name="include_dedent" href="#include_dedent">#</a>
|
|
219
214
|
**dedent** (_false_): If enabled, the included content will be dedented.
|
|
220
|
-
- <a name="
|
|
215
|
+
- <a name="include_exclude" href="#include_exclude">#</a>
|
|
221
216
|
**exclude**: Specify with a glob which files should be ignored. Only useful
|
|
222
217
|
when passing globs to include multiple files.
|
|
223
|
-
- <a name="
|
|
218
|
+
- <a name="include_trailing-newlines" href="#include_trailing-newlines">#</a>
|
|
224
219
|
**trailing-newlines** (_true_): When this option is disabled, the trailing newlines
|
|
225
220
|
found in the content to include are stripped. Possible values are `true` and `false`.
|
|
226
|
-
- <a name="
|
|
221
|
+
- <a name="include_recursive" href="#include_recursive">#</a>
|
|
227
222
|
**recursive** (_true_): When this option is disabled, included files are not
|
|
228
223
|
processed for recursive includes. Possible values are `true` and `false`.
|
|
229
|
-
- <a name="
|
|
224
|
+
- <a name="include_order" href="#include_order">#</a>
|
|
225
|
+
**order** (_'alpha-path'_): Define the order in which multiple files are included
|
|
226
|
+
when using globs. Possible values are:
|
|
227
|
+
- A combination of an optional order type and an optional order by separated
|
|
228
|
+
by a hyphen (`-`), and optionally prefixed by a hyphen (`-`) to indicate
|
|
229
|
+
ascending order. If an order type or an order by is not specified, the defaults
|
|
230
|
+
are used. It follows the form:
|
|
231
|
+
`[-]<order_type>-<order_by>` where:
|
|
232
|
+
- **Order type**:
|
|
233
|
+
- `'alpha'` (default): Alphabetical order.
|
|
234
|
+
- `'natural'`: Natural order, so that e.g. `file2.md` comes before `file10.md`.
|
|
235
|
+
- **Order by**:
|
|
236
|
+
- `'path'` (default): Order by full file path.
|
|
237
|
+
- `'name'`: Order by file name only.
|
|
238
|
+
- `'extension'`: Order by file extension.
|
|
239
|
+
- A combination of an optional prefix hyphen to denote ascending order and one
|
|
240
|
+
of the following values in the form `[-]<value>` where `<value>` is one of:
|
|
241
|
+
- `'size'`: Order by file size.
|
|
242
|
+
- `'mtime'`: Order by file modification time.
|
|
243
|
+
- `'ctime'`: Order by file creation time (or the last metadata change time
|
|
244
|
+
on Unix systems).
|
|
245
|
+
- `'atime'`: Order by file last access time.
|
|
246
|
+
- `'system'`: Order provided by the operating system. This is the same as not
|
|
247
|
+
specifying any order and relying on the default order of the filesystem.
|
|
248
|
+
This may be different between operating systems, so use it with care.
|
|
249
|
+
- `'random'`: Random order.
|
|
250
|
+
- <a name="include_encoding" href="#include_encoding">#</a>
|
|
230
251
|
**encoding** (_'utf-8'_): Specify the encoding of the included file.
|
|
231
252
|
If not defined `'utf-8'` will be used.
|
|
253
|
+
|
|
254
|
+
<!-- mdpo-disable-next-line -->
|
|
255
|
+
|
|
256
|
+
#### **`include-markdown`**
|
|
257
|
+
|
|
258
|
+
Includes Markdown files content, optionally using two delimiters to filter the
|
|
259
|
+
content to include.
|
|
260
|
+
|
|
232
261
|
- <a name="include-markdown_rewrite-relative-urls" href="#include-markdown_rewrite-relative-urls">#</a>
|
|
233
262
|
**rewrite-relative-urls** (_true_): When this option is enabled (default),
|
|
234
263
|
Markdown links and images in the content that are specified by a relative URL
|
|
@@ -284,6 +313,7 @@ content to include.
|
|
|
284
313
|
{%
|
|
285
314
|
include-markdown "**"
|
|
286
315
|
exclude="./{index,LICENSE}.md"
|
|
316
|
+
order="name"
|
|
287
317
|
%}
|
|
288
318
|
```
|
|
289
319
|
|
|
@@ -291,36 +321,19 @@ content to include.
|
|
|
291
321
|
{% include-markdown '/escap\'ed/single-quotes/in/file\'/name.md' %}
|
|
292
322
|
```
|
|
293
323
|
|
|
324
|
+
```jinja
|
|
325
|
+
{%
|
|
326
|
+
include-markdown "**"
|
|
327
|
+
order="-natural-extension"
|
|
328
|
+
%}
|
|
329
|
+
```
|
|
330
|
+
|
|
294
331
|
<!-- mdpo-disable-next-line -->
|
|
295
332
|
|
|
296
333
|
#### **`include`**
|
|
297
334
|
|
|
298
335
|
Includes the content of a file or a group of files.
|
|
299
336
|
|
|
300
|
-
- <a name="include_start" href="#include_start">#</a>
|
|
301
|
-
**start**: Delimiter that marks the beginning of the content to include.
|
|
302
|
-
- <a name="include_end" href="#include_end">#</a>
|
|
303
|
-
**end**: Delimiter that marks the end of the content to include.
|
|
304
|
-
- <a name="include_preserve-includer-indent" href="#include_preserve-includer-indent">#</a>
|
|
305
|
-
**preserve-includer-indent** (_true_): When this option is enabled (default),
|
|
306
|
-
every line of the content to include is indented with the same number of
|
|
307
|
-
spaces used to indent the includer `{% %}` template. Possible values are
|
|
308
|
-
`true` and `false`.
|
|
309
|
-
- <a name="include_dedent" href="#include_dedent">#</a>
|
|
310
|
-
**dedent** (_false_): If enabled, the included content will be dedented.
|
|
311
|
-
- <a name="include_exclude" href="#include_exclude">#</a>
|
|
312
|
-
**exclude**: Specify with a glob which files should be ignored. Only useful
|
|
313
|
-
when passing globs to include multiple files.
|
|
314
|
-
- <a name="include_trailing-newlines" href="#include_trailing-newlines">#</a>
|
|
315
|
-
**trailing-newlines** (_true_): When this option is disabled, the trailing newlines
|
|
316
|
-
found in the content to include are stripped. Possible values are `true` and `false`.
|
|
317
|
-
- <a name="include_recursive" href="#include_recursive">#</a>
|
|
318
|
-
**recursive** (_true_): When this option is disabled, included files are not
|
|
319
|
-
processed for recursive includes. Possible values are `true` and `false`.
|
|
320
|
-
- <a name="include_encoding" href="#include_encoding">#</a>
|
|
321
|
-
**encoding** (_'utf-8'_): Specify the encoding of the included file.
|
|
322
|
-
If not defined `'utf-8'` will be used.
|
|
323
|
-
|
|
324
337
|
##### Examples
|
|
325
338
|
|
|
326
339
|
```jinja
|
|
@@ -341,6 +354,7 @@ Includes the content of a file or a group of files.
|
|
|
341
354
|
{%
|
|
342
355
|
include '**'
|
|
343
356
|
exclude='./*.md'
|
|
357
|
+
order='random'
|
|
344
358
|
%}
|
|
345
359
|
```
|
|
346
360
|
|
|
@@ -146,6 +146,8 @@ plugins:
|
|
|
146
146
|
This plugin provides two directives, one to include Markdown files and another
|
|
147
147
|
to include files of any type.
|
|
148
148
|
|
|
149
|
+
#### Common arguments
|
|
150
|
+
|
|
149
151
|
Paths of included files can be either:
|
|
150
152
|
|
|
151
153
|
- URLs to include remote content.
|
|
@@ -164,36 +166,63 @@ single `'` quotes, which can be escaped prepending them a `\` character as
|
|
|
164
166
|
The arguments **start** and **end** may contain usual (Python-style) escape
|
|
165
167
|
sequences like `\n` to match against newlines.
|
|
166
168
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
#### **`include-markdown`**
|
|
170
|
-
|
|
171
|
-
Includes Markdown files content, optionally using two delimiters to filter the
|
|
172
|
-
content to include.
|
|
173
|
-
|
|
174
|
-
- <a name="include-markdown_start" href="#include-markdown_start">#</a>
|
|
169
|
+
- <a name="include_start" href="#include_start">#</a>
|
|
175
170
|
**start**: Delimiter that marks the beginning of the content to include.
|
|
176
|
-
- <a name="
|
|
171
|
+
- <a name="include_end" href="#include_end">#</a>
|
|
177
172
|
**end**: Delimiter that marks the end of the content to include.
|
|
178
|
-
- <a name="
|
|
173
|
+
- <a name="include_preserve-includer-indent" href="#include_preserve-includer-indent">#</a>
|
|
179
174
|
**preserve-includer-indent** (_true_): When this option is enabled (default),
|
|
180
175
|
every line of the content to include is indented with the same number of
|
|
181
176
|
spaces used to indent the includer `{% %}` template. Possible values are
|
|
182
177
|
`true` and `false`.
|
|
183
|
-
- <a name="
|
|
178
|
+
- <a name="include_dedent" href="#include_dedent">#</a>
|
|
184
179
|
**dedent** (_false_): If enabled, the included content will be dedented.
|
|
185
|
-
- <a name="
|
|
180
|
+
- <a name="include_exclude" href="#include_exclude">#</a>
|
|
186
181
|
**exclude**: Specify with a glob which files should be ignored. Only useful
|
|
187
182
|
when passing globs to include multiple files.
|
|
188
|
-
- <a name="
|
|
183
|
+
- <a name="include_trailing-newlines" href="#include_trailing-newlines">#</a>
|
|
189
184
|
**trailing-newlines** (_true_): When this option is disabled, the trailing newlines
|
|
190
185
|
found in the content to include are stripped. Possible values are `true` and `false`.
|
|
191
|
-
- <a name="
|
|
186
|
+
- <a name="include_recursive" href="#include_recursive">#</a>
|
|
192
187
|
**recursive** (_true_): When this option is disabled, included files are not
|
|
193
188
|
processed for recursive includes. Possible values are `true` and `false`.
|
|
194
|
-
- <a name="
|
|
189
|
+
- <a name="include_order" href="#include_order">#</a>
|
|
190
|
+
**order** (_'alpha-path'_): Define the order in which multiple files are included
|
|
191
|
+
when using globs. Possible values are:
|
|
192
|
+
- A combination of an optional order type and an optional order by separated
|
|
193
|
+
by a hyphen (`-`), and optionally prefixed by a hyphen (`-`) to indicate
|
|
194
|
+
ascending order. If an order type or an order by is not specified, the defaults
|
|
195
|
+
are used. It follows the form:
|
|
196
|
+
`[-]<order_type>-<order_by>` where:
|
|
197
|
+
- **Order type**:
|
|
198
|
+
- `'alpha'` (default): Alphabetical order.
|
|
199
|
+
- `'natural'`: Natural order, so that e.g. `file2.md` comes before `file10.md`.
|
|
200
|
+
- **Order by**:
|
|
201
|
+
- `'path'` (default): Order by full file path.
|
|
202
|
+
- `'name'`: Order by file name only.
|
|
203
|
+
- `'extension'`: Order by file extension.
|
|
204
|
+
- A combination of an optional prefix hyphen to denote ascending order and one
|
|
205
|
+
of the following values in the form `[-]<value>` where `<value>` is one of:
|
|
206
|
+
- `'size'`: Order by file size.
|
|
207
|
+
- `'mtime'`: Order by file modification time.
|
|
208
|
+
- `'ctime'`: Order by file creation time (or the last metadata change time
|
|
209
|
+
on Unix systems).
|
|
210
|
+
- `'atime'`: Order by file last access time.
|
|
211
|
+
- `'system'`: Order provided by the operating system. This is the same as not
|
|
212
|
+
specifying any order and relying on the default order of the filesystem.
|
|
213
|
+
This may be different between operating systems, so use it with care.
|
|
214
|
+
- `'random'`: Random order.
|
|
215
|
+
- <a name="include_encoding" href="#include_encoding">#</a>
|
|
195
216
|
**encoding** (_'utf-8'_): Specify the encoding of the included file.
|
|
196
217
|
If not defined `'utf-8'` will be used.
|
|
218
|
+
|
|
219
|
+
<!-- mdpo-disable-next-line -->
|
|
220
|
+
|
|
221
|
+
#### **`include-markdown`**
|
|
222
|
+
|
|
223
|
+
Includes Markdown files content, optionally using two delimiters to filter the
|
|
224
|
+
content to include.
|
|
225
|
+
|
|
197
226
|
- <a name="include-markdown_rewrite-relative-urls" href="#include-markdown_rewrite-relative-urls">#</a>
|
|
198
227
|
**rewrite-relative-urls** (_true_): When this option is enabled (default),
|
|
199
228
|
Markdown links and images in the content that are specified by a relative URL
|
|
@@ -249,6 +278,7 @@ content to include.
|
|
|
249
278
|
{%
|
|
250
279
|
include-markdown "**"
|
|
251
280
|
exclude="./{index,LICENSE}.md"
|
|
281
|
+
order="name"
|
|
252
282
|
%}
|
|
253
283
|
```
|
|
254
284
|
|
|
@@ -256,36 +286,19 @@ content to include.
|
|
|
256
286
|
{% include-markdown '/escap\'ed/single-quotes/in/file\'/name.md' %}
|
|
257
287
|
```
|
|
258
288
|
|
|
289
|
+
```jinja
|
|
290
|
+
{%
|
|
291
|
+
include-markdown "**"
|
|
292
|
+
order="-natural-extension"
|
|
293
|
+
%}
|
|
294
|
+
```
|
|
295
|
+
|
|
259
296
|
<!-- mdpo-disable-next-line -->
|
|
260
297
|
|
|
261
298
|
#### **`include`**
|
|
262
299
|
|
|
263
300
|
Includes the content of a file or a group of files.
|
|
264
301
|
|
|
265
|
-
- <a name="include_start" href="#include_start">#</a>
|
|
266
|
-
**start**: Delimiter that marks the beginning of the content to include.
|
|
267
|
-
- <a name="include_end" href="#include_end">#</a>
|
|
268
|
-
**end**: Delimiter that marks the end of the content to include.
|
|
269
|
-
- <a name="include_preserve-includer-indent" href="#include_preserve-includer-indent">#</a>
|
|
270
|
-
**preserve-includer-indent** (_true_): When this option is enabled (default),
|
|
271
|
-
every line of the content to include is indented with the same number of
|
|
272
|
-
spaces used to indent the includer `{% %}` template. Possible values are
|
|
273
|
-
`true` and `false`.
|
|
274
|
-
- <a name="include_dedent" href="#include_dedent">#</a>
|
|
275
|
-
**dedent** (_false_): If enabled, the included content will be dedented.
|
|
276
|
-
- <a name="include_exclude" href="#include_exclude">#</a>
|
|
277
|
-
**exclude**: Specify with a glob which files should be ignored. Only useful
|
|
278
|
-
when passing globs to include multiple files.
|
|
279
|
-
- <a name="include_trailing-newlines" href="#include_trailing-newlines">#</a>
|
|
280
|
-
**trailing-newlines** (_true_): When this option is disabled, the trailing newlines
|
|
281
|
-
found in the content to include are stripped. Possible values are `true` and `false`.
|
|
282
|
-
- <a name="include_recursive" href="#include_recursive">#</a>
|
|
283
|
-
**recursive** (_true_): When this option is disabled, included files are not
|
|
284
|
-
processed for recursive includes. Possible values are `true` and `false`.
|
|
285
|
-
- <a name="include_encoding" href="#include_encoding">#</a>
|
|
286
|
-
**encoding** (_'utf-8'_): Specify the encoding of the included file.
|
|
287
|
-
If not defined `'utf-8'` will be used.
|
|
288
|
-
|
|
289
302
|
##### Examples
|
|
290
303
|
|
|
291
304
|
```jinja
|
|
@@ -306,6 +319,7 @@ Includes the content of a file or a group of files.
|
|
|
306
319
|
{%
|
|
307
320
|
include '**'
|
|
308
321
|
exclude='./*.md'
|
|
322
|
+
order='random'
|
|
309
323
|
%}
|
|
310
324
|
```
|
|
311
325
|
|
{mkdocs_include_markdown_plugin-7.1.8 → mkdocs_include_markdown_plugin-7.2.1}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mkdocs-include-markdown-plugin"
|
|
3
|
-
version = "7.1
|
|
3
|
+
version = "7.2.1"
|
|
4
4
|
description = "Mkdocs Markdown includer plugin."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -151,7 +151,7 @@ select = [
|
|
|
151
151
|
"COM",
|
|
152
152
|
"SLOT",
|
|
153
153
|
]
|
|
154
|
-
ignore = ["G004"]
|
|
154
|
+
ignore = ["G004", "E731"]
|
|
155
155
|
|
|
156
156
|
[tool.ruff.lint.pydocstyle]
|
|
157
157
|
convention = "google"
|
|
@@ -20,6 +20,7 @@ class PluginConfig(Config): # noqa: D101
|
|
|
20
20
|
comments = MkType(bool, default=False)
|
|
21
21
|
rewrite_relative_urls = MkType(bool, default=True)
|
|
22
22
|
heading_offset = MkType(int, default=0)
|
|
23
|
+
order = MkType(str, default='alpha-path')
|
|
23
24
|
start = Optional(MkType(str))
|
|
24
25
|
end = Optional(MkType(str))
|
|
25
26
|
exclude = ListOfItems(MkType(str), default=[])
|
|
@@ -13,8 +13,15 @@ from typing import TYPE_CHECKING
|
|
|
13
13
|
from mkdocs.exceptions import PluginError
|
|
14
14
|
from wcmatch import glob
|
|
15
15
|
|
|
16
|
-
from mkdocs_include_markdown_plugin import process
|
|
17
16
|
from mkdocs_include_markdown_plugin.logger import logger
|
|
17
|
+
from mkdocs_include_markdown_plugin.process import (
|
|
18
|
+
file_lineno_message,
|
|
19
|
+
filter_paths,
|
|
20
|
+
is_absolute_path,
|
|
21
|
+
is_relative_path,
|
|
22
|
+
is_url,
|
|
23
|
+
sort_paths,
|
|
24
|
+
)
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
@dataclass
|
|
@@ -28,6 +35,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
28
35
|
from typing import Callable, Literal, TypedDict
|
|
29
36
|
|
|
30
37
|
DirectiveBoolArgumentsDict = dict[str, DirectiveBoolArgument]
|
|
38
|
+
OrderOption = tuple[bool, str, str]
|
|
31
39
|
|
|
32
40
|
DefaultValues = TypedDict(
|
|
33
41
|
'DefaultValues', {
|
|
@@ -41,6 +49,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
41
49
|
'recursive': bool,
|
|
42
50
|
'start': str | None,
|
|
43
51
|
'end': str | None,
|
|
52
|
+
'order': str,
|
|
44
53
|
},
|
|
45
54
|
)
|
|
46
55
|
|
|
@@ -92,10 +101,12 @@ def str_arg(arg: str) -> re.Pattern[str]:
|
|
|
92
101
|
|
|
93
102
|
|
|
94
103
|
ARGUMENT_REGEXES = {
|
|
104
|
+
# str
|
|
95
105
|
'start': functools.partial(str_arg, 'start'),
|
|
96
106
|
'end': functools.partial(str_arg, 'end'),
|
|
97
107
|
'exclude': functools.partial(str_arg, 'exclude'),
|
|
98
108
|
'encoding': functools.partial(str_arg, 'encoding'),
|
|
109
|
+
'order': functools.partial(str_arg, 'order'),
|
|
99
110
|
|
|
100
111
|
# bool
|
|
101
112
|
'comments': functools.partial(arg, 'comments'),
|
|
@@ -129,7 +140,7 @@ def _maybe_arguments_iter(arguments_string: str) -> Iterable[str]:
|
|
|
129
140
|
inside_string = False
|
|
130
141
|
escaping = False
|
|
131
142
|
opening_argument = False # whether we are at the beginning of an argument
|
|
132
|
-
current_value =
|
|
143
|
+
current_value: list[str] = []
|
|
133
144
|
|
|
134
145
|
for c in arguments_string:
|
|
135
146
|
if inside_string:
|
|
@@ -142,24 +153,25 @@ def _maybe_arguments_iter(arguments_string: str) -> Iterable[str]:
|
|
|
142
153
|
else:
|
|
143
154
|
escaping = False
|
|
144
155
|
elif c == '=':
|
|
156
|
+
current_value_str = ''.join(current_value)
|
|
145
157
|
new_current_value = ''
|
|
146
|
-
for ch in reversed(
|
|
158
|
+
for ch in reversed(current_value_str):
|
|
147
159
|
if ch in string.whitespace:
|
|
148
|
-
|
|
160
|
+
current_value_str = new_current_value[::-1]
|
|
149
161
|
break
|
|
150
162
|
new_current_value += ch
|
|
151
|
-
yield
|
|
152
|
-
current_value =
|
|
163
|
+
yield current_value_str
|
|
164
|
+
current_value = []
|
|
153
165
|
opening_argument = True
|
|
154
166
|
elif opening_argument:
|
|
155
167
|
opening_argument = False
|
|
156
168
|
if c in ('"', "'"):
|
|
157
169
|
current_string_opening = c
|
|
158
170
|
inside_string = True
|
|
159
|
-
current_value
|
|
160
|
-
current_value
|
|
171
|
+
current_value.append(c)
|
|
172
|
+
current_value.append(c)
|
|
161
173
|
else:
|
|
162
|
-
current_value
|
|
174
|
+
current_value.append(c)
|
|
163
175
|
|
|
164
176
|
|
|
165
177
|
def warn_invalid_directive_arguments(
|
|
@@ -178,7 +190,7 @@ def warn_invalid_directive_arguments(
|
|
|
178
190
|
)
|
|
179
191
|
for maybe_arg in _maybe_arguments_iter(arguments_string):
|
|
180
192
|
if maybe_arg not in valid_args:
|
|
181
|
-
location =
|
|
193
|
+
location = file_lineno_message(
|
|
182
194
|
page_src_path, docs_dir, directive_lineno(),
|
|
183
195
|
)
|
|
184
196
|
logger.warning(
|
|
@@ -283,12 +295,13 @@ def resolve_file_paths_to_include( # noqa: PLR0912
|
|
|
283
295
|
includer_page_src_path: str | None,
|
|
284
296
|
docs_dir: str,
|
|
285
297
|
ignore_paths: list[str],
|
|
298
|
+
order: str,
|
|
286
299
|
) -> tuple[list[str], bool]:
|
|
287
300
|
"""Resolve the file paths to include for a directive."""
|
|
288
|
-
if
|
|
301
|
+
if is_url(include_string):
|
|
289
302
|
return [include_string], True
|
|
290
303
|
|
|
291
|
-
if
|
|
304
|
+
if is_absolute_path(include_string):
|
|
292
305
|
if os.name == 'nt': # pragma: no cover
|
|
293
306
|
# Windows
|
|
294
307
|
fpath = os.path.normpath(include_string)
|
|
@@ -299,21 +312,25 @@ def resolve_file_paths_to_include( # noqa: PLR0912
|
|
|
299
312
|
if not is_file:
|
|
300
313
|
return [], False
|
|
301
314
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
),
|
|
315
|
+
paths = filter_paths([fpath], ignore_paths)
|
|
316
|
+
is_url_ = False
|
|
317
|
+
return sort_paths(paths, parse_order_option(order)), is_url_
|
|
305
318
|
|
|
306
319
|
try:
|
|
307
320
|
is_file = stat.S_ISREG(os.stat(include_string).st_mode)
|
|
308
321
|
except (FileNotFoundError, OSError):
|
|
309
322
|
is_file = False
|
|
310
|
-
|
|
323
|
+
paths = filter_paths(
|
|
311
324
|
[include_string] if is_file else glob.iglob(
|
|
312
325
|
include_string, flags=GLOB_FLAGS,
|
|
313
326
|
),
|
|
314
|
-
ignore_paths
|
|
327
|
+
ignore_paths,
|
|
328
|
+
)
|
|
329
|
+
is_url_ = False
|
|
330
|
+
sort_paths(paths, parse_order_option(order))
|
|
331
|
+
return paths, is_url_
|
|
315
332
|
|
|
316
|
-
if
|
|
333
|
+
if is_relative_path(include_string):
|
|
317
334
|
if includer_page_src_path is None: # pragma: no cover
|
|
318
335
|
raise PluginError(
|
|
319
336
|
'Relative paths are not allowed when the includer page'
|
|
@@ -338,7 +355,10 @@ def resolve_file_paths_to_include( # noqa: PLR0912
|
|
|
338
355
|
root_dir=root_dir,
|
|
339
356
|
):
|
|
340
357
|
paths.append(os.path.join(root_dir, fp))
|
|
341
|
-
|
|
358
|
+
paths = filter_paths(paths, ignore_paths)
|
|
359
|
+
is_url_ = False
|
|
360
|
+
sort_paths(paths, parse_order_option(order))
|
|
361
|
+
return paths, is_url_
|
|
342
362
|
|
|
343
363
|
# relative to docs_dir
|
|
344
364
|
paths = []
|
|
@@ -357,7 +377,10 @@ def resolve_file_paths_to_include( # noqa: PLR0912
|
|
|
357
377
|
root_dir=root_dir,
|
|
358
378
|
):
|
|
359
379
|
paths.append(os.path.join(root_dir, fp))
|
|
360
|
-
|
|
380
|
+
paths = filter_paths(paths, ignore_paths)
|
|
381
|
+
is_url_ = False
|
|
382
|
+
sort_paths(paths, parse_order_option(order))
|
|
383
|
+
return paths, is_url_
|
|
361
384
|
|
|
362
385
|
|
|
363
386
|
def resolve_file_paths_to_exclude(
|
|
@@ -366,10 +389,10 @@ def resolve_file_paths_to_exclude(
|
|
|
366
389
|
docs_dir: str,
|
|
367
390
|
) -> list[str]:
|
|
368
391
|
"""Resolve the file paths to exclude for a directive."""
|
|
369
|
-
if
|
|
392
|
+
if is_absolute_path(exclude_string):
|
|
370
393
|
return glob.glob(exclude_string, flags=GLOB_FLAGS)
|
|
371
394
|
|
|
372
|
-
if
|
|
395
|
+
if is_relative_path(exclude_string):
|
|
373
396
|
if includer_page_src_path is None: # pragma: no cover
|
|
374
397
|
raise PluginError(
|
|
375
398
|
'Relative paths are not allowed when the includer page'
|
|
@@ -394,3 +417,58 @@ def resolve_file_paths_to_exclude(
|
|
|
394
417
|
flags=GLOB_FLAGS,
|
|
395
418
|
root_dir=docs_dir,
|
|
396
419
|
)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def validate_order_option(
|
|
423
|
+
order: str,
|
|
424
|
+
page_src_path: str | None,
|
|
425
|
+
docs_dir: str,
|
|
426
|
+
directive_lineno: Callable[[], int],
|
|
427
|
+
directive: str,
|
|
428
|
+
) -> None:
|
|
429
|
+
"""Validate the 'order' option."""
|
|
430
|
+
regex = get_order_option_regex()
|
|
431
|
+
match = regex.match(order)
|
|
432
|
+
if not match:
|
|
433
|
+
location = file_lineno_message(
|
|
434
|
+
page_src_path, docs_dir, directive_lineno(),
|
|
435
|
+
)
|
|
436
|
+
raise PluginError(
|
|
437
|
+
f"Invalid value '{order}' for the 'order' argument in"
|
|
438
|
+
f" '{directive}' directive at {location}. The argument"
|
|
439
|
+
" 'order' must be a string that matches the regex"
|
|
440
|
+
f" '{regex.pattern}'.",
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
@functools.cache
|
|
445
|
+
def get_order_option_regex() -> re.Pattern[str]:
|
|
446
|
+
"""Return the compiled regex to validate the 'order' option."""
|
|
447
|
+
return re.compile(
|
|
448
|
+
r'^-?'
|
|
449
|
+
r'(?:'
|
|
450
|
+
r'(?:alpha|natural)?(?:-?(?:path|name|extension))?'
|
|
451
|
+
r'|system|random|size|mtime|ctime|atime'
|
|
452
|
+
r')?$',
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
def parse_order_option(order: str) -> OrderOption:
|
|
457
|
+
"""Parse the 'order' option into a tuple."""
|
|
458
|
+
ascending = False
|
|
459
|
+
order_type = 'alpha'
|
|
460
|
+
order_by = 'path'
|
|
461
|
+
if order.startswith('-'):
|
|
462
|
+
ascending = True
|
|
463
|
+
order = order[1:]
|
|
464
|
+
order_split = order.split('-', 1)
|
|
465
|
+
if len(order_split) == 2: # noqa: PLR2004
|
|
466
|
+
order_type, order_by = order_split
|
|
467
|
+
elif order_split[0] in (
|
|
468
|
+
'alpha', 'random', 'natural', 'system',
|
|
469
|
+
'size', 'mtime', 'ctime', 'atime',
|
|
470
|
+
):
|
|
471
|
+
order_type = order_split[0]
|
|
472
|
+
elif order_split[0] in ('name', 'path', 'extension'):
|
|
473
|
+
order_by = order_split[0]
|
|
474
|
+
return ascending, order_type, order_by
|
|
@@ -24,6 +24,7 @@ from mkdocs_include_markdown_plugin.directive import (
|
|
|
24
24
|
parse_string_argument,
|
|
25
25
|
resolve_file_paths_to_exclude,
|
|
26
26
|
resolve_file_paths_to_include,
|
|
27
|
+
validate_order_option,
|
|
27
28
|
warn_invalid_directive_arguments,
|
|
28
29
|
)
|
|
29
30
|
from mkdocs_include_markdown_plugin.files_watcher import FilesWatcher
|
|
@@ -141,13 +142,42 @@ def get_file_content( # noqa: PLR0913, PLR0915
|
|
|
141
142
|
):
|
|
142
143
|
ignore_paths.append(path)
|
|
143
144
|
|
|
145
|
+
order = defaults['order']
|
|
146
|
+
if 'order' in used_arguments:
|
|
147
|
+
order_match = ARGUMENT_REGEXES['order']().search(
|
|
148
|
+
arguments_string,
|
|
149
|
+
)
|
|
150
|
+
order_ = parse_string_argument(order_match)
|
|
151
|
+
if order_ is None:
|
|
152
|
+
location = process.file_lineno_message(
|
|
153
|
+
page_src_path, docs_dir, directive_lineno(),
|
|
154
|
+
)
|
|
155
|
+
raise PluginError(
|
|
156
|
+
"Invalid empty 'order' argument in 'include'"
|
|
157
|
+
f' directive at {location}',
|
|
158
|
+
)
|
|
159
|
+
validate_order_option(
|
|
160
|
+
order_, page_src_path, docs_dir, directive_lineno, 'include',
|
|
161
|
+
)
|
|
162
|
+
order = order_
|
|
163
|
+
|
|
144
164
|
file_paths_to_include, is_url = resolve_file_paths_to_include(
|
|
145
165
|
filename,
|
|
146
166
|
page_src_path,
|
|
147
167
|
docs_dir,
|
|
148
168
|
ignore_paths,
|
|
169
|
+
order,
|
|
149
170
|
)
|
|
150
171
|
|
|
172
|
+
if is_url and 'order' in used_arguments: # pragma: no cover
|
|
173
|
+
location = process.file_lineno_message(
|
|
174
|
+
page_src_path, docs_dir, directive_lineno(),
|
|
175
|
+
)
|
|
176
|
+
logger.warning(
|
|
177
|
+
f"Ignoring 'order' argument of 'include' directive"
|
|
178
|
+
f" at {location} because the included path is a URL",
|
|
179
|
+
)
|
|
180
|
+
|
|
151
181
|
if not file_paths_to_include:
|
|
152
182
|
location = process.file_lineno_message(
|
|
153
183
|
page_src_path, docs_dir, directive_lineno(),
|
|
@@ -353,13 +383,46 @@ def get_file_content( # noqa: PLR0913, PLR0915
|
|
|
353
383
|
):
|
|
354
384
|
ignore_paths.append(path)
|
|
355
385
|
|
|
386
|
+
order = defaults['order']
|
|
387
|
+
if 'order' in used_arguments:
|
|
388
|
+
order_match = ARGUMENT_REGEXES['order']().search(
|
|
389
|
+
arguments_string,
|
|
390
|
+
)
|
|
391
|
+
order_ = parse_string_argument(order_match)
|
|
392
|
+
if order_ is None:
|
|
393
|
+
location = process.file_lineno_message(
|
|
394
|
+
page_src_path, docs_dir, directive_lineno(),
|
|
395
|
+
)
|
|
396
|
+
raise PluginError(
|
|
397
|
+
"Invalid empty 'order' argument in 'include-markdown'"
|
|
398
|
+
f' directive at {location}',
|
|
399
|
+
)
|
|
400
|
+
validate_order_option(
|
|
401
|
+
order_,
|
|
402
|
+
page_src_path,
|
|
403
|
+
docs_dir,
|
|
404
|
+
directive_lineno,
|
|
405
|
+
'include-markdown',
|
|
406
|
+
)
|
|
407
|
+
order = order_
|
|
408
|
+
|
|
356
409
|
file_paths_to_include, is_url = resolve_file_paths_to_include(
|
|
357
410
|
filename,
|
|
358
411
|
page_src_path,
|
|
359
412
|
docs_dir,
|
|
360
413
|
ignore_paths,
|
|
414
|
+
order,
|
|
361
415
|
)
|
|
362
416
|
|
|
417
|
+
if is_url and 'order' in used_arguments: # pragma: no cover
|
|
418
|
+
location = process.file_lineno_message(
|
|
419
|
+
page_src_path, docs_dir, directive_lineno(),
|
|
420
|
+
)
|
|
421
|
+
logger.warning(
|
|
422
|
+
f"Ignoring 'order' argument of 'include-markdown' directive"
|
|
423
|
+
f" at {location} because the included path is a URL",
|
|
424
|
+
)
|
|
425
|
+
|
|
363
426
|
if not file_paths_to_include:
|
|
364
427
|
location = process.file_lineno_message(
|
|
365
428
|
page_src_path, docs_dir, directive_lineno(),
|
|
@@ -482,7 +545,7 @@ def get_file_content( # noqa: PLR0913, PLR0915
|
|
|
482
545
|
# but they have been specified, so the warning(s) must be raised
|
|
483
546
|
expected_but_any_found = [start is not None, end is not None]
|
|
484
547
|
|
|
485
|
-
|
|
548
|
+
text_to_include_parts = []
|
|
486
549
|
for file_path in file_paths_to_include:
|
|
487
550
|
if process.is_url(filename):
|
|
488
551
|
new_text_to_include = process.read_url(
|
|
@@ -558,11 +621,10 @@ def get_file_content( # noqa: PLR0913, PLR0915
|
|
|
558
621
|
new_text_to_include
|
|
559
622
|
):
|
|
560
623
|
lines = new_text_to_include.splitlines(keepends=True)
|
|
561
|
-
|
|
624
|
+
indented_lines = [lines[0]]
|
|
562
625
|
for i in range(1, len(lines)):
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
)
|
|
626
|
+
indented_lines.append(filled_includer_indent + lines[i])
|
|
627
|
+
new_text_to_include = ''.join(indented_lines)
|
|
566
628
|
|
|
567
629
|
if offset:
|
|
568
630
|
new_text_to_include = process.increase_headings_offset(
|
|
@@ -570,7 +632,9 @@ def get_file_content( # noqa: PLR0913, PLR0915
|
|
|
570
632
|
offset=offset + cumulative_heading_offset,
|
|
571
633
|
)
|
|
572
634
|
|
|
573
|
-
|
|
635
|
+
text_to_include_parts.append(new_text_to_include)
|
|
636
|
+
|
|
637
|
+
text_to_include = ''.join(text_to_include_parts)
|
|
574
638
|
|
|
575
639
|
# warn if expected start or ends haven't been found in included content
|
|
576
640
|
for i, delimiter_name in enumerate(['start', 'end']):
|
|
@@ -645,6 +709,7 @@ def on_page_markdown(
|
|
|
645
709
|
'recursive': config.recursive,
|
|
646
710
|
'start': config.start,
|
|
647
711
|
'end': config.end,
|
|
712
|
+
'order': config.order,
|
|
648
713
|
},
|
|
649
714
|
Settings(
|
|
650
715
|
exclude=config.exclude,
|
|
@@ -11,7 +11,6 @@ from mkdocs.plugins import BasePlugin, event_priority
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING: # pragma: no cover
|
|
14
|
-
|
|
15
14
|
from mkdocs.config.defaults import MkDocsConfig
|
|
16
15
|
from mkdocs.livereload import LiveReloadServer
|
|
17
16
|
from mkdocs.structure.files import Files
|
|
@@ -19,6 +18,9 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
19
18
|
|
|
20
19
|
from mkdocs_include_markdown_plugin.cache import Cache, initialize_cache
|
|
21
20
|
from mkdocs_include_markdown_plugin.config import PluginConfig
|
|
21
|
+
from mkdocs_include_markdown_plugin.directive import (
|
|
22
|
+
get_order_option_regex,
|
|
23
|
+
)
|
|
22
24
|
from mkdocs_include_markdown_plugin.event import (
|
|
23
25
|
on_page_markdown as _on_page_markdown,
|
|
24
26
|
)
|
|
@@ -50,6 +52,15 @@ class IncludeMarkdownPlugin(BasePlugin[PluginConfig]):
|
|
|
50
52
|
' "include-markdown".',
|
|
51
53
|
)
|
|
52
54
|
|
|
55
|
+
if self.config.order != 'alpha-path':
|
|
56
|
+
regex = get_order_option_regex()
|
|
57
|
+
if not regex.match(self.config.order):
|
|
58
|
+
raise PluginError(
|
|
59
|
+
f"Invalid value '{self.config.order}' for the 'order'"
|
|
60
|
+
' global setting. Order must be a string'
|
|
61
|
+
f" that matches the regex '{regex.pattern}'.",
|
|
62
|
+
)
|
|
63
|
+
|
|
53
64
|
return config
|
|
54
65
|
|
|
55
66
|
@cached_property
|
|
@@ -15,6 +15,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
15
15
|
from typing import Any
|
|
16
16
|
|
|
17
17
|
from mkdocs_include_markdown_plugin.cache import Cache
|
|
18
|
+
from mkdocs_include_markdown_plugin.directive import OrderOption
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
# Markdown regular expressions. Taken from the original Markdown.pl by John
|
|
@@ -173,10 +174,12 @@ def transform_p_by_p_skipping_codeblocks( # noqa: PLR0912, PLR0915
|
|
|
173
174
|
_maybe_icodeblock_lines: list[str] = []
|
|
174
175
|
_previous_line_was_empty = False
|
|
175
176
|
|
|
176
|
-
lines
|
|
177
|
+
lines = []
|
|
178
|
+
current_paragraph_lines: list[str] = []
|
|
177
179
|
|
|
178
180
|
def process_current_paragraph() -> None:
|
|
179
|
-
lines.extend(func(
|
|
181
|
+
lines.extend(func(''.join(current_paragraph_lines),
|
|
182
|
+
).splitlines(keepends=True))
|
|
180
183
|
|
|
181
184
|
# The next implementation takes into account that indented code
|
|
182
185
|
# blocks must be surrounded by newlines as per the CommonMark
|
|
@@ -190,25 +193,24 @@ def transform_p_by_p_skipping_codeblocks( # noqa: PLR0912, PLR0915
|
|
|
190
193
|
if lstripped_line.startswith(('```', '~~~')):
|
|
191
194
|
_current_fcodeblock_delimiter = lstripped_line[:3]
|
|
192
195
|
process_current_paragraph()
|
|
193
|
-
|
|
196
|
+
current_paragraph_lines = []
|
|
194
197
|
lines.append(line)
|
|
195
198
|
elif line.startswith(' '):
|
|
196
199
|
if not lstripped_line or _maybe_icodeblock_lines:
|
|
197
200
|
# maybe enter indented codeblock
|
|
198
201
|
_maybe_icodeblock_lines.append(line)
|
|
199
202
|
else:
|
|
200
|
-
|
|
203
|
+
current_paragraph_lines.append(line)
|
|
201
204
|
elif _maybe_icodeblock_lines:
|
|
202
205
|
process_current_paragraph()
|
|
203
|
-
|
|
206
|
+
current_paragraph_lines = []
|
|
204
207
|
if not _previous_line_was_empty:
|
|
205
208
|
# wasn't an indented code block
|
|
206
|
-
|
|
207
|
-
current_paragraph += line_
|
|
209
|
+
current_paragraph_lines.extend(_maybe_icodeblock_lines)
|
|
208
210
|
_maybe_icodeblock_lines = []
|
|
209
|
-
|
|
211
|
+
current_paragraph_lines.append(line)
|
|
210
212
|
process_current_paragraph()
|
|
211
|
-
|
|
213
|
+
current_paragraph_lines = []
|
|
212
214
|
else:
|
|
213
215
|
# exit indented codeblock
|
|
214
216
|
for line_ in _maybe_icodeblock_lines:
|
|
@@ -216,7 +218,7 @@ def transform_p_by_p_skipping_codeblocks( # noqa: PLR0912, PLR0915
|
|
|
216
218
|
_maybe_icodeblock_lines = []
|
|
217
219
|
lines.append(line)
|
|
218
220
|
else:
|
|
219
|
-
|
|
221
|
+
current_paragraph_lines.append(line)
|
|
220
222
|
_previous_line_was_empty = not lstripped_line
|
|
221
223
|
else:
|
|
222
224
|
lines.append(line)
|
|
@@ -229,14 +231,13 @@ def transform_p_by_p_skipping_codeblocks( # noqa: PLR0912, PLR0915
|
|
|
229
231
|
if not _previous_line_was_empty:
|
|
230
232
|
# at EOF
|
|
231
233
|
process_current_paragraph()
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
current_paragraph += line_
|
|
234
|
+
current_paragraph_lines = []
|
|
235
|
+
current_paragraph_lines.extend(_maybe_icodeblock_lines)
|
|
235
236
|
process_current_paragraph()
|
|
236
|
-
|
|
237
|
+
current_paragraph_lines = []
|
|
237
238
|
else:
|
|
238
239
|
process_current_paragraph()
|
|
239
|
-
|
|
240
|
+
current_paragraph_lines = []
|
|
240
241
|
for line_ in _maybe_icodeblock_lines:
|
|
241
242
|
lines.append(line_)
|
|
242
243
|
else:
|
|
@@ -494,12 +495,12 @@ def filter_paths(
|
|
|
494
495
|
|
|
495
496
|
Args:
|
|
496
497
|
filepaths (list): Set of source paths to filter.
|
|
497
|
-
ignore_paths (list): Paths that
|
|
498
|
+
ignore_paths (list): Paths that are ignored.
|
|
498
499
|
|
|
499
500
|
Returns:
|
|
500
501
|
list: Non filtered paths ordered alphabetically.
|
|
501
502
|
"""
|
|
502
|
-
|
|
503
|
+
result = []
|
|
503
504
|
for filepath in filepaths:
|
|
504
505
|
# ignore by filepath
|
|
505
506
|
if filepath in ignore_paths:
|
|
@@ -514,11 +515,60 @@ def filter_paths(
|
|
|
514
515
|
# ignore if is a directory
|
|
515
516
|
try:
|
|
516
517
|
if not stat.S_ISDIR(os.stat(filepath).st_mode):
|
|
517
|
-
|
|
518
|
+
result.append(filepath)
|
|
518
519
|
except (FileNotFoundError, OSError): # pragma: no cover
|
|
519
520
|
continue
|
|
520
|
-
|
|
521
|
-
|
|
521
|
+
return result
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def natural_sort_key(s: str) -> list[Any]:
|
|
525
|
+
"""Key function for natural sorting of strings."""
|
|
526
|
+
return [int(text) if text.isdigit() else text.lower()
|
|
527
|
+
for text in re.split(r'(\d+)', s)]
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def sort_paths(paths: list[str], order: OrderOption) -> list[str]:
|
|
531
|
+
"""Sort a list of paths in-place according to an order option."""
|
|
532
|
+
ascending, order_type, order_by = order
|
|
533
|
+
|
|
534
|
+
if order_type == 'random':
|
|
535
|
+
import random # noqa: PLC0415
|
|
536
|
+
|
|
537
|
+
random.shuffle(paths)
|
|
538
|
+
return paths
|
|
539
|
+
|
|
540
|
+
key = None
|
|
541
|
+
if order_type == 'alpha':
|
|
542
|
+
if order_by == 'name':
|
|
543
|
+
def key(p: str) -> str:
|
|
544
|
+
return os.path.basename(p)
|
|
545
|
+
elif order_by == 'extension':
|
|
546
|
+
def key(p: str) -> str:
|
|
547
|
+
return os.path.splitext(p)[1]
|
|
548
|
+
elif order_type == 'natural':
|
|
549
|
+
if order_by == 'extension':
|
|
550
|
+
def key(p: str) -> str:
|
|
551
|
+
return natural_sort_key(os.path.splitext(p)[1]) # type: ignore
|
|
552
|
+
elif order_by == 'name':
|
|
553
|
+
def key(p: str) -> str:
|
|
554
|
+
return natural_sort_key(os.path.basename(p)) # type: ignore
|
|
555
|
+
else:
|
|
556
|
+
key = natural_sort_key # type: ignore
|
|
557
|
+
elif order_type == 'size':
|
|
558
|
+
def key(p: str) -> int: # type: ignore
|
|
559
|
+
return os.path.getsize(p)
|
|
560
|
+
ascending = not ascending # larger files first
|
|
561
|
+
elif order_type == 'mtime':
|
|
562
|
+
def key(p: str) -> float: # type: ignore
|
|
563
|
+
return os.path.getmtime(p)
|
|
564
|
+
elif order_type == 'ctime':
|
|
565
|
+
def key(p: str) -> float: # type: ignore
|
|
566
|
+
return os.path.getctime(p)
|
|
567
|
+
elif order_type == 'atime':
|
|
568
|
+
def key(p: str) -> float: # type: ignore
|
|
569
|
+
return os.path.getatime(p)
|
|
570
|
+
paths.sort(key=key, reverse=ascending)
|
|
571
|
+
return paths
|
|
522
572
|
|
|
523
573
|
|
|
524
574
|
def _is_valid_url_scheme_char(c: str) -> bool:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|