Files
CTStruct/docs/ARCHITECTURE.md
gm 6e3cd19b55 feat: initial CTStruct framework
- CTNode: 트리 기본 단위 (전위/후위/BFS 순회, 탐색, 분리)
- CTTree: 트리 컨테이너 (빌더 API, TOC, filter/map/merge)
- NodeType: 구조/블록/인라인/메타 노드 타입 Enum
- MarkdownParser: Markdown → CTTree 파서
- MarkdownRenderer: CTTree → Markdown 렌더러
- JSONRenderer: CTTree → JSON 직렬화
- 27개 단위/통합 테스트 전체 통과
2026-05-30 20:40:28 +09:00

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         — 타입 검사