@starzhuimeng/formula-editor
Version:
A configurable formula editor with customizable symbols
214 lines • 8.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormulaParser = void 0;
const types_1 = require("../types");
const dom_1 = require("./dom");
/**
* 公式解析器类
*/
class FormulaParser {
/**
* 将字符串解析为公式元素树
* @param formula 公式字符串
* @returns 公式元素树
*/
static parse(formula) {
if (!formula) {
return [];
}
const elements = [];
let currentIndex = 0;
while (currentIndex < formula.length) {
const char = formula[currentIndex];
// 解析数字
if (/[0-9.]/.test(char)) {
let numStr = '';
let j = currentIndex;
while (j < formula.length && /[0-9.]/.test(formula[j])) {
numStr += formula[j];
j++;
}
elements.push({
type: types_1.ElementType.NUMBER,
value: numStr,
id: (0, dom_1.generateId)()
});
currentIndex = j;
continue;
}
// 解析变量(字母)
if (/[a-zA-Z]/.test(char)) {
// 检查是否是预定义函数名
if (formula.substring(currentIndex).match(/^(sin|cos|tan|log|ln)\(/)) {
const match = formula.substring(currentIndex).match(/^(sin|cos|tan|log|ln)/);
if (match) {
elements.push({
type: types_1.ElementType.FUNCTION,
value: match[0],
id: (0, dom_1.generateId)()
});
currentIndex += match[0].length;
continue;
}
}
// 处理为单个字母变量
elements.push({
type: types_1.ElementType.VARIABLE,
value: char,
id: (0, dom_1.generateId)()
});
currentIndex++;
continue;
}
// 解析运算符
if (['+', '-', '×', '÷', '*', '/', '='].includes(char)) {
elements.push({
type: types_1.ElementType.OPERATOR,
value: char,
id: (0, dom_1.generateId)()
});
currentIndex++;
continue;
}
// 解析括号
if (['(', ')', '[', ']', '{', '}'].includes(char)) {
elements.push({
type: types_1.ElementType.BRACKET,
value: char,
id: (0, dom_1.generateId)()
});
currentIndex++;
continue;
}
// 解析上标、下标
if (char === '^') {
const lastElement = elements[elements.length - 1];
currentIndex++;
// 找到上标内容
let superscriptContent = '';
if (formula[currentIndex] === '{') {
// 大括号中的内容作为一个整体
currentIndex++;
let braceCount = 1;
while (currentIndex < formula.length && braceCount > 0) {
if (formula[currentIndex] === '{')
braceCount++;
if (formula[currentIndex] === '}')
braceCount--;
if (braceCount > 0) {
superscriptContent += formula[currentIndex];
}
currentIndex++;
}
}
else {
// 单个字符作为上标
superscriptContent = formula[currentIndex];
currentIndex++;
}
if (lastElement) {
const superscriptElement = {
type: types_1.ElementType.SUPERSCRIPT,
value: superscriptContent,
id: (0, dom_1.generateId)()
};
if (!lastElement.children) {
lastElement.children = [];
}
lastElement.children.push(superscriptElement);
}
continue;
}
// 下标处理 (使用 _)
if (char === '_') {
const lastElement = elements[elements.length - 1];
currentIndex++;
// 找到下标内容
let subscriptContent = '';
if (formula[currentIndex] === '{') {
// 大括号中的内容作为一个整体
currentIndex++;
let braceCount = 1;
while (currentIndex < formula.length && braceCount > 0) {
if (formula[currentIndex] === '{')
braceCount++;
if (formula[currentIndex] === '}')
braceCount--;
if (braceCount > 0) {
subscriptContent += formula[currentIndex];
}
currentIndex++;
}
}
else {
// 单个字符作为下标
subscriptContent = formula[currentIndex];
currentIndex++;
}
if (lastElement) {
const subscriptElement = {
type: types_1.ElementType.SUBSCRIPT,
value: subscriptContent,
id: (0, dom_1.generateId)()
};
if (!lastElement.children) {
lastElement.children = [];
}
lastElement.children.push(subscriptElement);
}
continue;
}
// 其他符号当作普通符号处理
elements.push({
type: types_1.ElementType.SYMBOL,
value: char,
id: (0, dom_1.generateId)()
});
currentIndex++;
}
return elements;
}
/**
* 将公式元素树转换为字符串
* @param elements 公式元素树
* @returns 公式字符串
*/
static stringify(elements) {
let result = '';
elements.forEach(element => {
switch (element.type) {
case types_1.ElementType.NUMBER:
case types_1.ElementType.VARIABLE:
case types_1.ElementType.SYMBOL:
case types_1.ElementType.OPERATOR:
case types_1.ElementType.BRACKET:
result += element.value;
break;
case types_1.ElementType.FUNCTION:
result += element.value;
break;
default:
result += element.value;
}
// 处理子元素
if (element.children && element.children.length > 0) {
element.children.forEach(child => {
switch (child.type) {
case types_1.ElementType.SUPERSCRIPT:
result += `^{${child.value}}`;
break;
case types_1.ElementType.SUBSCRIPT:
result += `_{${child.value}}`;
break;
default:
// 其他类型的子元素,可以根据需要添加处理
break;
}
});
}
});
return result;
}
}
exports.FormulaParser = FormulaParser;
//# sourceMappingURL=parser.js.map