- CTNode: 트리 기본 단위 (전위/후위/BFS 순회, 탐색, 분리) - CTTree: 트리 컨테이너 (빌더 API, TOC, filter/map/merge) - NodeType: 구조/블록/인라인/메타 노드 타입 Enum - MarkdownParser: Markdown → CTTree 파서 - MarkdownRenderer: CTTree → Markdown 렌더러 - JSONRenderer: CTTree → JSON 직렬화 - 27개 단위/통합 테스트 전체 통과
149 lines
4.1 KiB
Markdown
149 lines
4.1 KiB
Markdown
# CTStruct
|
||
|
||
> **텍스트 양식을 구조화하는 Python 트리 자료형 라이브러리**
|
||
|
||
CTStruct는 Markdown, 일반 텍스트, JSON 등 다양한 텍스트 포맷을 **통일된 트리 자료구조(CTTree)** 로 파싱·변환·렌더링하는 Python 라이브러리입니다.
|
||
|
||
```
|
||
텍스트 입력 → [Parser] → CTTree → [Renderer] → 출력 포맷
|
||
↑
|
||
(탐색 / 변환 / 병합)
|
||
```
|
||
|
||
---
|
||
|
||
## 특징
|
||
|
||
- **통일된 트리 API** — 어떤 포맷이든 `CTNode` / `CTTree` 로 표현
|
||
- **플러그인형 파서 & 렌더러** — `BaseParser` / `BaseRenderer` 상속으로 손쉽게 확장
|
||
- **풍부한 탐색 API** — `walk()`, `find()`, `ancestors()`, `toc()` 등
|
||
- **불변 변환** — `filter()`, `map()` 은 새 트리를 반환하여 원본 보존
|
||
- **직렬화** — `to_dict()` / `from_dict()` 로 JSON 직렬화 지원
|
||
- **의존성 없음** — 표준 라이브러리만 사용
|
||
|
||
---
|
||
|
||
## 빠른 시작
|
||
|
||
### 설치
|
||
|
||
```bash
|
||
pip install -e .
|
||
```
|
||
|
||
### 기본 사용 예시
|
||
|
||
```python
|
||
from ctstruct import CTTree, CTNode, NodeType
|
||
from ctstruct.parsers import MarkdownParser
|
||
from ctstruct.renderers import MarkdownRenderer, JSONRenderer
|
||
|
||
# 1) 직접 트리 빌드
|
||
tree = CTTree(title="나의 문서")
|
||
sec = CTNode(NodeType.SECTION)
|
||
sec.append(CTNode(NodeType.HEADING, "소개", {"level": 1}))
|
||
sec.append(CTNode(NodeType.PARAGRAPH, "CTStruct 는 텍스트를 트리로 구조화합니다."))
|
||
sec.append(CTTree.make_list(["파싱", "변환", "렌더링"]))
|
||
tree.root.append(sec)
|
||
|
||
# 2) Markdown 파싱
|
||
parser = MarkdownParser()
|
||
tree = parser.parse(open("document.md").read())
|
||
|
||
# 3) 탐색
|
||
for heading in tree.find(NodeType.HEADING):
|
||
print(heading.attr("level"), heading.content)
|
||
|
||
# 목차 생성
|
||
for entry in tree.toc():
|
||
print(" " * (entry["level"] - 1) + entry["text"])
|
||
|
||
# 4) 렌더링
|
||
md_renderer = MarkdownRenderer()
|
||
print(md_renderer.render(tree))
|
||
|
||
json_renderer = JSONRenderer(indent=2)
|
||
print(json_renderer.render(tree))
|
||
|
||
# 5) 트리 변환 (불변)
|
||
filtered = tree.filter(lambda n: n.node_type != NodeType.CODE_BLOCK)
|
||
upper = tree.map(lambda n: setattr(n, "content", (n.content or "").upper()) or None)
|
||
```
|
||
|
||
### 트리 구조 시각화
|
||
|
||
```python
|
||
print(tree.pretty())
|
||
# [a1b2c3d4] ROOT: None
|
||
# [e5f6a7b8] SECTION: None
|
||
# [c9d0e1f2] HEADING level=1: '소개'
|
||
# [a3b4c5d6] PARAGRAPH: 'CTStruct 는 텍스트를…'
|
||
# [e7f8a9b0] LIST style='unordered': None
|
||
# [c1d2e3f4] LIST_ITEM: '파싱'
|
||
# [a5b6c7d8] LIST_ITEM: '변환'
|
||
# [e9f0a1b2] LIST_ITEM: '렌더링'
|
||
```
|
||
|
||
---
|
||
|
||
## 지원 노드 타입
|
||
|
||
| 카테고리 | 타입 | 설명 |
|
||
|----------|------|------|
|
||
| 구조 | `ROOT` | 트리 최상위 |
|
||
| 구조 | `DOCUMENT` | 문서 단위 |
|
||
| 구조 | `SECTION` | 헤딩 + 내용 묶음 |
|
||
| 블록 | `HEADING` | 제목 (level 1–6) |
|
||
| 블록 | `PARAGRAPH` | 문단 |
|
||
| 블록 | `LIST` / `LIST_ITEM` | 목록 |
|
||
| 블록 | `TABLE` / `TABLE_ROW` / `TABLE_CELL` | 표 |
|
||
| 블록 | `CODE_BLOCK` | 코드 블록 |
|
||
| 블록 | `BLOCKQUOTE` | 인용구 |
|
||
| 블록 | `DIVIDER` | 구분선 |
|
||
| 인라인 | `TEXT` `BOLD` `ITALIC` `CODE` `LINK` `IMAGE` | 인라인 요소 |
|
||
| 메타 | `METADATA` | 문서 메타 (frontmatter) |
|
||
| 메타 | `ANNOTATION` | 주석/노트 |
|
||
| 메타 | `CUSTOM` | 사용자 정의 확장 |
|
||
|
||
---
|
||
|
||
## 프로젝트 구조
|
||
|
||
```
|
||
CTStruct/
|
||
├── ctstruct/
|
||
│ ├── __init__.py # 공개 API
|
||
│ ├── types.py # NodeType Enum
|
||
│ ├── node.py # CTNode 클래스
|
||
│ ├── tree.py # CTTree 클래스
|
||
│ ├── parsers/
|
||
│ │ ├── base.py # BaseParser (추상)
|
||
│ │ └── markdown.py # MarkdownParser
|
||
│ └── renderers/
|
||
│ ├── base.py # BaseRenderer (추상)
|
||
│ ├── markdown.py # MarkdownRenderer
|
||
│ └── json_renderer.py # JSONRenderer
|
||
├── tests/
|
||
│ ├── test_node.py
|
||
│ ├── test_tree.py
|
||
│ └── test_parsers.py
|
||
├── docs/
|
||
│ └── ARCHITECTURE.md
|
||
└── pyproject.toml
|
||
```
|
||
|
||
---
|
||
|
||
## 테스트 실행
|
||
|
||
```bash
|
||
pip install -e ".[dev]"
|
||
pytest -v --cov=ctstruct
|
||
```
|
||
|
||
---
|
||
|
||
## 라이선스
|
||
|
||
MIT
|