rolfedh-doc-utils 0.1.0__tar.gz → 0.1.2__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 (34) hide show
  1. rolfedh_doc_utils-0.1.2/PKG-INFO +257 -0
  2. rolfedh_doc_utils-0.1.2/README.md +225 -0
  3. rolfedh_doc_utils-0.1.2/archive_unused_files.py +35 -0
  4. rolfedh_doc_utils-0.1.2/archive_unused_images.py +35 -0
  5. rolfedh_doc_utils-0.1.2/check_scannability.py +109 -0
  6. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/file_utils.py +47 -3
  7. rolfedh_doc_utils-0.1.2/find_unused_attributes.py +41 -0
  8. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/pyproject.toml +5 -2
  9. rolfedh_doc_utils-0.1.2/rolfedh_doc_utils.egg-info/PKG-INFO +257 -0
  10. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/rolfedh_doc_utils.egg-info/SOURCES.txt +10 -0
  11. rolfedh_doc_utils-0.1.2/rolfedh_doc_utils.egg-info/top_level.txt +5 -0
  12. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/tests/test_archive_unused_files.py +1 -0
  13. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/tests/test_archive_unused_images.py +9 -4
  14. rolfedh_doc_utils-0.1.2/tests/test_cli_entry_points.py +348 -0
  15. rolfedh_doc_utils-0.1.2/tests/test_file_utils.py +350 -0
  16. rolfedh_doc_utils-0.1.2/tests/test_fixture_archive_unused_files.py +38 -0
  17. rolfedh_doc_utils-0.1.2/tests/test_fixture_archive_unused_images.py +45 -0
  18. rolfedh_doc_utils-0.1.2/tests/test_fixture_check_scannability.py +26 -0
  19. rolfedh_doc_utils-0.1.2/tests/test_parse_exclude_list.py +62 -0
  20. rolfedh_doc_utils-0.1.0/PKG-INFO +0 -83
  21. rolfedh_doc_utils-0.1.0/README.md +0 -51
  22. rolfedh_doc_utils-0.1.0/rolfedh_doc_utils.egg-info/PKG-INFO +0 -83
  23. rolfedh_doc_utils-0.1.0/rolfedh_doc_utils.egg-info/top_level.txt +0 -1
  24. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/LICENSE +0 -0
  25. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/__init__.py +0 -0
  26. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/scannability.py +0 -0
  27. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/unused_adoc.py +0 -0
  28. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/unused_attributes.py +0 -0
  29. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/doc_utils/unused_images.py +0 -0
  30. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/rolfedh_doc_utils.egg-info/dependency_links.txt +0 -0
  31. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/rolfedh_doc_utils.egg-info/entry_points.txt +0 -0
  32. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/setup.cfg +0 -0
  33. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/tests/test_check_scannability.py +0 -0
  34. {rolfedh_doc_utils-0.1.0 → rolfedh_doc_utils-0.1.2}/tests/test_unused_attributes.py +0 -0
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: rolfedh-doc-utils
3
+ Version: 0.1.2
4
+ Summary: CLI tools for AsciiDoc documentation projects
5
+ Author: Rolfe Dlugy-Hegwer
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Rolfe Dlugy-Hegwer
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Requires-Python: >=3.8
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Dynamic: license-file
32
+
33
+ # doc-utils
34
+
35
+ A set of Python utilities and CLI tools to help technical writers maintain AsciiDoc documentation repositories.
36
+
37
+ > ⚠️ **IMPORTANT: Safety First**
38
+ >
39
+ > These tools can modify or delete files in your documentation repository. Always:
40
+ > - **Work in a git branch** - Never run these tools on the main/master branch
41
+ > - **Review all changes carefully** - Use `git diff` or a pull request to verify modifications
42
+ > - **Check your preview builds** - Ensure no documentation errors were introduced
43
+
44
+ ## Resources
45
+
46
+ - [PyPI: rolfedh-doc-utils](https://pypi.org/project/rolfedh-doc-utils/)
47
+ - [GitHub repository](https://github.com/rolfedh/doc-utils)
48
+
49
+ ## Installation
50
+
51
+ ### From PyPI
52
+
53
+ Install the package from PyPI:
54
+
55
+ ```sh
56
+ pip install rolfedh-doc-utils
57
+ ````
58
+
59
+ ### For Development
60
+
61
+ If you're developing or testing locally, install the package in editable mode:
62
+
63
+ ```sh
64
+ # Clone the repository
65
+ git clone https://github.com/rolfedh/doc-utils.git
66
+ cd doc-utils
67
+
68
+ # Install in editable mode
69
+ pip install -e .
70
+ ```
71
+
72
+ The following CLI tools are installed:
73
+
74
+ * `check-scannability`
75
+ * `archive-unused-files`
76
+ * `archive-unused-images`
77
+ * `find-unused-attributes`
78
+
79
+ These tools can be run from any directory.
80
+
81
+ ### Add to PATH (if needed)
82
+
83
+ By default, CLI tools install to:
84
+
85
+ ```sh
86
+ $HOME/.local/bin
87
+ ```
88
+
89
+ If this directory isn’t in your `PATH`, commands may not run. Append it to your shell configuration:
90
+
91
+ ```sh
92
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # or ~/.zshrc
93
+ ```
94
+
95
+ Then reload your shell:
96
+
97
+ ```sh
98
+ source ~/.bashrc # or ~/.zshrc
99
+ ```
100
+
101
+ ## CLI Tools Overview
102
+
103
+ ### `check-scannability`
104
+
105
+ Scans `.adoc` files in the current directory to report:
106
+
107
+ * Sentences that exceed a length limit (default: 22 words)
108
+ * Paragraphs with too many sentences (default: 3 sentences)
109
+ * Supports exclusion of files and directories
110
+
111
+ ➡️ See [`check_scannability.md`](https://github.com/rolfedh/doc-utils/blob/main/check_scannability.md) for details.
112
+
113
+ ---
114
+
115
+ ### `archive-unused-files`
116
+
117
+ Scans the `./modules` and `./assemblies` directories for `.adoc` files that are not referenced. Optionally archives and deletes them.
118
+
119
+ ➡️ See [`archive_unused_files.md`](https://github.com/rolfedh/doc-utils/blob/main/archive_unused_files.md).
120
+
121
+ ---
122
+
123
+ ### `archive-unused-images`
124
+
125
+ Finds unused image files (e.g., `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`) in the current directory and optionally archives and deletes them.
126
+
127
+ ➡️ See [`archive_unused_images.md`](https://github.com/rolfedh/doc-utils/blob/main/archive_unused_images.md).
128
+
129
+ ---
130
+
131
+ ### `find-unused-attributes`
132
+
133
+ Scans an attributes file (e.g., `attributes.adoc`) for unused attribute definitions across all `.adoc` files in the current directory.
134
+
135
+ ➡️ See [`find_unused_attributes.md`](https://github.com/rolfedh/doc-utils/blob/main/find_unused_attributes.md).
136
+
137
+ ## Best Practices for Safe Usage
138
+
139
+ ### Before Running Any Tool:
140
+
141
+ - **Create a feature branch:**
142
+ ```sh
143
+ git checkout -b doc-cleanup-$(date +%Y%m%d)
144
+ ```
145
+
146
+ - **Commit any pending changes:**
147
+ ```sh
148
+ git add -A && git commit -m "Save work before cleanup"
149
+ ```
150
+
151
+ - **Run tools in preview mode first:**
152
+ - For archive tools: Run without `--archive` to see what would be affected
153
+
154
+ - **Review all changes and preview builds**
155
+
156
+ - **Only merge after verification:**
157
+
158
+ ## Usage
159
+
160
+ To run the tools after installation:
161
+
162
+ ```sh
163
+ check-scannability --help
164
+ archive-unused-files --help
165
+ find-unused-attributes attributes.adoc
166
+ ```
167
+
168
+ Or run them directly from source:
169
+
170
+ ```sh
171
+ python3 check_scannability.py
172
+ python3 archive_unused_files.py
173
+ python3 find_unused_attributes.py attributes.adoc
174
+ ```
175
+
176
+ ### Directory/File Exclusion
177
+
178
+ All tools support excluding specific directories and files from scanning. You can use these options:
179
+
180
+ 1. **`--exclude-dir`** - Exclude specific directories (can be used multiple times):
181
+ ```sh
182
+ archive-unused-files --exclude-dir ./modules/temp --exclude-dir ./modules/old
183
+ ```
184
+
185
+ 2. **`--exclude-file`** - Exclude specific files (can be used multiple times):
186
+ ```sh
187
+ check-scannability --exclude-file ./README.adoc --exclude-file ./test.adoc
188
+ ```
189
+
190
+ 3. **`--exclude-list`** - Point to a text file containing exclusions:
191
+ ```sh
192
+ archive-unused-images --exclude-list .docutils-ignore
193
+ ```
194
+
195
+ The exclusion file format:
196
+ ```
197
+ # Comments are supported
198
+ ./modules/deprecated/
199
+ ./assemblies/archive/
200
+ ./images/temp/
201
+ specific-file.adoc
202
+ ```
203
+
204
+ **Note:** When you exclude a parent directory, all its subdirectories are automatically excluded. Symbolic links are never followed during scanning.
205
+
206
+ ## Troubleshooting
207
+
208
+ ### ModuleNotFoundError
209
+
210
+ If you see an error like `ModuleNotFoundError: No module named 'find_unused_attributes'`, this typically means:
211
+
212
+ 1. The package isn't installed. Run:
213
+ ```sh
214
+ pip install rolfedh-doc-utils
215
+ ```
216
+
217
+ 2. You're trying to run the script directly without installation. Either:
218
+ - Install the package first (see Installation section)
219
+ - Run the script using Python directly:
220
+ ```sh
221
+ python3 find_unused_attributes.py attributes.adoc
222
+ ```
223
+
224
+ ### Command not found
225
+
226
+ If the command isn't found after installation, ensure `$HOME/.local/bin` is in your PATH (see "Add to PATH" section above).
227
+
228
+ ## Development
229
+
230
+ ### Running Tests
231
+
232
+ The project includes a comprehensive test suite. To run tests:
233
+
234
+ ```sh
235
+ # Install development dependencies
236
+ pip install -r requirements-dev.txt
237
+
238
+ # Run all tests
239
+ python -m pytest tests/
240
+
241
+ # Run with verbose output
242
+ python -m pytest tests/ -v
243
+ ```
244
+
245
+ ### Contributing
246
+
247
+ Contributions are welcome! Please ensure:
248
+ - All tests pass before submitting a PR
249
+ - New features include appropriate tests
250
+ - Code follows PEP 8 style guidelines
251
+ - Documentation is updated as needed
252
+
253
+ See [CONTRIBUTING.md](https://github.com/rolfedh/doc-utils/blob/main/CONTRIBUTING.md) for more details.
254
+
255
+ ## License
256
+
257
+ This project is licensed under the terms of the [LICENSE](https://github.com/rolfedh/doc-utils/blob/main/LICENSE).
@@ -0,0 +1,225 @@
1
+ # doc-utils
2
+
3
+ A set of Python utilities and CLI tools to help technical writers maintain AsciiDoc documentation repositories.
4
+
5
+ > ⚠️ **IMPORTANT: Safety First**
6
+ >
7
+ > These tools can modify or delete files in your documentation repository. Always:
8
+ > - **Work in a git branch** - Never run these tools on the main/master branch
9
+ > - **Review all changes carefully** - Use `git diff` or a pull request to verify modifications
10
+ > - **Check your preview builds** - Ensure no documentation errors were introduced
11
+
12
+ ## Resources
13
+
14
+ - [PyPI: rolfedh-doc-utils](https://pypi.org/project/rolfedh-doc-utils/)
15
+ - [GitHub repository](https://github.com/rolfedh/doc-utils)
16
+
17
+ ## Installation
18
+
19
+ ### From PyPI
20
+
21
+ Install the package from PyPI:
22
+
23
+ ```sh
24
+ pip install rolfedh-doc-utils
25
+ ````
26
+
27
+ ### For Development
28
+
29
+ If you're developing or testing locally, install the package in editable mode:
30
+
31
+ ```sh
32
+ # Clone the repository
33
+ git clone https://github.com/rolfedh/doc-utils.git
34
+ cd doc-utils
35
+
36
+ # Install in editable mode
37
+ pip install -e .
38
+ ```
39
+
40
+ The following CLI tools are installed:
41
+
42
+ * `check-scannability`
43
+ * `archive-unused-files`
44
+ * `archive-unused-images`
45
+ * `find-unused-attributes`
46
+
47
+ These tools can be run from any directory.
48
+
49
+ ### Add to PATH (if needed)
50
+
51
+ By default, CLI tools install to:
52
+
53
+ ```sh
54
+ $HOME/.local/bin
55
+ ```
56
+
57
+ If this directory isn’t in your `PATH`, commands may not run. Append it to your shell configuration:
58
+
59
+ ```sh
60
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # or ~/.zshrc
61
+ ```
62
+
63
+ Then reload your shell:
64
+
65
+ ```sh
66
+ source ~/.bashrc # or ~/.zshrc
67
+ ```
68
+
69
+ ## CLI Tools Overview
70
+
71
+ ### `check-scannability`
72
+
73
+ Scans `.adoc` files in the current directory to report:
74
+
75
+ * Sentences that exceed a length limit (default: 22 words)
76
+ * Paragraphs with too many sentences (default: 3 sentences)
77
+ * Supports exclusion of files and directories
78
+
79
+ ➡️ See [`check_scannability.md`](https://github.com/rolfedh/doc-utils/blob/main/check_scannability.md) for details.
80
+
81
+ ---
82
+
83
+ ### `archive-unused-files`
84
+
85
+ Scans the `./modules` and `./assemblies` directories for `.adoc` files that are not referenced. Optionally archives and deletes them.
86
+
87
+ ➡️ See [`archive_unused_files.md`](https://github.com/rolfedh/doc-utils/blob/main/archive_unused_files.md).
88
+
89
+ ---
90
+
91
+ ### `archive-unused-images`
92
+
93
+ Finds unused image files (e.g., `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`) in the current directory and optionally archives and deletes them.
94
+
95
+ ➡️ See [`archive_unused_images.md`](https://github.com/rolfedh/doc-utils/blob/main/archive_unused_images.md).
96
+
97
+ ---
98
+
99
+ ### `find-unused-attributes`
100
+
101
+ Scans an attributes file (e.g., `attributes.adoc`) for unused attribute definitions across all `.adoc` files in the current directory.
102
+
103
+ ➡️ See [`find_unused_attributes.md`](https://github.com/rolfedh/doc-utils/blob/main/find_unused_attributes.md).
104
+
105
+ ## Best Practices for Safe Usage
106
+
107
+ ### Before Running Any Tool:
108
+
109
+ - **Create a feature branch:**
110
+ ```sh
111
+ git checkout -b doc-cleanup-$(date +%Y%m%d)
112
+ ```
113
+
114
+ - **Commit any pending changes:**
115
+ ```sh
116
+ git add -A && git commit -m "Save work before cleanup"
117
+ ```
118
+
119
+ - **Run tools in preview mode first:**
120
+ - For archive tools: Run without `--archive` to see what would be affected
121
+
122
+ - **Review all changes and preview builds**
123
+
124
+ - **Only merge after verification:**
125
+
126
+ ## Usage
127
+
128
+ To run the tools after installation:
129
+
130
+ ```sh
131
+ check-scannability --help
132
+ archive-unused-files --help
133
+ find-unused-attributes attributes.adoc
134
+ ```
135
+
136
+ Or run them directly from source:
137
+
138
+ ```sh
139
+ python3 check_scannability.py
140
+ python3 archive_unused_files.py
141
+ python3 find_unused_attributes.py attributes.adoc
142
+ ```
143
+
144
+ ### Directory/File Exclusion
145
+
146
+ All tools support excluding specific directories and files from scanning. You can use these options:
147
+
148
+ 1. **`--exclude-dir`** - Exclude specific directories (can be used multiple times):
149
+ ```sh
150
+ archive-unused-files --exclude-dir ./modules/temp --exclude-dir ./modules/old
151
+ ```
152
+
153
+ 2. **`--exclude-file`** - Exclude specific files (can be used multiple times):
154
+ ```sh
155
+ check-scannability --exclude-file ./README.adoc --exclude-file ./test.adoc
156
+ ```
157
+
158
+ 3. **`--exclude-list`** - Point to a text file containing exclusions:
159
+ ```sh
160
+ archive-unused-images --exclude-list .docutils-ignore
161
+ ```
162
+
163
+ The exclusion file format:
164
+ ```
165
+ # Comments are supported
166
+ ./modules/deprecated/
167
+ ./assemblies/archive/
168
+ ./images/temp/
169
+ specific-file.adoc
170
+ ```
171
+
172
+ **Note:** When you exclude a parent directory, all its subdirectories are automatically excluded. Symbolic links are never followed during scanning.
173
+
174
+ ## Troubleshooting
175
+
176
+ ### ModuleNotFoundError
177
+
178
+ If you see an error like `ModuleNotFoundError: No module named 'find_unused_attributes'`, this typically means:
179
+
180
+ 1. The package isn't installed. Run:
181
+ ```sh
182
+ pip install rolfedh-doc-utils
183
+ ```
184
+
185
+ 2. You're trying to run the script directly without installation. Either:
186
+ - Install the package first (see Installation section)
187
+ - Run the script using Python directly:
188
+ ```sh
189
+ python3 find_unused_attributes.py attributes.adoc
190
+ ```
191
+
192
+ ### Command not found
193
+
194
+ If the command isn't found after installation, ensure `$HOME/.local/bin` is in your PATH (see "Add to PATH" section above).
195
+
196
+ ## Development
197
+
198
+ ### Running Tests
199
+
200
+ The project includes a comprehensive test suite. To run tests:
201
+
202
+ ```sh
203
+ # Install development dependencies
204
+ pip install -r requirements-dev.txt
205
+
206
+ # Run all tests
207
+ python -m pytest tests/
208
+
209
+ # Run with verbose output
210
+ python -m pytest tests/ -v
211
+ ```
212
+
213
+ ### Contributing
214
+
215
+ Contributions are welcome! Please ensure:
216
+ - All tests pass before submitting a PR
217
+ - New features include appropriate tests
218
+ - Code follows PEP 8 style guidelines
219
+ - Documentation is updated as needed
220
+
221
+ See [CONTRIBUTING.md](https://github.com/rolfedh/doc-utils/blob/main/CONTRIBUTING.md) for more details.
222
+
223
+ ## License
224
+
225
+ This project is licensed under the terms of the [LICENSE](https://github.com/rolfedh/doc-utils/blob/main/LICENSE).
@@ -0,0 +1,35 @@
1
+ """
2
+ Archive Unused AsciiDoc Files
3
+
4
+ Scans './modules' and './assemblies' for AsciiDoc files not referenced by any other AsciiDoc file in the project. Optionally archives and deletes them.
5
+
6
+ For full documentation and usage examples, see archive_unused_files.md in this directory.
7
+ """
8
+
9
+ import argparse
10
+ from doc_utils.unused_adoc import find_unused_adoc
11
+ from doc_utils.file_utils import parse_exclude_list_file
12
+
13
+ def main():
14
+ parser = argparse.ArgumentParser(description='Archive unused AsciiDoc files.')
15
+ parser.add_argument('--archive', action='store_true', help='Move the files to a dated zip in the archive directory.')
16
+ parser.add_argument('--exclude-dir', action='append', default=[], help='Directory to exclude (can be used multiple times).')
17
+ parser.add_argument('--exclude-file', action='append', default=[], help='File to exclude (can be used multiple times).')
18
+ parser.add_argument('--exclude-list', type=str, help='Path to a file containing directories or files to exclude, one per line.')
19
+ args = parser.parse_args()
20
+
21
+ scan_dirs = ['./modules', './modules/rn', './assemblies']
22
+ archive_dir = './archive'
23
+
24
+ exclude_dirs = list(args.exclude_dir)
25
+ exclude_files = list(args.exclude_file)
26
+
27
+ if args.exclude_list:
28
+ list_dirs, list_files = parse_exclude_list_file(args.exclude_list)
29
+ exclude_dirs.extend(list_dirs)
30
+ exclude_files.extend(list_files)
31
+
32
+ find_unused_adoc(scan_dirs, archive_dir, args.archive, exclude_dirs, exclude_files)
33
+
34
+ if __name__ == '__main__':
35
+ main()
@@ -0,0 +1,35 @@
1
+ """
2
+ Archive Unused Image Files
3
+
4
+ Scans './modules' and './assemblies' for image files (e.g., .png, .jpg, .jpeg, .gif, .svg) not referenced by any AsciiDoc file in the project. Optionally archives and deletes them.
5
+
6
+ For full documentation and usage examples, see archive_unused_files.md in this directory.
7
+ """
8
+
9
+ import argparse
10
+ from doc_utils.unused_images import find_unused_images
11
+ from doc_utils.file_utils import parse_exclude_list_file
12
+
13
+ def main():
14
+ parser = argparse.ArgumentParser(description='Archive unused image files.')
15
+ parser.add_argument('--archive', action='store_true', help='Move the files to a dated zip in the archive directory.')
16
+ parser.add_argument('--exclude-dir', action='append', default=[], help='Directory to exclude (can be used multiple times).')
17
+ parser.add_argument('--exclude-file', action='append', default=[], help='File to exclude (can be used multiple times).')
18
+ parser.add_argument('--exclude-list', type=str, help='Path to a file containing directories or files to exclude, one per line.')
19
+ args = parser.parse_args()
20
+
21
+ scan_dirs = ['.']
22
+ archive_dir = './archive'
23
+
24
+ exclude_dirs = list(args.exclude_dir)
25
+ exclude_files = list(args.exclude_file)
26
+
27
+ if args.exclude_list:
28
+ list_dirs, list_files = parse_exclude_list_file(args.exclude_list)
29
+ exclude_dirs.extend(list_dirs)
30
+ exclude_files.extend(list_files)
31
+
32
+ find_unused_images(scan_dirs, archive_dir, args.archive, exclude_dirs, exclude_files)
33
+
34
+ if __name__ == '__main__':
35
+ main()
@@ -0,0 +1,109 @@
1
+ """
2
+ Scannability Checker for AsciiDoc Files
3
+
4
+ This script analyzes AsciiDoc (`.adoc`) files in the current directory to detect scannability issues that affect readability.
5
+
6
+ - Flags sentences that exceed 22 words (default, adjustable with -s)
7
+ - Flags paragraphs with more than 3 sentences (default, adjustable with -p)
8
+ - Excludes code blocks (delimited by ----, ...., or [source] blocks) from analysis
9
+
10
+ When using -o, the script prints the path to the report file; it does not attempt to open the file automatically.
11
+
12
+ For full documentation, see check_scannability.md in this directory.
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ import argparse
18
+ from datetime import datetime
19
+ from doc_utils.scannability import check_scannability
20
+ from doc_utils.file_utils import collect_files, parse_exclude_list_file
21
+
22
+ BASE_SENTENCE_WORD_LIMIT = 22
23
+ BASE_PARAGRAPH_SENTENCE_LIMIT = 3
24
+
25
+ def print_help():
26
+ print(__doc__)
27
+
28
+ def main():
29
+ # Manual check for -h or --help to display the full docstring
30
+ if '-h' in sys.argv or '--help' in sys.argv:
31
+ print_help()
32
+ sys.exit(0)
33
+
34
+ parser = argparse.ArgumentParser(add_help=False)
35
+ parser.add_argument('-s', '--max-sentence-length', type=int, default=0, help='Extra words allowed per sentence (default: 0, base: 22)')
36
+ parser.add_argument('-p', '--max-paragraph-sentences', type=int, default=0, help='Extra sentences allowed per paragraph (default: 0, base: 3)')
37
+ parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output (show all files, even those without issues)')
38
+ parser.add_argument('-o', '--output', action='store_true', help='Output the report to a timestamped txt file in your home directory')
39
+ parser.add_argument('--exclude-dir', action='append', default=[], help='Directory to exclude (can be used multiple times).')
40
+ parser.add_argument('--exclude-file', action='append', default=[], help='File to exclude (can be used multiple times).')
41
+ parser.add_argument('--exclude-list', type=str, help='Path to a file containing directories or files to exclude, one per line.')
42
+ # Do not add -h/--help to argparse, handled manually above
43
+ args = parser.parse_args()
44
+
45
+ exclude_dirs = list(args.exclude_dir)
46
+ exclude_files = list(args.exclude_file)
47
+
48
+ if args.exclude_list:
49
+ list_dirs, list_files = parse_exclude_list_file(args.exclude_list)
50
+ exclude_dirs.extend(list_dirs)
51
+ exclude_files.extend(list_files)
52
+ adoc_files = collect_files(['.'], {'.adoc'}, exclude_dirs, exclude_files)
53
+ sentence_word_limit = BASE_SENTENCE_WORD_LIMIT + args.max_sentence_length
54
+ paragraph_sentence_limit = BASE_PARAGRAPH_SENTENCE_LIMIT + args.max_paragraph_sentences
55
+ long_sentences, long_paragraphs = check_scannability(
56
+ adoc_files,
57
+ max_sentence_length=sentence_word_limit,
58
+ max_paragraph_sentences=paragraph_sentence_limit
59
+ )
60
+ # Build a report per file
61
+ report_lines = []
62
+ issues_by_file = {}
63
+ for file, line, sent in long_sentences:
64
+ issues_by_file.setdefault(file, []).append(f"Line {line}: Sentence exceeds {sentence_word_limit} words: {sent}")
65
+ for file, line, count in long_paragraphs:
66
+ issues_by_file.setdefault(file, []).append(f"Line {line}: Paragraph exceeds {paragraph_sentence_limit} sentences ({count} sentences)")
67
+ for adoc in adoc_files:
68
+ issues = issues_by_file.get(adoc, [])
69
+ if issues or args.verbose:
70
+ report_lines.append("") # Blank line above each filename
71
+ report_lines.append(f"{adoc}:")
72
+ if issues:
73
+ for issue in issues:
74
+ report_lines.append(" " + issue)
75
+ else:
76
+ report_lines.append(" No scannability issues found.")
77
+
78
+ output = "\n".join(report_lines)
79
+ if args.output:
80
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
81
+ home_dir = os.path.expanduser("~")
82
+ filename = os.path.join(home_dir, f"{timestamp}.txt")
83
+ now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
84
+ pwd = os.getcwd()
85
+ cmd = "python3 " + " ".join([sys.argv[0]] + sys.argv[1:])
86
+ metadata = [
87
+ "Scannability Report",
88
+ "",
89
+ f"Purpose: This report lists scannability issues in .adoc files in the current directory.",
90
+ f"Directory: {pwd}",
91
+ f"Date and Time: {now_str}",
92
+ f"Sentence length limit: {sentence_word_limit} words (22 plus -s/--max-sentence-length {args.max_sentence_length})",
93
+ f"Paragraph sentence limit: {paragraph_sentence_limit} sentences (3 plus -p/--max-paragraph-sentences {args.max_paragraph_sentences})",
94
+ "See check_scannability.md for usage instructions and examples.",
95
+ f"Command: {cmd}",
96
+ "",
97
+ "------------------------------------------------------------",
98
+ "",
99
+ ]
100
+ with open(filename, "w", encoding="utf-8") as f:
101
+ f.write("\n".join(metadata))
102
+ f.write(output.lstrip() + "\n")
103
+ print(f"Report written to: {filename}")
104
+ else:
105
+ if output:
106
+ print(output.lstrip())
107
+
108
+ if __name__ == "__main__":
109
+ main()