Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.2.0579.9 KB2026-09-150.1.1576.6 KB2026-09-12
Version
0.2.0
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-09-15
Size
579.9 KB
Downloads
2
Checksum
58312d92e63a92784e82a974317afd849e59d143a6320c3cc62faa0980834a7b
Dependencies
None

node.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//! 構文木の型


/// 記号の種別。前後に入れる空きと、斜体にするかどうかを決める
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Class {
    /// 変数として斜体で組む文字
    Variable,
    /// 立体で組むふつうの文字 (数字など)
    Ordinary,
    /// 二項演算子
    Binary,
    /// 関係記号
    Relation,
    /// 開き括弧
    Open,
    /// 閉じ括弧
    Close,
    /// 区切り
    Punctuation,
    /// 関数名
    Function,
    /// 大きな演算子
    Large,
    /// 幅だけを持つ空き。値は em
    Space(f64),
}


/// 文字の装い
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Style {
    /// 種別にまかせる (変数だけ斜体)
    Auto,
    /// 立体
    Roman,
    /// 斜体
    Italic,
    /// 太字
    Bold,
    /// 太字の斜体
    BoldItalic,
    /// 黒板太字
    Blackboard,
    /// スクリプト体
    Script,
    /// フラクトゥール
    Fraktur,
    /// サンセリフ
    SansSerif,
    /// 等幅
    Monospace,
}


/// 添字を土台の真上と真下に置くかどうか
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Limits {
    /// display のときだけ上下に置く。大きな演算子の既定
    Auto,
    /// いつでも上下に置く
    Always,
    /// いつでも横に置く
    Never,
}


/// 組み方の段階
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Level {
    Display,
    Text,
    Script,
    ScriptScript,
}


/// 行列の列の揃え方
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Align {
    Left,
    Center,
    Right,
}


/// 行列の列と行の空け方
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Spacing {
    /// matrix や array。列のあいだを同じだけ空ける
    Matrix,
    /// amsmath の align・aligned・gather。右寄せと左寄せの 2 列を 1 組として詰め、組と組のあいだを空ける
    Align,
    /// amsmath の alignat。組と組のあいだも詰める
    Alignat,
}


/// 数式の構文木
#[derive(Debug, Clone, PartialEq)]
pub enum Node {
    /// 1 つの記号。text は複数文字のこともある (sin, log など)
    Symbol {
        text: String,
        class: Class,
    },
    /// \text{...} の中身。空白をそのまま残して立体で組む
    Text(String),
    /// 横に並んだ要素の列
    Row(Vec<Node>),
    /// 分数。bar が false なら線を引かない (\binom)
    Fraction {
        numerator: Box<Node>,
        denominator: Box<Node>,
        bar: bool,
    },
    /// 根号。index は \sqrt[3]{x} の 3
    Root {
        index: Option<Box<Node>>,
        body: Box<Node>,
    },
    /// 上付きと下付き
    Scripts {
        base: Box<Node>,
        superscript: Option<Box<Node>>,
        subscript: Option<Box<Node>>,
        limits: Limits,
    },
    /// 中身の高さに合わせて伸びる括弧。要らない側は空文字
    Fenced {
        left: &'static str,
        right: &'static str,
        body: Box<Node>,
    },
    /// 行列。rows[行][列] がセル、lines はその手前に横線を引く行の番号
    Matrix {
        rows: Vec<Vec<Node>>,
        left: &'static str,
        right: &'static str,
        align: Vec<Align>,
        lines: Vec<usize>,
        spacing: Spacing,
    },
    /// 装いを変えたもの
    Styled {
        style: Style,
        body: Box<Node>,
    },
    /// 演算子名 (\operatorname)。中身は立体で組み、前後の空きは \sin などの関数名と同じにする
    Operator {
        body: Box<Node>,
    },
    /// 中身に付ける印。above が false なら下に付ける
    Accent {
        mark: &'static str,
        body: Box<Node>,
        above: bool,
    },
    /// 組み方の段階を切り替えたもの
    Sized {
        level: Level,
        body: Box<Node>,
    },
    /// 大きさを指定した括弧。height は em
    Delimiter {
        text: &'static str,
        height: f64,
        class: Class,
    },
    /// 上下に置いたものの幅に合わせて伸びる記号
    Extend {
        mark: &'static str,
        above: Option<Box<Node>>,
        below: Option<Box<Node>>,
    },
    /// 全体に引く線。above が true なら上、false なら下
    Line {
        body: Box<Node>,
        above: bool,
    },
    /// 場所だけ空けて何も描かないもの
    ///
    /// width と height は、中身のどちらの寸法を残すかを表す。
    /// `\phantom` は両方、`\hphantom` は幅だけ、`\vphantom` は高さだけを残す
    Phantom {
        body: Box<Node>,
        width: bool,
        height: bool,
    },
}


/// 空の Row を作る
pub fn empty() -> Node {
    Node::Row(Vec::new())
}


/// 中身のない Row かどうか
pub fn is_empty(node: &Node) -> bool {
    matches!(node, Node::Row(items) if items.is_empty())
}


/// 前後の空きを決めるための種別。まとまりはすべて Ordinary として扱う
pub fn class_of(node: &Node) -> Class {
    match node {
        Node::Symbol {class, ..} => *class,
        Node::Scripts {base, ..} => class_of(base),
        Node::Styled {body, ..} => class_of(body),
        Node::Operator {..} => Class::Function,
        Node::Sized {body, ..} => class_of(body),
        Node::Delimiter {class, ..} => *class,
        Node::Extend {..} => Class::Relation,
        _ => Class::Ordinary,
    }
}


/// CSS の class 名
pub fn class_name(class: Class) -> &'static str {
    match class {
        Class::Variable => "variable",
        Class::Ordinary => "ordinary",
        Class::Binary => "binary",
        Class::Relation => "relation",
        Class::Open => "open",
        Class::Close => "close",
        Class::Punctuation => "punctuation",
        Class::Function => "function",
        Class::Large => "large",
        Class::Space(_) => "space",
    }
}