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

91 lines
4.6 KiB
Python

import sys, os, re, json
sys.stdout.reconfigure(encoding='utf-8')
md_files = [
("공통_제1장", "resources/knowledge/original/원가계산/건설공사_표준품셈/01_공통부문/제1장_적용기준.md"),
("공통_제3장", "resources/knowledge/original/원가계산/건설공사_표준품셈/01_공통부문/제3장_토공사.md"),
("공통_제4장", "resources/knowledge/original/원가계산/건설공사_표준품셈/01_공통부문/제4장_조경공사.md"),
("공통_제6장", "resources/knowledge/original/원가계산/건설공사_표준품셈/01_공통부문/제6장_철근콘크리트공사.md"),
("토목_제1장", "resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제1장_도로포장공사.md"),
("토목_제6장", "resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/제6장_관부설및접합공사.md"),
("건축_제9장", "resources/knowledge/original/원가계산/건설공사_표준품셈/03_건축부문/제9장_미장공사.md"),
("유지관리_제1장", "resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제1장_공통.md"),
("유지관리_제3장", "resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/제3장_건축.md"),
]
report = {}
for label, path in md_files:
if not os.path.exists(path):
continue
with open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
print(f"\n=======================================================")
print(f"Scanning {label} ({os.path.basename(path)}) - {len(lines)} lines")
file_issues = {
"attached_section_headers": [],
"collapsed_table_rows": [],
"attached_notes_tail": [],
"page_transition_artifacts": []
}
for idx, line in enumerate(lines):
line_num = idx + 1
line_clean = line.strip()
# 1. Attached section headers: e.g. text ending immediately with 1-2-2 or 3-4-1 without newline
m_sec = re.findall(r'([^\s#\-\*\>\|])(\d+-\d+(?:-\d+)?)', line)
for prev_char, sec_num in m_sec:
# check if it looks like a real section header
if prev_char not in ['제', '표', '·', '(', '/', '-', ',', ':']:
file_issues["attached_section_headers"].append({
"line": line_num,
"prev_char": prev_char,
"sec_num": sec_num,
"snippet": line_clean[:120]
})
# 2. Collapsed table rows: table row with extreme length or multiple repeated patterns in single cell
if line_clean.startswith('|') and line_clean.endswith('|'):
cells = [c.strip() for c in line_clean.split('|')[1:-1]]
for c in cells:
# if cell has multiple words separated by space that look like collapsed table rows (e.g. 5 or more items)
tokens = c.split()
if len(tokens) >= 15:
file_issues["collapsed_table_rows"].append({
"line": line_num,
"token_count": len(tokens),
"snippet": c[:100] + "..."
})
break
# 3. Page transition artifacts: e.g. "→4공통부문" or "3제1장 적용기준"
m_page = re.findall(r'(?:→\d+|\d+제\d+장|\d+공통부문|\d+토목부문|\d+건축부문|\d+유지관리부문)', line)
if m_page:
file_issues["page_transition_artifacts"].append({
"line": line_num,
"artifacts": m_page,
"snippet": line_clean[:100]
})
# 4. Attached notes tail: [주] ending with next section immediately
if '[주]' in line or '주]' in line:
m_tail = re.findall(r'(\[주\].*?)(\d+-\d+)', line)
if m_tail:
file_issues["attached_notes_tail"].append({
"line": line_num,
"snippet": line_clean[:100]
})
print(f" - Attached section headers: {len(file_issues['attached_section_headers'])}")
print(f" - Collapsed table rows: {len(file_issues['collapsed_table_rows'])}")
print(f" - Attached notes tails: {len(file_issues['attached_notes_tail'])}")
print(f" - Page transition artifacts: {len(file_issues['page_transition_artifacts'])}")
report[label] = file_issues
with open('scratch/const_md_flaws_scan.json', 'w', encoding='utf-8') as f:
json.dump(report, f, ensure_ascii=False, indent=2)