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.
- {rolfedh_doc_utils-0.1.25/rolfedh_doc_utils.egg-info → rolfedh_doc_utils-0.1.27}/PKG-INFO +1 -1
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/detector.py +93 -0
- rolfedh_doc_utils-0.1.27/callout_lib/table_parser.py +581 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/convert_callouts_to_deflist.py +5 -4
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/pyproject.toml +1 -1
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27/rolfedh_doc_utils.egg-info}/PKG-INFO +1 -1
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/SOURCES.txt +3 -0
- rolfedh_doc_utils-0.1.27/tests/test_table_callout_conversion.py +261 -0
- rolfedh_doc_utils-0.1.27/tests/test_table_parser.py +330 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/LICENSE +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/README.md +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/__init__.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_bullets.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_comments.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/callout_lib/converter_deflist.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/convert_callouts_interactive.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/__init__.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/extract_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/file_utils.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/format_asciidoc_spacing.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/replace_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/scannability.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/spinner.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/topic_map_parser.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_adoc.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/validate_links.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/version.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils/version_check.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/doc_utils_cli.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/extract_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/find_unused_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/format_asciidoc_spacing.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/replace_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/dependency_links.txt +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/entry_points.txt +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/requires.txt +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/rolfedh_doc_utils.egg-info/top_level.txt +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/setup.cfg +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/setup.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_auto_discovery.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_cli_entry_points.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_extract_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_file_utils.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_archive_unused_files.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_archive_unused_images.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_fixture_check_scannability.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_parse_exclude_list.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_replace_link_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_symlink_handling.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_topic_map_parser.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_unused_attributes.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_validate_links.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/tests/test_version_check.py +0 -0
- {rolfedh_doc_utils-0.1.25 → rolfedh_doc_utils-0.1.27}/validate_links.py +0 -0
|
@@ -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
|
|