rolfedh-doc-utils 0.1.25__tar.gz → 0.1.27__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.25/rolfedh_doc_utils.egg-info → rolfedh_doc_utils-0.1.27}/PKG-INFO +1 -1
  2. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/detector.py +93 -0
  3. rolfedh_doc_utils-0.1.27/callout_lib/table_parser.py +581 -0
  4. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/convert_callouts_to_deflist.py +5 -4
  5. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/pyproject.toml +1 -1
  6. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27/rolfedh_doc_utils.egg-info}/PKG-INFO +1 -1
  7. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/SOURCES.txt +3 -0
  8. rolfedh_doc_utils-0.1.27/tests/test_table_callout_conversion.py +261 -0
  9. rolfedh_doc_utils-0.1.27/tests/test_table_parser.py +330 -0
  10. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/LICENSE +0 -0
  11. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/README.md +0 -0
  12. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/archive_unused_files.py +0 -0
  13. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/archive_unused_images.py +0 -0
  14. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/__init__.py +0 -0
  15. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_bullets.py +0 -0
  16. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_comments.py +0 -0
  17. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_deflist.py +0 -0
  18. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/check_scannability.py +0 -0
  19. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/convert_callouts_interactive.py +0 -0
  20. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/__init__.py +0 -0
  21. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/extract_link_attributes.py +0 -0
  22. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/file_utils.py +0 -0
  23. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/format_asciidoc_spacing.py +0 -0
  24. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/replace_link_attributes.py +0 -0
  25. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/scannability.py +0 -0
  26. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/spinner.py +0 -0
  27. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/topic_map_parser.py +0 -0
  28. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_adoc.py +0 -0
  29. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_attributes.py +0 -0
  30. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_images.py +0 -0
  31. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/validate_links.py +0 -0
  32. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/version.py +0 -0
  33. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/version_check.py +0 -0
  34. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils_cli.py +0 -0
  35. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/extract_link_attributes.py +0 -0
  36. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/find_unused_attributes.py +0 -0
  37. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/format_asciidoc_spacing.py +0 -0
  38. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/replace_link_attributes.py +0 -0
  39. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/dependency_links.txt +0 -0
  40. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/entry_points.txt +0 -0
  41. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/requires.txt +0 -0
  42. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/top_level.txt +0 -0
  43. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/setup.cfg +0 -0
  44. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/setup.py +0 -0
  45. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_archive_unused_files.py +0 -0
  46. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_archive_unused_images.py +0 -0
  47. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_auto_discovery.py +0 -0
  48. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_check_scannability.py +0 -0
  49. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_cli_entry_points.py +0 -0
  50. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_extract_link_attributes.py +0 -0
  51. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_file_utils.py +0 -0
  52. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_archive_unused_files.py +0 -0
  53. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_archive_unused_images.py +0 -0
  54. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_check_scannability.py +0 -0
  55. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_parse_exclude_list.py +0 -0
  56. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_replace_link_attributes.py +0 -0
  57. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_symlink_handling.py +0 -0
  58. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_topic_map_parser.py +0 -0
  59. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_unused_attributes.py +0 -0
  60. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_validate_links.py +0 -0
  61. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_version_check.py +0 -0
  62. {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/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.25
3
+ Version: 0.1.27
4
4
  Summary: CLI tools for AsciiDoc documentation projects
5
5
  Author: Rolfe Dlugy-Hegwer
6
6
  License: MIT License
@@ -2,11 +2,13 @@
2
2
  Callout Detection Module
3
3
 
4
4
  Detects code blocks with callouts and extracts callout information from AsciiDoc files.
5
+ Supports both list-format and table-format callout explanations.
5
6
  """
6
7
 
7
8
  import re
8
9
  from typing import List, Dict, Tuple, Optional
9
10
  from dataclasses import dataclass
11
+ from .table_parser import TableParser
10
12
 
11
13
 
12
14
  @dataclass
@@ -50,6 +52,10 @@ class CalloutDetector:
50
52
  # Excludes heredoc syntax (<<) and comparison operators
51
53
  USER_VALUE_PATTERN = re.compile(r'(?<!<)<([a-zA-Z][^>]*)>')
52
54
 
55
+ def __init__(self):
56
+ """Initialize detector with table parser."""
57
+ self.table_parser = TableParser()
58
+
53
59
  def find_code_blocks(self, lines: List[str]) -> List[CodeBlock]:
54
60
  """Find all code blocks in the document."""
55
61
  blocks = []
@@ -151,8 +157,95 @@ class CalloutDetector:
151
157
  def extract_callout_explanations(self, lines: List[str], start_line: int) -> Tuple[Dict[int, Callout], int]:
152
158
  """
153
159
  Extract callout explanations following a code block.
160
+ Supports list-format (<1> text), 2-column table, and 3-column table formats.
154
161
  Returns dict of callouts and the line number where explanations end.
155
162
  """
163
+ # First, try to find a table-format callout explanation
164
+ table = self.table_parser.find_callout_table_after_code_block(lines, start_line)
165
+ if table:
166
+ # Check if it's a 3-column table (Item | Value | Description)
167
+ if self.table_parser.is_3column_callout_table(table):
168
+ return self._extract_from_3column_table(table)
169
+ # Check if it's a 2-column table (<callout> | explanation)
170
+ elif self.table_parser.is_callout_table(table):
171
+ return self._extract_from_table(table)
172
+
173
+ # Fall back to list-format extraction
174
+ return self._extract_from_list(lines, start_line)
175
+
176
+ def _extract_from_table(self, table) -> Tuple[Dict[int, Callout], int]:
177
+ """Extract callout explanations from a table format."""
178
+ explanations = {}
179
+ table_data = self.table_parser.extract_callout_explanations_from_table(table)
180
+
181
+ for callout_num, (explanation_lines, conditionals) in table_data.items():
182
+ # Combine explanation lines with conditionals preserved
183
+ all_lines = []
184
+ for line in explanation_lines:
185
+ all_lines.append(line)
186
+
187
+ # Add conditionals as separate lines (they'll be preserved in output)
188
+ all_lines.extend(conditionals)
189
+
190
+ # Check if marked as optional
191
+ is_optional = False
192
+ if all_lines and (all_lines[0].lower().startswith('optional.') or
193
+ all_lines[0].lower().startswith('optional:')):
194
+ is_optional = True
195
+ all_lines[0] = all_lines[0][9:].strip()
196
+ elif all_lines and ('(Optional)' in all_lines[0] or '(optional)' in all_lines[0]):
197
+ is_optional = True
198
+ all_lines[0] = re.sub(r'\s*\(optional\)\s*', ' ', all_lines[0], flags=re.IGNORECASE).strip()
199
+
200
+ explanations[callout_num] = Callout(callout_num, all_lines, is_optional)
201
+
202
+ return explanations, table.end_line
203
+
204
+ def _extract_from_3column_table(self, table) -> Tuple[Dict[int, Callout], int]:
205
+ """
206
+ Extract callout explanations from a 3-column table format.
207
+ Format: Item (number) | Value | Description
208
+ """
209
+ explanations = {}
210
+ table_data = self.table_parser.extract_3column_callout_explanations(table)
211
+
212
+ for callout_num, (value_lines, description_lines, conditionals) in table_data.items():
213
+ # Combine value and description into explanation lines
214
+ # Strategy: Include value as context, then description
215
+ all_lines = []
216
+
217
+ # Add value lines with context
218
+ if value_lines:
219
+ # Format: "Refers to `value`. Description..."
220
+ value_text = value_lines[0] if value_lines else ""
221
+ # If value is code-like (contains backticks or special chars), keep it formatted
222
+ if value_text:
223
+ all_lines.append(f"Refers to {value_text}.")
224
+
225
+ # Add additional value lines if multi-line
226
+ for line in value_lines[1:]:
227
+ all_lines.append(line)
228
+
229
+ # Add description lines
230
+ all_lines.extend(description_lines)
231
+
232
+ # Add conditionals as separate lines (they'll be preserved in output)
233
+ all_lines.extend(conditionals)
234
+
235
+ # Check if marked as optional
236
+ is_optional = False
237
+ if all_lines and (all_lines[0].lower().startswith('optional.') or
238
+ all_lines[0].lower().startswith('optional:') or
239
+ 'optional' in all_lines[0].lower()[:50]): # Check first 50 chars
240
+ is_optional = True
241
+ # Don't remove "optional" text - it's part of the description
242
+
243
+ explanations[callout_num] = Callout(callout_num, all_lines, is_optional)
244
+
245
+ return explanations, table.end_line
246
+
247
+ def _extract_from_list(self, lines: List[str], start_line: int) -> Tuple[Dict[int, Callout], int]:
248
+ """Extract callout explanations from list format (<1> text)."""
156
249
  explanations = {}
157
250
  i = start_line + 1 # Start after the closing delimiter
158
251