- CTNode: 트리 기본 단위 (전위/후위/BFS 순회, 탐색, 분리) - CTTree: 트리 컨테이너 (빌더 API, TOC, filter/map/merge) - NodeType: 구조/블록/인라인/메타 노드 타입 Enum - MarkdownParser: Markdown → CTTree 파서 - MarkdownRenderer: CTTree → Markdown 렌더러 - JSONRenderer: CTTree → JSON 직렬화 - 27개 단위/통합 테스트 전체 통과
7.3 KiB
7.3 KiB
CTStruct 아키텍처 문서
1. 개요
CTStruct(Contextual Text Structure)는 다양한 텍스트 포맷을 단일 트리 자료구조로 표현하고, 파서와 렌더러를 플러그인처럼 교체할 수 있도록 설계된 Python 라이브러리입니다.
2. 설계 목표
| 목표 | 설명 |
|---|---|
| 통일성 | Markdown, JSON, 일반 텍스트 등 모든 포맷이 동일한 CTTree API로 조작됨 |
| 확장성 | 새 파서·렌더러를 BaseParser / BaseRenderer 상속으로 추가 가능 |
| 불변 변환 | filter(), map() 은 원본 트리를 변경하지 않고 새 트리 반환 |
| 의존성 최소화 | 표준 라이브러리만 사용, 외부 패키지 없음 |
| 타입 안전성 | NodeType Enum 으로 잘못된 타입 사용 방지 |
3. 핵심 구성요소
3.1 NodeType (types.py)
NodeType
├── 구조 노드: ROOT, DOCUMENT, SECTION
├── 블록 노드: HEADING, PARAGRAPH, LIST, LIST_ITEM,
│ TABLE, TABLE_ROW, TABLE_CELL,
│ CODE_BLOCK, BLOCKQUOTE, DIVIDER
├── 인라인 노드: TEXT, BOLD, ITALIC, CODE, LINK, IMAGE
└── 메타 노드: METADATA, ANNOTATION, CUSTOM
NodeType 은 Python Enum 으로 구현되어 있으며,
노드의 의미적 역할을 정의합니다.
3.2 CTNode (node.py)
트리의 기본 단위. dataclass 로 구현되어 있습니다.
CTNode
├── node_id : str # 고유 식별자 (8자리 hex)
├── node_type : NodeType # 의미적 타입
├── content : str | None # 직접 보유 텍스트
├── attributes : dict # 메타정보 (level, lang, …)
├── parent : CTNode | None
└── children : list[CTNode]
주요 메서드
| 메서드 | 설명 |
|---|---|
append(child) |
자식 추가 (체이닝 지원) |
prepend(child) |
맨 앞 삽입 |
insert(i, child) |
지정 위치 삽입 |
remove(child) |
자식 제거 |
detach() |
부모에서 자신을 분리 |
walk(order) |
"pre" / "post" / "bfs" 순회 |
find(type) |
타입별 하위 노드 검색 |
ancestors() |
부모 방향 이터레이터 |
text_content() |
모든 하위 텍스트 추출 |
pretty() |
트리 시각화 문자열 |
3.3 CTTree (tree.py)
루트 노드를 감싸는 컨테이너. 문서 단위의 고수준 API를 제공합니다.
CTTree
└── root: CTNode (NodeType.ROOT)
빌더 API (정적 메서드)
CTTree.make_heading(text, level)
CTTree.make_paragraph(text)
CTTree.make_code_block(code, language)
CTTree.make_list(items, ordered)
CTTree.make_table(headers, rows)
탐색 API
tree.find(NodeType.HEADING) # 타입별 검색
tree.find_by_id("a1b2c3d4") # ID 검색
tree.headings() # 헤딩 목록
tree.toc() # 목차 생성
tree.walk(order) # 전체 순회
변환 API (원본 불변)
tree.filter(predicate) # 조건 필터링 → 새 CTTree
tree.map(transform) # 변환 적용 → 새 CTTree
tree.merge(other) # 다른 트리 병합 (in-place)
직렬화
d = tree.to_dict() # Python dict
tree = CTTree.from_dict(d) # dict → CTTree
3.4 파서 (parsers/)
BaseParser (추상)
└── parse(text: str) → CTTree
└── MarkdownParser
├── frontmatter 파싱 (--- key: value ---)
├── ATX 헤딩 (# ~ ######)
├── 섹션 자동 분류 (H1 기준)
├── 코드 블록 (``` … ```)
├── 목록 (-, *, 1.)
├── 인용구 (>)
├── 구분선 (---)
└── 문단 (multi-line 연결)
커스텀 파서 작성:
from ctstruct.parsers import BaseParser
from ctstruct import CTTree, CTNode, NodeType
class MyParser(BaseParser):
def parse(self, text: str) -> CTTree:
tree = CTTree()
for line in text.splitlines():
tree.add(NodeType.PARAGRAPH, line)
return tree
3.5 렌더러 (renderers/)
BaseRenderer (추상)
└── render(tree: CTTree) → str
├── MarkdownRenderer → Markdown 텍스트
└── JSONRenderer → JSON 문자열
커스텀 렌더러 작성:
from ctstruct.renderers import BaseRenderer
from ctstruct import CTTree, NodeType
class PlainTextRenderer(BaseRenderer):
def render(self, tree: CTTree) -> str:
lines = []
for node in tree.walk():
if node.content:
lines.append(node.content)
return "\n".join(lines)
4. 데이터 흐름
┌──────────────┐ parse() ┌──────────────┐
│ 텍스트 입력 │ ──────────► │ CTTree │
│ (Markdown, │ │ │
│ JSON, etc) │ │ ┌────────┐ │ render() ┌──────────────┐
└──────────────┘ │ │CTNode │ │ ────────────► │ 텍스트 출력 │
│ │ ├child │ │ │ (Markdown, │
│ │ ├child │ │ │ JSON, etc) │
│ │ └child │ │ └──────────────┘
│ └────────┘ │
│ │
│ filter() │
│ map() │ ──► 새 CTTree
│ merge() │
└──────────────┘
5. 노드 속성 규약
각 노드 타입별 attributes 딕셔너리의 키 규약:
| NodeType | 속성 키 | 타입 | 설명 |
|---|---|---|---|
HEADING |
level |
int (1-6) |
헤딩 레벨 |
CODE_BLOCK |
language |
str |
코드 언어 |
LIST |
style |
"ordered" / "unordered" / "task" |
목록 스타일 |
LIST_ITEM |
checked |
bool |
태스크 목록 체크 여부 |
TABLE_CELL |
align |
"left" / "center" / "right" |
정렬 |
TABLE_CELL |
is_header |
bool |
헤더 셀 여부 |
LINK |
href |
str |
URL |
IMAGE |
src |
str |
이미지 경로 |
IMAGE |
alt |
str |
대체 텍스트 |
METADATA |
(자유형식) | — | frontmatter 키-값 |
6. 확장 계획
| 단계 | 기능 |
|---|---|
| v0.2 | PlainTextParser — 들여쓰기/구분자 기반 텍스트 파싱 |
| v0.2 | HTMLRenderer — CTTree → HTML 변환 |
| v0.3 | JSONParser — JSON 구조 → CTTree |
| v0.3 | YAMLParser — YAML → CTTree |
| v0.4 | XPathQuery — 트리 경로 쿼리 언어 |
| v0.5 | 스트리밍 파서 — 대용량 문서 처리 |
| v1.0 | 완전한 CommonMark 호환 Markdown 파서 |
7. 의존성
Python >= 3.10
표준 라이브러리: uuid, re, json, copy, abc, dataclasses, enum
개발 도구 (선택):
pytest — 테스트
pytest-cov — 커버리지
ruff — 린터
mypy — 타입 검사