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

151 lines
7.4 KiB
Python

import glob, re, os, sys, fitz
sys.stdout.reconfigure(encoding='utf-8')
pdf_path = 'resources/knowledge/original/원가계산/건설공사_표준품셈/2026년_건설공사_표준품셈.pdf'
doc = fitz.open(pdf_path)
target_files = []
target_files.extend(glob.glob('resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문/*.md'))
target_files.extend(glob.glob('resources/knowledge/original/원가계산/건설공사_표준품셈/05_유지관리부문/*.md'))
target_files.append('resources/knowledge/original/원가계산/건설공사_표준품셈/04_기계설비부문/제13장_플랜트설비공사.md')
print(f"Target files: {len(target_files)}")
# Build PDF index of section headings
print("Indexing PDF pages for section headings...")
sec_to_pdf_page = {}
for p_num in range(len(doc)):
text = doc[p_num].get_text()
# Find all patterns like X-Y-Z or X-Y
matches = re.findall(r'(\d+-\d+(?:-\d+)?)', text)
for m in matches:
sec_to_pdf_page.setdefault(m, []).append(p_num)
print(f"Indexed {len(sec_to_pdf_page)} section numbers in PDF.")
# Now parse each markdown file's tables that have a Remarks column
discrepancies = []
for fpath in target_files:
fname = os.path.basename(fpath)
with open(fpath, 'r', encoding='utf-8') as f:
lines = f.readlines()
current_sec_num = 'UNKNOWN'
current_sec_title = 'UNKNOWN'
in_table = False
headers = []
table_rows = []
start_line = 0
for idx, line in enumerate(lines):
line_s = line.strip()
sec_m = re.search(r'(\d+-\d+(?:-\d+)?)(\s+[^\n(]+)?', line_s)
if sec_m and not line_s.startswith('|'):
current_sec_num = sec_m.group(1).strip()
current_sec_title = line_s
if line_s.startswith('|') and not line_s.startswith('|---'):
cols = [c.strip() for c in line_s.split('|')[1:-1]]
if not in_table:
# check if header has 비고 or 비 고
if any('비고' in c or '비 고' in c for c in cols):
headers = cols
in_table = True
start_line = idx + 1
table_rows = []
continue
if in_table:
table_rows.append((idx + 1, cols))
else:
if in_table and (line_s == '' or not line_s.startswith('|')):
# Check this table against PDF!
remarks_col_idx = -1
for ci, h in enumerate(headers):
if '비고' in h or '비 고' in h:
remarks_col_idx = ci
break
if remarks_col_idx != -1 and len(table_rows) > 0:
md_remarks = [r[1][remarks_col_idx] if remarks_col_idx < len(r[1]) else '' for r in table_rows]
# Find matching page in PDF
cand_pages = sec_to_pdf_page.get(current_sec_num, [])
# filter to body pages (> 45)
body_pages = [p for p in cand_pages if p > 45]
found_pdf_table = False
for p in body_pages:
page = doc[p]
tabs = page.find_tables()
for tab in tabs:
df = tab.extract()
if not df or len(df) < 2:
continue
pdf_header = [c if c else '' for c in df[0]]
# Check if pdf_header has 비고
pdf_rem_idx = -1
for pci, ph in enumerate(pdf_header):
if '비고' in ph or '비 고' in ph:
pdf_rem_idx = pci
break
if pdf_rem_idx != -1:
found_pdf_table = True
# Extract pdf remarks
pdf_remarks_raw = [r[pdf_rem_idx] if pdf_rem_idx < len(r) and r[pdf_rem_idx] else '' for r in df[1:]]
# Flatten any multi-line in pdf remarks
pdf_remarks_split = []
for pr in pdf_remarks_raw:
pdf_remarks_split.extend([sub.strip() for sub in pr.split('\n') if sub.strip()])
# Compare count of non-empty remarks or ditto presence
md_non_empty = [m for m in md_remarks if m]
pdf_non_empty = [p for p in pdf_remarks_split if p]
# Check if ditto marks or numbers mismatch
has_ditto = any('〃' in m or '"' in m for m in md_remarks) or any('〃' in p for p in pdf_non_empty)
# If row count differs significantly or ditto count differs
md_ditto_cnt = sum(1 for m in md_remarks if '〃' in m or '"' in m)
pdf_ditto_cnt = sum(1 for p in pdf_non_empty if '〃' in p or '"' in p)
if has_ditto and md_ditto_cnt != pdf_ditto_cnt:
discrepancies.append({
'file': fname,
'sec': current_sec_num,
'line': start_line,
'type': 'Ditto count mismatch',
'md_dittos': md_ditto_cnt,
'pdf_dittos': pdf_ditto_cnt,
'md_remarks': md_remarks,
'pdf_remarks': pdf_remarks_raw,
'page': p + 1
})
elif len(md_remarks) != len(df) - 1:
# Row count mismatch in table with remarks
discrepancies.append({
'file': fname,
'sec': current_sec_num,
'line': start_line,
'type': 'Row count mismatch in remarks table',
'md_rows': len(md_remarks),
'pdf_rows': len(df) - 1,
'md_remarks': md_remarks,
'pdf_remarks': pdf_remarks_raw,
'page': p + 1
})
in_table = False
headers = []
table_rows = []
print(f"\nTotal Discrepancies found: {len(discrepancies)}")
for d in discrepancies:
print(f"\n[{d['file']}] {d['sec']} (L{d['line']}, PDF page {d.get('page')}) -> {d['type']}")
if 'md_dittos' in d:
print(f" MD dittos: {d['md_dittos']} vs PDF dittos: {d['pdf_dittos']}")
if 'md_rows' in d:
print(f" MD rows: {d['md_rows']} vs PDF rows: {d['pdf_rows']}")
print(f" MD remarks: {d['md_remarks'][:6]}")
print(f" PDF remarks: {d['pdf_remarks'][:6]}")