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']}")