v1.0
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# agent/markdown_utils.py
|
||||
import re
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
|
||||
def extract_section(md_text: str, section_title: str) -> str:
|
||||
"""Extract content of a ## or ### section from markdown text.
|
||||
Stops at the next heading of equal or higher level (fewer or equal #'s).
|
||||
For ## sections, includes ### sub-sections.
|
||||
"""
|
||||
heading_re = rf'^(#{{2,3}})\s+{re.escape(section_title)}[^\S\n]*$'
|
||||
h_match = re.search(heading_re, md_text, re.MULTILINE)
|
||||
if not h_match:
|
||||
return ''
|
||||
|
||||
level = len(h_match.group(1))
|
||||
start = h_match.end()
|
||||
|
||||
next_re = rf'^#{{1,{level}}}\s'
|
||||
n_match = re.search(next_re, md_text[start:], re.MULTILINE)
|
||||
end = start + n_match.start() if n_match else len(md_text)
|
||||
|
||||
return md_text[start:end]
|
||||
|
||||
|
||||
def parse_table_rows(text: str) -> List[Dict[str, str]]:
|
||||
"""Parse a markdown table from text, return list of row dicts.
|
||||
Handles tables with exactly one header row and one separator row.
|
||||
"""
|
||||
lines = []
|
||||
for line in text.split('\n'):
|
||||
stripped = line.strip()
|
||||
if stripped.startswith('|') and stripped.endswith('|'):
|
||||
if re.match(r'^\|[\s\-:]+\|', stripped):
|
||||
continue
|
||||
lines.append(stripped)
|
||||
|
||||
if len(lines) < 1:
|
||||
return []
|
||||
|
||||
headers = [cell.strip() for cell in lines[0].split('|')[1:-1]]
|
||||
rows = []
|
||||
for line in lines[1:]:
|
||||
cells = [cell.strip() for cell in line.split('|')[1:-1]]
|
||||
if len(cells) == len(headers):
|
||||
rows.append(dict(zip(headers, cells)))
|
||||
return rows
|
||||
|
||||
|
||||
def parse_table_from_section(md_text: str, section_title: str) -> List[Dict[str, str]]:
|
||||
"""Find a ### section and parse its first table."""
|
||||
section_text = extract_section(md_text, section_title)
|
||||
if not section_text:
|
||||
return []
|
||||
return parse_table_rows(section_text)
|
||||
|
||||
|
||||
def find_row_by_key(rows: List[Dict[str, str]], key_col: str, key_value: str) -> Optional[Dict[str, str]]:
|
||||
"""Find a table row where a specific column matches the key value."""
|
||||
for row in rows:
|
||||
if row.get(key_col, '').strip() == key_value:
|
||||
return row
|
||||
return None
|
||||
Reference in New Issue
Block a user