91 lines
4.1 KiB
Python
91 lines
4.1 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')
|
||
|
||
suspicious_cases = []
|
||
|
||
# Scan markdown tables for suspicious remarks or 조건 cells
|
||
for fpath in target_files:
|
||
fname = os.path.basename(fpath)
|
||
with open(fpath, 'r', encoding='utf-8') as f:
|
||
lines = f.readlines()
|
||
|
||
current_sec = 'UNKNOWN'
|
||
in_table = False
|
||
headers = []
|
||
table_rows = []
|
||
header_idx = 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 = sec_m.group(1).strip()
|
||
|
||
if line_s.startswith('|') and not line_s.startswith('|---'):
|
||
cols = [c.strip() for c in line_s.split('|')[1:-1]]
|
||
if not in_table:
|
||
# Header row
|
||
if any('비고' in c or '비 고' in c or '구분' in c or '직종' in c or '규격' in c for c in cols):
|
||
headers = cols
|
||
in_table = True
|
||
header_idx = 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 table_rows for suspicious patterns
|
||
# Find remarks col index if any
|
||
remarks_idx = -1
|
||
for ci, h in enumerate(headers):
|
||
if '비고' in h or '비 고' in h:
|
||
remarks_idx = ci
|
||
break
|
||
|
||
for ri, (ln, rcols) in enumerate(table_rows):
|
||
# Check remarks cell
|
||
if remarks_idx != -1 and remarks_idx < len(rcols):
|
||
rval = rcols[remarks_idx]
|
||
# Patterns: starts with %, contains lonely number/percentage, or short fragment
|
||
if re.match(r'^[\d\.]+\s*[%%]', rval) or rval in ['45%', '50%', '30%'] or re.match(r'^[0-9]+[가-힣a-zA-Z]*$', rval) and len(rval) <= 4:
|
||
suspicious_cases.append({
|
||
'type': 'Suspicious Remarks Value',
|
||
'file': fname,
|
||
'sec': current_sec,
|
||
'line': ln,
|
||
'row': rcols,
|
||
'remarks': rval,
|
||
'reason': f'Remarks starts with percentage/number: {rval}'
|
||
})
|
||
# Check if rcols has ditto mark following an empty cell or strange transition
|
||
for ci, cval in enumerate(rcols):
|
||
if cval in ['〃', '"', '″'] and ri == 0:
|
||
suspicious_cases.append({
|
||
'type': 'Ditto on First Row',
|
||
'file': fname,
|
||
'sec': current_sec,
|
||
'line': ln,
|
||
'row': rcols,
|
||
'col_idx': ci,
|
||
'reason': f'Ditto mark on first row of table: {cval}'
|
||
})
|
||
|
||
in_table = False
|
||
headers = []
|
||
table_rows = []
|
||
|
||
print(f"Total suspicious cases found in MD: {len(suspicious_cases)}")
|
||
for sc in suspicious_cases:
|
||
print(f"[{sc['file']}] {sc['sec']} (L{sc['line']}): {sc['reason']}")
|
||
print(f" Row: {sc['row']}")
|