rolfedh-doc-utils 0.1.26__tar.gz → 0.1.28__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 (62) hide show
  1. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/PKG-INFO +1 -1
  2. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/converter_bullets.py +2 -2
  3. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/converter_deflist.py +2 -2
  4. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/detector.py +64 -7
  5. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/table_parser.py +159 -4
  6. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/convert_callouts_to_deflist.py +5 -4
  7. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/pyproject.toml +1 -1
  8. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/PKG-INFO +1 -1
  9. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/LICENSE +0 -0
  10. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/README.md +0 -0
  11. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/archive_unused_files.py +0 -0
  12. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/archive_unused_images.py +0 -0
  13. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/__init__.py +0 -0
  14. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/callout_lib/converter_comments.py +0 -0
  15. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/check_scannability.py +0 -0
  16. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/convert_callouts_interactive.py +0 -0
  17. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/__init__.py +0 -0
  18. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/extract_link_attributes.py +0 -0
  19. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/file_utils.py +0 -0
  20. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/format_asciidoc_spacing.py +0 -0
  21. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/replace_link_attributes.py +0 -0
  22. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/scannability.py +0 -0
  23. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/spinner.py +0 -0
  24. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/topic_map_parser.py +0 -0
  25. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/unused_adoc.py +0 -0
  26. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/unused_attributes.py +0 -0
  27. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/unused_images.py +0 -0
  28. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/validate_links.py +0 -0
  29. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/version.py +0 -0
  30. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils/version_check.py +0 -0
  31. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/doc_utils_cli.py +0 -0
  32. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/extract_link_attributes.py +0 -0
  33. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/find_unused_attributes.py +0 -0
  34. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/format_asciidoc_spacing.py +0 -0
  35. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/replace_link_attributes.py +0 -0
  36. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/SOURCES.txt +0 -0
  37. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/dependency_links.txt +0 -0
  38. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/entry_points.txt +0 -0
  39. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/requires.txt +0 -0
  40. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/rolfedh_doc_utils.egg-info/top_level.txt +0 -0
  41. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/setup.cfg +0 -0
  42. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/setup.py +0 -0
  43. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_archive_unused_files.py +0 -0
  44. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_archive_unused_images.py +0 -0
  45. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_auto_discovery.py +0 -0
  46. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_check_scannability.py +0 -0
  47. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_cli_entry_points.py +0 -0
  48. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_extract_link_attributes.py +0 -0
  49. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_file_utils.py +0 -0
  50. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_fixture_archive_unused_files.py +0 -0
  51. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_fixture_archive_unused_images.py +0 -0
  52. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_fixture_check_scannability.py +0 -0
  53. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_parse_exclude_list.py +0 -0
  54. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_replace_link_attributes.py +0 -0
  55. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_symlink_handling.py +0 -0
  56. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_table_callout_conversion.py +0 -0
  57. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_table_parser.py +0 -0
  58. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_topic_map_parser.py +0 -0
  59. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_unused_attributes.py +0 -0
  60. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_validate_links.py +0 -0
  61. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/tests/test_version_check.py +0 -0
  62. {rolfedh_doc_utils-0.1.26 → rolfedh_doc_utils-0.1.28}/validate_links.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rolfedh-doc-utils
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: CLI tools for AsciiDoc documentation projects
5
5
  Author: Rolfe Dlugy-Hegwer
6
6
  License: MIT License
@@ -59,8 +59,8 @@ class BulletListConverter:
59
59
  user_value = f'{user_value}>'
60
60
  term = f'`{user_value}`'
61
61
  else:
62
- # This is a code line - use it as-is in backticks
63
- term = f'`{code_line}`'
62
+ # This is a code line - strip whitespace before wrapping in backticks
63
+ term = f'`{code_line.strip()}`'
64
64
 
65
65
  # Collect all explanations for this group
66
66
  all_explanation_lines = []
@@ -54,8 +54,8 @@ class DefListConverter:
54
54
  user_value = f'{user_value}>'
55
55
  term = f'`{user_value}`'
56
56
  else:
57
- # This is a code line - use it as-is in backticks
58
- term = f'`{code_line}`'
57
+ # This is a code line - strip whitespace before wrapping in backticks
58
+ term = f'`{code_line.strip()}`'
59
59
 
60
60
  # Add blank line before each term
61
61
  lines.append('')
@@ -45,6 +45,11 @@ class CalloutDetector:
45
45
  # Pattern for callout number in code block (can appear multiple times per line)
46
46
  CALLOUT_IN_CODE = re.compile(r'<(\d+)>')
47
47
 
48
+ # Pattern for callout with optional preceding comment syntax
49
+ # Matches common comment styles: //, #, --, ;, followed by optional whitespace and <number>
50
+ # The comment syntax must be preceded by whitespace to avoid matching code operators
51
+ CALLOUT_WITH_COMMENT = re.compile(r'\s*(?://|#|--|;)\s*<\d+>|\s*<\d+>')
52
+
48
53
  # Pattern for callout explanation line: <1> Explanation text
49
54
  CALLOUT_EXPLANATION = re.compile(r'^<(\d+)>\s+(.+)$')
50
55
 
@@ -130,8 +135,9 @@ class CalloutDetector:
130
135
  # Look for all callout numbers on this line
131
136
  callout_matches = list(self.CALLOUT_IN_CODE.finditer(line))
132
137
  if callout_matches:
133
- # Remove all callouts from the line to get the actual code
134
- line_without_callouts = self.CALLOUT_IN_CODE.sub('', line).strip()
138
+ # Remove callouts AND preceding comment syntax from the line
139
+ # Use CALLOUT_WITH_COMMENT to remove both comment syntax and callout
140
+ line_without_callouts = self.CALLOUT_WITH_COMMENT.sub('', line).rstrip()
135
141
 
136
142
  # Find all angle-bracket enclosed values
137
143
  user_values = self.USER_VALUE_PATTERN.findall(line_without_callouts)
@@ -157,13 +163,18 @@ class CalloutDetector:
157
163
  def extract_callout_explanations(self, lines: List[str], start_line: int) -> Tuple[Dict[int, Callout], int]:
158
164
  """
159
165
  Extract callout explanations following a code block.
160
- Supports both list-format (<1> text) and table-format explanations.
166
+ Supports list-format (<1> text), 2-column table, and 3-column table formats.
161
167
  Returns dict of callouts and the line number where explanations end.
162
168
  """
163
169
  # First, try to find a table-format callout explanation
164
170
  table = self.table_parser.find_callout_table_after_code_block(lines, start_line)
165
171
  if table:
166
- return self._extract_from_table(table)
172
+ # Check if it's a 3-column table (Item | Value | Description)
173
+ if self.table_parser.is_3column_callout_table(table):
174
+ return self._extract_from_3column_table(table)
175
+ # Check if it's a 2-column table (<callout> | explanation)
176
+ elif self.table_parser.is_callout_table(table):
177
+ return self._extract_from_table(table)
167
178
 
168
179
  # Fall back to list-format extraction
169
180
  return self._extract_from_list(lines, start_line)
@@ -196,6 +207,49 @@ class CalloutDetector:
196
207
 
197
208
  return explanations, table.end_line
198
209
 
210
+ def _extract_from_3column_table(self, table) -> Tuple[Dict[int, Callout], int]:
211
+ """
212
+ Extract callout explanations from a 3-column table format.
213
+ Format: Item (number) | Value | Description
214
+ """
215
+ explanations = {}
216
+ table_data = self.table_parser.extract_3column_callout_explanations(table)
217
+
218
+ for callout_num, (value_lines, description_lines, conditionals) in table_data.items():
219
+ # Combine value and description into explanation lines
220
+ # Strategy: Include value as context, then description
221
+ all_lines = []
222
+
223
+ # Add value lines with context
224
+ if value_lines:
225
+ # Format: "`value`:"
226
+ value_text = value_lines[0] if value_lines else ""
227
+ # If value is code-like (contains backticks or special chars), keep it formatted
228
+ if value_text:
229
+ all_lines.append(f"{value_text}:")
230
+
231
+ # Add additional value lines if multi-line
232
+ for line in value_lines[1:]:
233
+ all_lines.append(line)
234
+
235
+ # Add description lines
236
+ all_lines.extend(description_lines)
237
+
238
+ # Add conditionals as separate lines (they'll be preserved in output)
239
+ all_lines.extend(conditionals)
240
+
241
+ # Check if marked as optional
242
+ is_optional = False
243
+ if all_lines and (all_lines[0].lower().startswith('optional.') or
244
+ all_lines[0].lower().startswith('optional:') or
245
+ 'optional' in all_lines[0].lower()[:50]): # Check first 50 chars
246
+ is_optional = True
247
+ # Don't remove "optional" text - it's part of the description
248
+
249
+ explanations[callout_num] = Callout(callout_num, all_lines, is_optional)
250
+
251
+ return explanations, table.end_line
252
+
199
253
  def _extract_from_list(self, lines: List[str], start_line: int) -> Tuple[Dict[int, Callout], int]:
200
254
  """Extract callout explanations from list format (<1> text)."""
201
255
  explanations = {}
@@ -242,11 +296,14 @@ class CalloutDetector:
242
296
  return explanations, i - 1
243
297
 
244
298
  def remove_callouts_from_code(self, content: List[str]) -> List[str]:
245
- """Remove callout numbers from code block content (handles multiple callouts per line)."""
299
+ """
300
+ Remove callout numbers and preceding comment syntax from code block content.
301
+ Handles multiple callouts per line and various comment styles (//, #, --, ;).
302
+ """
246
303
  cleaned = []
247
304
  for line in content:
248
- # Remove all callout numbers and trailing whitespace
249
- cleaned.append(self.CALLOUT_IN_CODE.sub('', line).rstrip())
305
+ # Remove all callout numbers with their preceding comment syntax
306
+ cleaned.append(self.CALLOUT_WITH_COMMENT.sub('', line).rstrip())
250
307
  return cleaned
251
308
 
252
309
  def validate_callouts(self, callout_groups: List[CalloutGroup], explanations: Dict[int, Callout]) -> Tuple[bool, set, set]:
@@ -188,9 +188,34 @@ class TableParser:
188
188
 
189
189
  # Extract cell content from this line (text after |)
190
190
  cell_content = line[1:].strip() # Remove leading |
191
- if cell_content:
192
- current_cell_lines.append(cell_content)
193
- # If empty, just start a new cell with no content yet
191
+
192
+ # Check if there are multiple cells on the same line (e.g., |Cell1 |Cell2 |Cell3)
193
+ if '|' in cell_content:
194
+ # Split by | to get multiple cells
195
+ parts = cell_content.split('|')
196
+ for part in parts:
197
+ part = part.strip()
198
+ if part: # Skip empty parts
199
+ current_row_cells.append(TableCell(
200
+ content=[part],
201
+ conditionals=[]
202
+ ))
203
+
204
+ # Multi-cell line completes a row - finalize it
205
+ if current_row_cells:
206
+ rows.append(TableRow(
207
+ cells=current_row_cells.copy(),
208
+ conditionals_before=conditionals_before_row.copy(),
209
+ conditionals_after=conditionals_after_row.copy()
210
+ ))
211
+ current_row_cells = []
212
+ conditionals_before_row = []
213
+ conditionals_after_row = []
214
+ else:
215
+ # Single cell on this line
216
+ if cell_content:
217
+ current_cell_lines.append(cell_content)
218
+ # If empty, just start a new cell with no content yet
194
219
 
195
220
  i += 1
196
221
  continue
@@ -229,6 +254,65 @@ class TableParser:
229
254
 
230
255
  return True
231
256
 
257
+ def _has_header_row(self, table: AsciiDocTable) -> bool:
258
+ """
259
+ Check if table has a header row.
260
+ Common header patterns: "Item", "Value", "Description", "Column", etc.
261
+ """
262
+ if not table.rows:
263
+ return False
264
+
265
+ first_row = table.rows[0]
266
+ if not first_row.cells:
267
+ return False
268
+
269
+ # Collect text from all cells in first row
270
+ header_text = ' '.join(
271
+ cell.content[0] if cell.content else ''
272
+ for cell in first_row.cells
273
+ ).lower()
274
+
275
+ # Check for common header keywords
276
+ header_keywords = ['item', 'description', 'value', 'column', 'parameter', 'field', 'name']
277
+ return any(keyword in header_text for keyword in header_keywords)
278
+
279
+ def is_3column_callout_table(self, table: AsciiDocTable) -> bool:
280
+ """
281
+ Determine if a table is a 3-column callout explanation table.
282
+ Format: Item (number) | Value | Description
283
+
284
+ This format is used in some documentation (e.g., Debezium) where:
285
+ - Column 1: Item number (1, 2, 3...) corresponding to callout numbers
286
+ - Column 2: The value/code being explained
287
+ - Column 3: Description/explanation text
288
+ """
289
+ if not table.rows:
290
+ return False
291
+
292
+ # Determine if there's a header row
293
+ has_header = self._has_header_row(table)
294
+ data_rows = table.rows[1:] if has_header else table.rows
295
+
296
+ if not data_rows:
297
+ return False
298
+
299
+ # Check if all data rows have exactly 3 cells
300
+ if not all(len(row.cells) == 3 for row in data_rows):
301
+ return False
302
+
303
+ # Check if first cell of each data row contains a plain number (1, 2, 3...)
304
+ for row in data_rows:
305
+ first_cell = row.cells[0]
306
+ if not first_cell.content:
307
+ return False
308
+
309
+ # First line of first cell should be a number
310
+ first_line = first_cell.content[0].strip()
311
+ if not first_line.isdigit():
312
+ return False
313
+
314
+ return True
315
+
232
316
  def extract_callout_explanations_from_table(self, table: AsciiDocTable) -> Dict[int, Tuple[List[str], List[str]]]:
233
317
  """
234
318
  Extract callout explanations from a table.
@@ -276,6 +360,77 @@ class TableParser:
276
360
 
277
361
  return explanations
278
362
 
363
+ def extract_3column_callout_explanations(self, table: AsciiDocTable) -> Dict[int, Tuple[List[str], List[str], List[str]]]:
364
+ """
365
+ Extract callout explanations from a 3-column table.
366
+ Returns dict mapping callout number to tuple of (value_lines, description_lines, conditionals).
367
+
368
+ Format: Item | Value | Description
369
+ - Item: Number (1, 2, 3...) corresponding to callout number
370
+ - Value: The code/value being explained
371
+ - Description: Explanation text
372
+
373
+ The conditionals list includes any ifdef/ifndef/endif statements that should
374
+ be preserved when converting the table to other formats.
375
+ """
376
+ explanations = {}
377
+
378
+ # Determine if there's a header row and skip it
379
+ has_header = self._has_header_row(table)
380
+ data_rows = table.rows[1:] if has_header else table.rows
381
+
382
+ for row in data_rows:
383
+ if len(row.cells) != 3:
384
+ continue
385
+
386
+ item_cell = row.cells[0]
387
+ value_cell = row.cells[1]
388
+ desc_cell = row.cells[2]
389
+
390
+ # Extract item number (maps to callout number)
391
+ if not item_cell.content:
392
+ continue
393
+
394
+ item_num_str = item_cell.content[0].strip()
395
+ if not item_num_str.isdigit():
396
+ continue
397
+
398
+ callout_num = int(item_num_str)
399
+
400
+ # Collect value lines (column 2)
401
+ value_lines = []
402
+ for line in value_cell.content:
403
+ # Skip conditional directives in value (preserve them separately)
404
+ if not (self.IFDEF_PATTERN.match(line) or self.ENDIF_PATTERN.match(line)):
405
+ value_lines.append(line)
406
+
407
+ # Collect description lines (column 3)
408
+ description_lines = []
409
+ for line in desc_cell.content:
410
+ # Skip conditional directives in description (preserve them separately)
411
+ if not (self.IFDEF_PATTERN.match(line) or self.ENDIF_PATTERN.match(line)):
412
+ description_lines.append(line)
413
+
414
+ # Collect all conditionals for this row
415
+ all_conditionals = []
416
+ all_conditionals.extend(row.conditionals_before)
417
+
418
+ # Extract conditionals from value cell
419
+ for line in value_cell.content:
420
+ if self.IFDEF_PATTERN.match(line) or self.ENDIF_PATTERN.match(line):
421
+ all_conditionals.append(line)
422
+
423
+ # Extract conditionals from description cell
424
+ for line in desc_cell.content:
425
+ if self.IFDEF_PATTERN.match(line) or self.ENDIF_PATTERN.match(line):
426
+ all_conditionals.append(line)
427
+
428
+ all_conditionals.extend(row.conditionals_after)
429
+
430
+ explanations[callout_num] = (value_lines, description_lines, all_conditionals)
431
+
432
+ return explanations
433
+
279
434
  def find_callout_table_after_code_block(self, lines: List[str], code_block_end: int) -> Optional[AsciiDocTable]:
280
435
  """
281
436
  Find a callout explanation table that appears after a code block.
@@ -316,7 +471,7 @@ class TableParser:
316
471
  start_line = j - 1
317
472
 
318
473
  table = self._parse_table(lines, start_line, j)
319
- if table and self.is_callout_table(table):
474
+ if table and (self.is_callout_table(table) or self.is_3column_callout_table(table)):
320
475
  return table
321
476
 
322
477
  # If we found a table but it's not a callout table, stop searching
@@ -166,14 +166,15 @@ class CalloutConverter:
166
166
  content_start = block.start_line + 1 # After ---- only
167
167
  content_end = block.end_line
168
168
 
169
- # For comments format (without fallback), we keep the explanations section
170
- # For deflist/bullets format, we remove old explanations and add new list
169
+ # For comments format (without fallback), remove explanations but don't add new list
170
+ # For deflist/bullets format, remove old explanations and add new list
171
171
  if self.output_format == 'comments' and not use_deflist_fallback:
172
- # Keep everything as-is, just replace code content
172
+ # Remove old callout explanations (list or table format)
173
173
  new_section = (
174
174
  new_lines[:content_start] +
175
175
  converted_content +
176
- new_lines[content_end:]
176
+ [new_lines[content_end]] + # Keep closing delimiter
177
+ new_lines[explanation_end + 1:] # Skip explanations/table, keep rest
177
178
  )
178
179
  else:
179
180
  # Remove old callout explanations and add new list
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rolfedh-doc-utils"
7
- version = "0.1.26"
7
+ version = "0.1.28"
8
8
  description = "CLI tools for AsciiDoc documentation projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rolfedh-doc-utils
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: CLI tools for AsciiDoc documentation projects
5
5
  Author: Rolfe Dlugy-Hegwer
6
6
  License: MIT License