Files
Aislo/resources/tester/scratch/enrich_tables.py
T

118 lines
4.1 KiB
Python

import re
import sys
import json
from pathlib import Path
sys.stdout.reconfigure(encoding='utf-8')
md_path = Path("resources/knowledge/original/행정규칙/임도 품셈 적용기준 (현 산림사업 표준품셈)/첨부/(산림청고시 제2025-82호) 산림사업 표준품셈.md")
with open(md_path, "r", encoding="utf-8") as f:
lines = f.readlines()
# 1. Parse Chapters and Sections
# Track current chapter, section, and text before tables
chapters = []
for idx, line in enumerate(lines):
m = re.match(r'^(#{1,3})\s*(제\s*\d+\s*장(?:\s+[^\,\n]+)?)$', line.strip())
if m and not any(k in line for k in ['참조', '적용기준,', '토질,']):
chapters.append((idx + 1, m.group(2).strip()))
def get_chapter(line_no):
cur_ch = "제0장 머리말"
for lno, ch in chapters:
if line_no >= lno:
cur_ch = ch
else:
break
return cur_ch
# 2. Extract tables and their contexts
tables = []
current_table = []
start_line = -1
for idx, line in enumerate(lines):
line_str = line.strip()
if line_str.startswith('|') and line_str.endswith('|'):
if not current_table:
start_line = idx + 1
current_table.append((idx + 1, line))
else:
if current_table:
has_sep = any(re.match(r'^\|(?:\s*:?-+:?\s*\|)+$', l.strip()) for _, l in current_table)
if has_sep:
tables.append({
'start_line': start_line,
'end_line': current_table[-1][0],
'lines': [l for _, l in current_table]
})
current_table = []
if current_table:
has_sep = any(re.match(r'^\|(?:\s*:?-+:?\s*\|)+$', l.strip()) for _, l in current_table)
if has_sep:
tables.append({
'start_line': start_line,
'end_line': current_table[-1][0],
'lines': [l for _, l in current_table]
})
print(f"Extracted {len(tables)} tables.")
# Enrich each table with pre-context (up to 15 lines before) and post-context ([주] up to next table/heading)
for i, t in enumerate(tables):
t_id = f"F{i+1:04d}"
t['table_id'] = t_id
t['chapter'] = get_chapter(t['start_line'])
# Pre-context: lines before start_line
pre_start = max(0, t['start_line'] - 15)
pre_lines = [lines[j].strip() for j in range(pre_start, t['start_line'] - 1) if lines[j].strip()]
t['pre_context'] = pre_lines
# Find section title from pre-lines (looking backwards)
section = "미식별"
for pl in reversed(pre_lines):
if re.match(r'^(?:#{1,4}\s*)?(?:\d+[-\.]\d+|\d+\.)', pl):
section = pl
break
t['section'] = section
# Post-context: lines after end_line until next table start or heading
post_end = len(lines)
if i + 1 < len(tables):
post_end = min(tables[i+1]['start_line'] - 1, t['end_line'] + 30)
else:
post_end = min(len(lines), t['end_line'] + 30)
post_lines = []
notes = []
in_note = False
for j in range(t['end_line'], post_end):
lj = lines[j].strip()
if not lj:
if in_note and len(notes) > 5 and not lj: # allow blank lines inside note
pass
continue
if lj.startswith('#') or (lj.startswith('|') and lj.endswith('|')):
break
post_lines.append(lj)
if '[주]' in lj or '【주】' in lj or re.match(r'^\s*주\s*[:\)]', lj):
in_note = True
if in_note:
notes.append(lj)
# if line looks like next section heading, stop
if re.match(r'^\d+\s*[\.-]\s*\d+', lj) and not re.match(r'^\s*[\(\[\d]+\s*[\.\)]', lj):
break
t['post_lines'] = post_lines
t['notes'] = notes
print(f"Sample table 10 (F0010):")
t10 = tables[9]
print(f" ID: {t10['table_id']}, Chapter: {t10['chapter']}, Section: {t10['section']}")
print(f" Start line: {t10['start_line']}, End line: {t10['end_line']}")
print(f" Pre-context (last 3): {t10['pre_context'][-3:]}")
print(f" Notes count: {len(t10['notes'])}")
if t10['notes']:
print(f" Notes sample: {t10['notes'][:3]}")