unified-hwpeq
v0.1.0
Published
unified plugin to parse HWPEQ (아래아한글 수식) markup
Maintainers
Readme
unified-hwpeq
unified plugin to parse and transform HWPEQ (아래아한글 수식) markup
HWPEQ는 한글과컴퓨터의 아래아한글 워드프로세서에서 사용하는 수식 표현 문법입니다. 이 라이브러리는 HWPEQ 문자열을 AST(Abstract Syntax Tree)로 파싱하고, LaTeX 등 다른 포맷으로 변환할 수 있습니다.
Features
- 🌳 AST 파싱: HWPEQ 문자열을 구조화된 AST로 변환
- 🔄 양방향 변환: HWPEQ ↔ AST ↔ LaTeX
- 🔌 unified 생태계: unified.js 플러그인으로 동작
- 📝 TypeScript: 완전한 타입 지원
- 🛠️ 유틸리티: AST 순회, 검색, 변환 함수 제공
Installation
npm install unified-hwpeq unified
# or
yarn add unified-hwpeq unified
# or
pnpm add unified-hwpeq unifiedUsage
Basic Parsing
import { unified } from 'unified';
import { hwpeqParse } from 'unified-hwpeq';
const processor = unified().use(hwpeqParse);
const ast = processor.parse('1 over 2 + sqrt{x^2 + 1}');
console.log(ast);HWPEQ to LaTeX
import { unified } from 'unified';
import { hwpeqParse, hwpeqToLatex } from 'unified-hwpeq';
const processor = unified()
.use(hwpeqParse)
.use(hwpeqToLatex);
const result = processor.processSync('1 over 2');
console.log(String(result)); // '\\frac{1}{2}'Direct Function Calls
import { parse, toLatex, stringify } from 'unified-hwpeq';
// Parse HWPEQ to AST
const ast = parse('sum_{i=1}^n a_i');
// Convert AST to LaTeX
const latex = toLatex(ast);
console.log(latex); // '\\sum_{i=1}^{n}a_{i}'
// Convert AST back to HWPEQ
const hwpeq = stringify(ast);
console.log(hwpeq); // 'sum_{i=1}^{n} a_i'AST Utilities
import { parse, visit, find, findAll, inspect } from 'unified-hwpeq';
const ast = parse('a over b + c over d');
// Visit all nodes
visit(ast, (node) => {
console.log(node.type);
});
// Find specific node types
visit(ast, 'fraction', (node) => {
console.log('Found fraction:', node);
});
// Find first match
const firstFraction = find(ast, 'fraction');
// Find all matches
const allFractions = findAll(ast, 'fraction');
// Debug print
console.log(inspect(ast));Supported HWPEQ Syntax
Basic Operations
| HWPEQ | Description | LaTeX |
|-------|-------------|-------|
| a over b | 분수 | \frac{a}{b} |
| a atop b | 분수 (선 없음) | {a \atop b} |
| sqrt x | 제곱근 | \sqrt{x} |
| ^n sqrt x | n제곱근 | \sqrt[n]{x} |
| x^2 | 위 첨자 | x^{2} |
| x_i | 아래 첨자 | x_{i} |
Big Operators
| HWPEQ | Description | LaTeX |
|-------|-------------|-------|
| sum_{i=1}^n | 총합 | \sum_{i=1}^{n} |
| prod_{i=1}^n | 곱 | \prod_{i=1}^{n} |
| int_0^1 | 적분 | \int_{0}^{1} |
| lim_{x->0} | 극한 | \lim_{x \to 0} |
Matrix
matrix{a & b # c & d}
pmatrix{a & b # c & d}
bmatrix{a & b # c & d}Accents
| HWPEQ | Description |
|-------|-------------|
| hat x | 모자 (^) |
| bar x | 윗줄 |
| vec x | 벡터 화살표 |
| tilde x | 물결 |
| dot x | 점 하나 |
| ddot x | 점 두 개 |
Special Characters
~: 빈칸 (스페이스)`: 작은 빈칸 (1/4)#: 줄 바꿈&: 칸 맞춤 (탭){}: 그룹화"": 긴 단어 묶음
API
Plugins
hwpeqParse
HWPEQ 문자열을 AST로 파싱하는 unified 플러그인
import { hwpeqParse } from 'unified-hwpeq';
unified().use(hwpeqParse, options);hwpeqStringify
AST를 HWPEQ 문자열로 변환하는 unified 플러그인
import { hwpeqStringify } from 'unified-hwpeq';
unified().use(hwpeqStringify, options);hwpeqToLatex
AST를 LaTeX 문자열로 변환하는 unified 플러그인
import { hwpeqToLatex } from 'unified-hwpeq';
unified().use(hwpeqToLatex, {
displayMode: true,
wrap: 'dollar' // '$...$' or '$$...$$'
});Functions
parse(input: string, options?): Root
HWPEQ 문자열을 AST로 파싱
stringify(ast: Root, options?): string
AST를 HWPEQ 문자열로 변환
toLatex(ast: Root, options?): string
AST를 LaTeX 문자열로 변환
Utilities
visit(tree, [test], visitor)
AST를 순회하면서 visitor 함수 호출
find(tree, test): Node | undefined
조건에 맞는 첫 번째 노드 찾기
findAll(tree, test): Node[]
조건에 맞는 모든 노드 찾기
map(tree, fn): Root
모든 노드를 변환
replace(tree, test, replacement): Root
조건에 맞는 노드를 교체
inspect(tree): string
AST를 문자열로 출력 (디버깅용)
AST Node Types
// Root node
interface Root {
type: 'root';
children: HwpEqContent[];
}
// Fraction
interface Fraction {
type: 'fraction';
numerator: HwpEqContent;
denominator: HwpEqContent;
noLine?: boolean; // atop
}
// Square root
interface Sqrt {
type: 'sqrt';
radicand: HwpEqContent;
index?: HwpEqContent; // n-th root
}
// ... 전체 타입은 src/ast/types.ts 참조Examples
분수 표현
parse('a+b over c+d');
// {
// type: 'root',
// children: [
// { type: 'fraction',
// numerator: { type: 'group', children: [...] },
// denominator: { type: 'group', children: [...] }
// }
// ]
// }행렬
parse('bmatrix{1 & 2 # 3 & 4}');
// → \begin{bmatrix}1 & 2 \\ 3 & 4\end{bmatrix}적분
parse('int_0^inf e^{-x^2} dx');
// → \int_{0}^{\infty}e^{-x^{2}}dxContributing
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
License
MIT © 2024
