111 lines
4.5 KiB
Python
111 lines
4.5 KiB
Python
import sys, os, re, json
|
||
sys.stdout.reconfigure(encoding='utf-8')
|
||
|
||
# 1. Load official TOC items from const master
|
||
with open('resources/data_work_item_master/const_work_item_master_2026-01-01.json', 'r', encoding='utf-8') as f:
|
||
master = json.load(f)
|
||
|
||
toc_items = master.get('work_items', [])
|
||
print(f"Loaded official TOC work items: {len(toc_items)}")
|
||
|
||
# Create a lookup map: (toc_number, division) -> name
|
||
# Note: number in const is like "1-2-2", "3-3-6", etc.
|
||
toc_dict = {}
|
||
for item in toc_items:
|
||
num = item.get('number', '').strip()
|
||
name = item.get('name', '').strip()
|
||
div = item.get('division', '').strip()
|
||
if num and name and '-' in num:
|
||
# Key by (division, num)
|
||
toc_dict[(div, num)] = name
|
||
# Also key by num alone
|
||
if num not in toc_dict:
|
||
toc_dict[num] = []
|
||
if isinstance(toc_dict[num], list):
|
||
toc_dict[num].append((div, name))
|
||
|
||
print(f"Unique TOC numbers with hyphens: {len([k for k in toc_dict.keys() if isinstance(k, str)])}")
|
||
|
||
base_dir = "resources/knowledge/original/원가계산/건설공사_표준품셈"
|
||
|
||
# Division mapper from file path
|
||
def get_division(rel_path):
|
||
if "01_공통부문" in rel_path: return "공통부문"
|
||
if "02_토목부문" in rel_path: return "토목부문"
|
||
if "03_건축부문" in rel_path: return "건축부문"
|
||
if "04_기계설비부문" in rel_path: return "기계설비부문"
|
||
if "05_유지관리부문" in rel_path: return "유지관리부문"
|
||
return ""
|
||
|
||
all_md_files = []
|
||
for root, dirs, files in os.walk(base_dir):
|
||
for f in files:
|
||
if f.endswith('.md') and not f.startswith('_') and '개정사항' not in f and '2026년_건설공사_표준품셈.md' not in f:
|
||
all_md_files.append(os.path.join(root, f))
|
||
|
||
verified_fixes = []
|
||
|
||
for fpath in sorted(all_md_files):
|
||
rel_path = os.path.relpath(fpath, base_dir)
|
||
div = get_division(rel_path)
|
||
with open(fpath, 'r', encoding='utf-8') as f:
|
||
text = f.read()
|
||
|
||
lines = text.split('\n')
|
||
file_fixes = []
|
||
|
||
for line_idx, line in enumerate(lines):
|
||
line_num = line_idx + 1
|
||
if line.strip().startswith('|') and line.strip().endswith('|'):
|
||
continue
|
||
|
||
# Match pattern: text ending with non-space immediately followed by sec_num
|
||
# e.g. "한다.1-2-2 단위표준"
|
||
# We search for any number like \d+-\d+(?:-\d+)?
|
||
matches = list(re.finditer(r'([^\s#\-\*\>\|])(\d+-\d+(?:-\d+)?)\s*([가-힣\w\(\)\/·\s]*)', line))
|
||
for m in matches:
|
||
prev_char = m.group(1)
|
||
sec_num = m.group(2)
|
||
following_text = m.group(3).strip()
|
||
|
||
# check if prev_char is an opening quote or bracket
|
||
if prev_char in ["'", '"', '‘', '’', '[', '(', '제', '표', '·', ':', '―', '-', '/']:
|
||
continue
|
||
|
||
# Check against TOC
|
||
matched_toc = None
|
||
if (div, sec_num) in toc_dict:
|
||
matched_toc = toc_dict[(div, sec_num)]
|
||
elif sec_num in toc_dict and isinstance(toc_dict[sec_num], list):
|
||
# find match
|
||
for d, nm in toc_dict[sec_num]:
|
||
if d == div:
|
||
matched_toc = nm
|
||
break
|
||
if not matched_toc and len(toc_dict[sec_num]) == 1:
|
||
matched_toc = toc_dict[sec_num][0][1]
|
||
|
||
if matched_toc:
|
||
# verify following text contains keywords of toc title
|
||
# e.g. following_text has first word of matched_toc
|
||
first_word = re.split(r'[\s\(\)]', matched_toc)[0]
|
||
if first_word and first_word in following_text[:30]:
|
||
file_fixes.append({
|
||
"file": rel_path,
|
||
"line": line_num,
|
||
"prev_char": prev_char,
|
||
"sec_num": sec_num,
|
||
"toc_name": matched_toc,
|
||
"matched_pos": m.start(2),
|
||
"line_snippet": line[max(0, m.start(2)-20):min(len(line), m.start(2)+40)]
|
||
})
|
||
|
||
if file_fixes:
|
||
print(f"{rel_path}: {len(file_fixes)} confirmed attached TOC section headers")
|
||
verified_fixes.extend(file_fixes)
|
||
|
||
print(f"\n=== Total Confirmed Attached TOC Section Headers across 45 files: {len(verified_fixes)} ===")
|
||
|
||
with open('scratch/confirmed_attached_headers.json', 'w', encoding='utf-8') as f:
|
||
json.dump(verified_fixes, f, ensure_ascii=False, indent=2)
|