"""MDX 01~03에서 17개 단위를 각각 추출. 중목차는 '제목만'이 아니라 소목차/블릿 내용까지 포함한 의미 단위로 처리.""" import re from pathlib import Path MDX_DIR = Path(r"d:\ad-hoc\kei\design_agent\samples\mdx_batch") def read_mdx(fname): with open(MDX_DIR / fname, encoding="utf-8") as f: content = f.read() # frontmatter 제거 content = re.sub(r"^---.*?---", "", content, flags=re.DOTALL).strip() # import 문 제거 content = re.sub(r"^import .*$", "", content, flags=re.MULTILINE) return content def extract_details_blocks(text): """
...
블록들 반환. [(full_match, inner_text), ...]""" pattern = re.compile(r"
.*?
", re.DOTALL) return pattern.findall(text) def remove_details(text): """
...
블록 제거""" return re.sub(r"
.*?
", "", text, flags=re.DOTALL) def extract_markdown_tables(text): """| ... | ... | 형식 표 블록들 반환.""" lines = text.split("\n") tables = [] current = [] in_table = False for ln in lines: stripped = ln.strip() if re.match(r"^\|.*\|", stripped): current.append(ln) in_table = True elif in_table: # 표 끝 if current: tables.append("\n".join(current)) current = [] in_table = False if current: tables.append("\n".join(current)) return tables def extract_images(text): """![alt](src) 이미지. [(alt, src), ...]""" pattern = re.compile(r"!\[([^\]]*)\]\(([^)]+)\)") return pattern.findall(text) def get_section(text, level, title_pattern, title_weight=3): """특정 레벨의 섹션 제목 + 본문 추출. title_weight: 제목을 본문 맨 앞에 N번 반복해서 가중치 부여 (BM25/TF-IDF에서 자동으로 높은 점수). 0으로 주면 제목 제외 (구버전 동작).""" prefix = "#" * level lines = text.split("\n") start = None title_text = "" for i, ln in enumerate(lines): m = re.match(rf"^{prefix}\s+{title_pattern}", ln) if m: start = i title_text = ln[level:].strip() break if start is None: return "" end = len(lines) for i in range(start + 1, len(lines)): ln = lines[i] m = re.match(r"^(#+)\s", ln) if m and len(m.group(1)) <= level: end = i break body = "\n".join(lines[start + 1:end]).strip() if title_weight > 0 and title_text: title_block = "\n".join([title_text] * title_weight) return (title_block + "\n\n" + body).strip() return body def extract_units(): """17개 단위를 추출해서 {unit_id: text} dict 반환""" mdx01 = read_mdx("01.mdx") mdx02 = read_mdx("02.mdx") mdx03 = read_mdx("03.mdx") units = {} # ═══════ MDX01 ═══════ # intro: 첫 ## 이전 텍스트,
는 제외 intro_block = mdx01.split("\n## ")[0] # intro의
details01 = extract_details_blocks(intro_block) # intro 본문 (details 제외) units["MDX01-intro"] = remove_details(intro_block).strip() units["MDX01-intro-details"] = details01[0] if details01 else "" # ## 1. 용어 정의 sec01_1 = get_section(mdx01, 2, "1\\. 용어 정의") units["MDX01-1"] = sec01_1 # ## 2. 용어간 상호관계 — 본문은 details 제외, 이미지 제외 sec01_2 = get_section(mdx01, 2, "2\\. 용어간 상호관계") sec01_2_main = remove_details(sec01_2) # 이미지 제거 sec01_2_main = re.sub(r"!\[[^\]]*\]\([^)]+\)", "", sec01_2_main).strip() units["MDX01-2"] = sec01_2_main # 이미지 단위 imgs01_2 = extract_images(sec01_2) if imgs01_2: alt, src = imgs01_2[0] units["MDX01-2-image"] = f"{alt} {src}" else: units["MDX01-2-image"] = "" #
(비교표) details01_2 = extract_details_blocks(sec01_2) units["MDX01-2-details"] = details01_2[0] if details01_2 else "" # ═══════ MDX02 ═══════ # ## 1. DX의 궁극적 목표 — 이미지 제외 sec02_1 = get_section(mdx02, 2, "1\\. DX의 궁극적 목표") sec02_1_main = re.sub(r"!\[[^\]]*\]\([^)]+\)", "", sec02_1).strip() units["MDX02-1"] = sec02_1_main imgs02_1 = extract_images(sec02_1) units["MDX02-1-image"] = f"{imgs02_1[0][0]} {imgs02_1[0][1]}" if imgs02_1 else "" # ## 2. 주체별 기대효과 (컨테이너 — 소목차+블릿 전체 포함) sec02_2 = get_section(mdx02, 2, "2\\. DX 기반 Process 혁신") units["MDX02-2"] = sec02_2 # 소목차까지 다 포함 # ### 2.1 업무 수행 과정의 변화 sec02_2_1 = get_section(mdx02, 3, "2\\.1 업무 수행 과정") units["MDX02-2.1"] = sec02_2_1 # ### 2.2 DX 시행 주체별 기대효과 sec02_2_2 = get_section(mdx02, 3, "2\\.2 DX 시행 주체별") units["MDX02-2.2"] = sec02_2_2 # 2.2 안의 표만 tables02_2_2 = extract_markdown_tables(sec02_2_2) units["MDX02-2.2-table"] = tables02_2_2[0] if tables02_2_2 else "" # ═══════ MDX03 ═══════ # ## 1. 필수 요건 sec03_1 = get_section(mdx03, 2, "1\\. DX 시행을 위한 필수 요건") units["MDX03-1"] = sec03_1 # ## 2. Process/Product 혁신 (컨테이너) sec03_2 = get_section(mdx03, 2, "2\\. Process의 혁신과 Product") units["MDX03-2"] = sec03_2 # ### 2.1 과정(Process)의 혁신 sec03_2_1 = get_section(mdx03, 3, "2\\.1 과정\\(Process\\)의 혁신") units["MDX03-2.1"] = sec03_2_1 # 2.1 안의 표만 tables03_2_1 = extract_markdown_tables(sec03_2_1) units["MDX03-2.1-table"] = tables03_2_1[0] if tables03_2_1 else "" # ### 2.2 결과(Product)의 변화 sec03_2_2 = get_section(mdx03, 3, "2\\.2 결과\\(Product\\)의 변화") units["MDX03-2.2"] = sec03_2_2 return units if __name__ == "__main__": units = extract_units() print(f"총 {len(units)}개 단위 추출\n") for uid, text in units.items(): preview = text[:80].replace("\n", " ").strip() print(f" {uid:25s} [{len(text):4d}자] {preview}...")