123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266 |
- /*!
- * ====================================================
- * kityformula-editor - v1.0.0 - 2014-04-03
- * https://github.com/HanCong03/kityformula-editor
- * GitHub: https://github.com/kitygraph/kityformula-editor.git
- * Copyright (c) 2014 Baidu Kity Group; Licensed MIT
- * ====================================================
- */
- (function () {
- /**
- * cmd 内部定义
- * build用
- */
- // 模块存储
- var _modules = {};
- function define ( id, deps, factory ) {
- _modules[ id ] = {
- exports: {},
- value: null,
- factory: null
- };
- if ( arguments.length === 2 ) {
- factory = deps;
- }
- if ( _modules.toString.call( factory ) === '[object Object]' ) {
- _modules[ id ][ 'value' ] = factory;
- } else if ( typeof factory === 'function' ) {
- _modules[ id ][ 'factory' ] = factory;
- } else {
- throw new Error( 'define函数未定义的行为' );
- }
- }
- function require ( id ) {
- var module = _modules[ id ],
- exports = null;
- if ( !module ) {
- return null;
- }
- if ( module.value ) {
- return module.value;
- }
- exports = module.factory.call( null, require, module.exports, module );
- // return 值不为空, 则以return值为最终值
- if ( exports ) {
- module.exports = exports;
- }
- module.value = module.exports;
- return module.value;
- }
- function use ( id ) {
- return require( id );
- }
- /*!
- * 装配器
- */
- define("assembly", [], function(require, exports, module) {
- var CONSTRUCT_MAPPING = {}, CURSOR_CHAR = "";
- function Assembly(container, config) {
- this.formula = new kf.Formula(container, config);
- }
- Assembly.prototype.generateBy = function(data) {
- var tree = data.tree, objTree = {}, selectInfo = {}, mapping = {};
- if (typeof tree === "string") {
- objTree = new kf.TextExpression(tree);
- this.formula.appendExpression(objTree);
- } else {
- this.formula.appendExpression(generateExpression(tree, deepCopy(tree), objTree, mapping, selectInfo));
- return {
- select: selectInfo,
- parsedTree: tree,
- tree: objTree,
- mapping: mapping
- };
- }
- };
- Assembly.prototype.regenerateBy = function(data) {
- this.formula.clearExpressions();
- return this.generateBy(data);
- };
- /**
- * 根据提供的树信息生成表达式
- * @param tree 中间格式的解析树
- * @return {kf.Expression} 生成的表达式
- */
- function generateExpression(originTree, tree, objTree, mapping, selectInfo) {
- var currentOperand = null, exp = null, // 记录光标位置
- cursorLocation = [], operand = tree.operand || [], constructor = null, constructorProxy;
- objTree.operand = [];
- // 文本表达式已经不需要再处理了
- if (tree.name.indexOf("text") === -1) {
- // 处理操作数
- for (var i = 0, len = operand.length; i < len; i++) {
- currentOperand = operand[i];
- //TODO 光标定位, 配合编辑器, 后期应该考虑是否有更佳的方案来实现
- if (currentOperand === CURSOR_CHAR) {
- cursorLocation.push(i);
- if (!selectInfo.hasOwnProperty("startOffset")) {
- // 字符串中的开始偏移是需要修正的
- selectInfo.startOffset = i;
- }
- selectInfo.endOffset = i;
- if (tree.attr && tree.attr.id) {
- selectInfo.groupId = tree.attr.id;
- }
- continue;
- }
- if (!currentOperand) {
- operand[i] = createObject("empty");
- objTree.operand.push(operand[i]);
- } else if (typeof currentOperand === "string") {
- // 括号表达式不能对前2个参数做处理, 这两个参数是代表括号类型
- if (tree.name === "brackets" && i < 2) {
- operand[i] = currentOperand;
- } else {
- operand[i] = createObject("text", currentOperand);
- }
- objTree.operand.push(operand[i]);
- } else {
- objTree.operand.push({});
- operand[i] = arguments.callee(originTree.operand[i], currentOperand, objTree.operand[objTree.operand.length - 1], mapping, selectInfo);
- }
- }
- while (i = cursorLocation.length) {
- i = cursorLocation[i - 1];
- operand.splice(i, 1);
- cursorLocation.length--;
- originTree.operand.splice(i, 1);
- }
- }
- constructor = getConstructor(tree.name);
- if (!constructor) {
- throw new Error("operator type error: not found " + tree.operator);
- }
- constructorProxy = function() {};
- constructorProxy.prototype = constructor.prototype;
- exp = new constructorProxy();
- constructor.apply(exp, operand);
- objTree.func = exp;
- // 调用配置函数
- for (var fn in tree.callFn) {
- if (!tree.callFn.hasOwnProperty(fn) || !exp[fn]) {
- continue;
- }
- exp[fn].apply(exp, tree.callFn[fn]);
- }
- if (tree.attr) {
- if (tree.attr.id) {
- mapping[tree.attr.id] = {
- objGroup: exp,
- strGroup: originTree
- };
- }
- exp.setAttr(tree.attr);
- }
- return exp;
- }
- function createObject(type, value) {
- switch (type) {
- case "empty":
- return new kf.EmptyExpression();
- case "text":
- return new kf.TextExpression(value);
- }
- }
- /**
- * 根据操作符获取对应的构造器
- */
- function getConstructor(name) {
- return CONSTRUCT_MAPPING[name] || kf[name.replace(/^[a-z]/i, function(match) {
- return match.toUpperCase();
- }).replace(/-([a-z])/gi, function(match, char) {
- return char.toUpperCase();
- }) + "Expression"];
- }
- function deepCopy(source) {
- var target = {};
- if ({}.toString.call(source) === "[object Array]") {
- target = [];
- for (var i = 0, len = source.length; i < len; i++) {
- target[i] = doCopy(source[i]);
- }
- } else {
- for (var key in source) {
- if (!source.hasOwnProperty(key)) {
- continue;
- }
- target[key] = doCopy(source[key]);
- }
- }
- return target;
- }
- function doCopy(source) {
- if (!source) {
- return source;
- }
- if (typeof source !== "object") {
- return source;
- }
- return deepCopy(source);
- }
- return {
- use: function(container, config) {
- return new Assembly(container, config);
- }
- };
- });
- /**
- * latex实现工具包
- */
- define("impl/latex/base/latex-utils", [ "impl/latex/base/rpn", "impl/latex/base/utils", "impl/latex/define/type", "impl/latex/base/tree", "impl/latex/handler/combination" ], function(require, exports, module) {
- return {
- toRPNExpression: require("impl/latex/base/rpn"),
- generateTree: require("impl/latex/base/tree")
- };
- });
- /**
- * 逆波兰表达式转换函数
- */
- define("impl/latex/base/rpn", [ "impl/latex/base/utils", "impl/latex/define/operator", "impl/latex/define/func", "impl/latex/handler/func", "impl/latex/define/type" ], function(require) {
- var Utils = require("impl/latex/base/utils");
- return function(units) {
- var signStack = [], TYPE = require("impl/latex/define/type"), currentUnit = null;
- // 先处理函数
- units = processFunction(units);
- while (currentUnit = units.shift()) {
- // 移除brackets中外层包裹的combination节点
- if (currentUnit.name === "combination" && currentUnit.operand.length === 1 && currentUnit.operand[0].name === "brackets") {
- currentUnit = currentUnit.operand[0];
- }
- if (Utils.isArray(currentUnit)) {
- signStack.push(arguments.callee(currentUnit));
- continue;
- }
- signStack.push(currentUnit);
- }
- // 要处理brackets被附加的包裹元素
- return signStack;
- };
- /**
- * “latex函数”处理器
- * @param units 单元组
- * @returns {Array} 处理过后的单元组
- */
- function processFunction(units) {
- var processed = [], currentUnit = null;
- while ((currentUnit = units.pop()) !== undefined) {
- if (currentUnit && typeof currentUnit === "object" && currentUnit.sign === false) {
- // 预先处理不可作为独立符号的函数
- var tt = currentUnit.handler(currentUnit, [], processed.reverse());
- processed.unshift(tt);
- processed.reverse();
- } else {
- processed.push(currentUnit);
- }
- }
- return processed.reverse();
- }
- });
- /**
- * 从单元组构建树
- */
- define("impl/latex/base/tree", [ "impl/latex/define/type", "impl/latex/handler/combination", "impl/latex/base/utils", "impl/latex/define/operator", "impl/latex/define/func", "impl/latex/handler/func" ], function(require) {
- var TYPE = require("impl/latex/define/type"), mergeHandler = require("impl/latex/handler/combination"), Utils = require("impl/latex/base/utils");
- return function(units) {
- var currentUnit = null, nextUnit = null, tree = [];
- for (var i = 0, len = units.length; i < len; i++) {
- if (Utils.isArray(units[i])) {
- units[i] = arguments.callee(units[i]);
- }
- }
- while (currentUnit = units.shift()) {
- if (typeof currentUnit === "object" && currentUnit.handler) {
- // 后操作数
- tree.push(currentUnit.handler(currentUnit, tree, units));
- } else {
- tree.push(currentUnit);
- }
- }
- return mergeHandler(tree);
- };
- });
- /**
- * 通用工具包
- */
- define("impl/latex/base/utils", [ "impl/latex/define/operator", "impl/latex/handler/script", "impl/latex/handler/func", "impl/latex/define/type", "impl/latex/handler/fraction", "impl/latex/handler/sqrt", "impl/latex/handler/summation", "impl/latex/handler/integration", "impl/latex/handler/brackets", "impl/latex/define/func", "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
- var OPERATOR_LIST = require("impl/latex/define/operator"), FUNCTION_LIST = require("impl/latex/define/func"), FUNCTION_HANDLER = require("impl/latex/handler/func"), Utils = {
- // 根据输入的latex字符串, 检测出该字符串所对应的kf的类型
- getLatexType: function(str) {
- str = str.replace(/^\\/, "");
- // 操作符
- if (OPERATOR_LIST[str]) {
- return "operator";
- }
- if (FUNCTION_LIST[str]) {
- return "function";
- }
- return "text";
- },
- isArray: function(obj) {
- return obj && Object.prototype.toString.call(obj) === "[object Array]";
- },
- getDefine: function(str) {
- return Utils.extend({}, OPERATOR_LIST[str.replace("\\", "")]);
- },
- getFuncDefine: function(str) {
- return {
- name: "function",
- params: str.replace(/^\\/, ""),
- handler: FUNCTION_HANDLER
- };
- },
- getBracketsDefine: function(leftBrackets, rightBrackets) {
- return Utils.extend({
- params: [ leftBrackets, rightBrackets ]
- }, OPERATOR_LIST["brackets"]);
- },
- extend: function(target, sources) {
- for (var key in sources) {
- if (sources.hasOwnProperty(key)) {
- target[key] = sources[key];
- }
- }
- return target;
- }
- };
- return Utils;
- });
- /**
- * 定义括号类型, 对于属于括号类型的符号或表达式, 则可以应用brackets函数处理
- */
- define("impl/latex/define/brackets", [], function(require, exports, module) {
- var t = true;
- return {
- ".": t,
- "{": t,
- "}": t,
- "[": t,
- "]": t,
- "(": t,
- ")": t,
- "|": t
- };
- });
- /**
- * 函数列表
- */
- define("impl/latex/define/func", [], function(require, exports, module) {
- return {
- sin: 1,
- cos: 1,
- arccos: 1,
- cosh: 1,
- det: 1,
- inf: 1,
- limsup: 1,
- Pr: 1,
- tan: 1,
- arcsin: 1,
- cot: 1,
- dim: 1,
- ker: 1,
- ln: 1,
- sec: 1,
- tanh: 1,
- arctan: 1,
- coth: 1,
- exp: 1,
- lg: 1,
- log: 1,
- arg: 1,
- csc: 1,
- gcd: 1,
- lim: 1,
- max: 1,
- sinh: 1,
- cos: 1,
- deg: 1,
- hom: 1,
- liminf: 1,
- min: 1,
- sup: 1
- };
- });
- /**
- * 操作符列表
- */
- define("impl/latex/define/operator", [ "impl/latex/handler/script", "impl/latex/handler/func", "impl/latex/handler/lib/int-extract", "impl/latex/define/type", "impl/latex/handler/fraction", "impl/latex/handler/sqrt", "impl/latex/handler/summation", "impl/latex/handler/integration", "impl/latex/handler/brackets", "impl/latex/define/brackets" ], function(require, exports, module) {
- var scriptHandler = require("impl/latex/handler/script"), funcHandler = require("impl/latex/handler/func"), TYPE = require("impl/latex/define/type");
- return {
- "^": {
- name: "superscript",
- type: TYPE.OP,
- handler: scriptHandler
- },
- _: {
- name: "subscript",
- type: TYPE.OP,
- handler: scriptHandler
- },
- frac: {
- name: "fraction",
- type: TYPE.FN,
- sign: false,
- handler: require("impl/latex/handler/fraction")
- },
- sqrt: {
- name: "radical",
- type: TYPE.FN,
- sign: false,
- handler: require("impl/latex/handler/sqrt")
- },
- sum: {
- name: "summation",
- type: TYPE.FN,
- traversal: "rtl",
- handler: require("impl/latex/handler/summation")
- },
- "int": {
- name: "integration",
- type: TYPE.FN,
- traversal: "rtl",
- handler: require("impl/latex/handler/integration")
- },
- brackets: {
- name: "brackets",
- type: "TYPE.FN",
- handler: require("impl/latex/handler/brackets")
- }
- };
- });
- /**
- * 预处理器列表
- */
- define("impl/latex/define/pre", [ "impl/latex/pre/sqrt", "impl/latex/pre/int" ], function(require, exports, module) {
- return {
- // 方根预处理器
- sqrt: require("impl/latex/pre/sqrt"),
- // 积分预处理器
- "int": require("impl/latex/pre/int")
- };
- });
- /*!
- * 逆解析对照表
- */
- define("impl/latex/define/reverse", [ "impl/latex/reverse/combination", "impl/latex/reverse/fraction", "impl/latex/reverse/func", "impl/latex/reverse/integration", "impl/latex/reverse/subscript", "impl/latex/reverse/superscript", "impl/latex/reverse/script", "impl/latex/reverse/sqrt", "impl/latex/reverse/summation", "impl/latex/reverse/brackets" ], function(require) {
- return {
- combination: require("impl/latex/reverse/combination"),
- fraction: require("impl/latex/reverse/fraction"),
- "function": require("impl/latex/reverse/func"),
- integration: require("impl/latex/reverse/integration"),
- subscript: require("impl/latex/reverse/subscript"),
- superscript: require("impl/latex/reverse/superscript"),
- script: require("impl/latex/reverse/script"),
- radical: require("impl/latex/reverse/sqrt"),
- summation: require("impl/latex/reverse/summation"),
- brackets: require("impl/latex/reverse/brackets")
- };
- });
- /**
- * 操作符类型定义
- */
- define("impl/latex/define/type", [], function(require, exports, module) {
- return {
- OP: 1,
- FN: 2
- };
- });
- /*!
- * 括号处理器
- */
- define("impl/latex/handler/brackets", [ "impl/latex/define/brackets" ], function(require, exports, module) {
- var BRACKETS_TYPE = require("impl/latex/define/brackets");
- return function(info, processedStack, unprocessedStack) {
- // 括号验证
- for (var i = 0, len = info.params.length; i < len; i++) {
- if (!(info.params[i] in BRACKETS_TYPE)) {
- throw new Error("Brackets: invalid params");
- }
- }
- info.operand = info.params;
- info.params[2] = unprocessedStack.shift();
- delete info.handler;
- delete info.params;
- return info;
- };
- });
- /*!
- * 合并处理(特殊处理函数)
- */
- define("impl/latex/handler/combination", [], function(require, exports, module) {
- return function() {
- if (arguments[0].length === 0) {
- return null;
- }
- return {
- name: "combination",
- operand: arguments[0]
- };
- };
- });
- /*!
- * 分数函数处理器
- */
- define("impl/latex/handler/fraction", [], function(require, exports, module) {
- // 处理函数接口
- return function(info, processedStack, unprocessedStack) {
- var numerator = unprocessedStack.shift(), // 分子
- denominator = unprocessedStack.shift();
- // 分母
- if (numerator === undefined || denominator === undefined) {
- throw new Error("Frac: Syntax Error");
- }
- info.operand = [ numerator, denominator ];
- delete info.handler;
- return info;
- };
- });
- /*!
- * 函数表达式处理器
- */
- define("impl/latex/handler/func", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
- var extractFn = require("impl/latex/handler/lib/int-extract");
- // 处理函数接口
- return function(info, processedStack, unprocessedStack) {
- var params = extractFn(unprocessedStack);
- info.operand = [ info.params, params.exp, params.sup, params.sub ];
- delete info.params;
- delete info.handler;
- return info;
- };
- });
- /*!
- * 积分函数处理器
- */
- define("impl/latex/handler/integration", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
- var extractFn = require("impl/latex/handler/lib/int-extract");
- return function(info, processedStack, unprocessedStack) {
- var count = unprocessedStack.shift(), params = extractFn(unprocessedStack);
- info.operand = [ params.exp, params.sup, params.sub ];
- // 参数配置调用
- info.callFn = {
- setType: [ count | 0 ]
- };
- delete info.handler;
- return info;
- };
- });
- /**
- * 积分参数提取函数
- */
- define("impl/latex/handler/lib/int-extract", [], function(require, exports, module) {
- return function(units) {
- var sup = units.shift() || null, sub = null, exp = null;
- if (sup !== null) {
- if (typeof sup === "string") {
- exp = sup;
- sup = null;
- } else {
- if (sup.name === "superscript") {
- sup = units.shift() || null;
- if (sup) {
- sub = units.shift() || null;
- if (sub) {
- if (sub.name === "subscript") {
- sub = units.shift() || null;
- exp = units.shift() || null;
- } else {
- exp = sub;
- sub = null;
- }
- }
- }
- } else if (sup.name === "subscript") {
- sub = units.shift() || null;
- if (sub) {
- sup = units.shift() || null;
- if (sup) {
- if (sup.name === "superscript") {
- sup = units.shift() || null;
- exp = units.shift() || null;
- } else {
- exp = sup;
- sup = null;
- }
- }
- }
- } else {
- exp = sup;
- sup = null;
- }
- }
- }
- return {
- sub: sub,
- sup: sup,
- exp: exp
- };
- };
- });
- /*!
- * 上下标操作符函数处理
- */
- define("impl/latex/handler/script", [], function(require, exports, module) {
- // 处理函数接口
- return function(info, processedStack, unprocessedStack) {
- var base = processedStack.pop(), script = unprocessedStack.shift() || null;
- if (!script) {
- throw new Error("Missing script");
- }
- base = base || "";
- if (base.name === info.name || base.name === "script") {
- throw new Error("script error");
- }
- // 执行替换
- if (base.name === "subscript") {
- base.name = "script";
- base.operand[2] = base.operand[1];
- base.operand[1] = script;
- return base;
- } else if (base.name === "superscript") {
- base.name = "script";
- base.operand[2] = script;
- return base;
- }
- info.operand = [ base, script ];
- // 删除处理器
- delete info.handler;
- return info;
- };
- });
- /*!
- * 方根函数处理器
- */
- define("impl/latex/handler/sqrt", [], function(require, exports, module) {
- // 处理函数接口
- return function(info, processedStack, unprocessedStack) {
- var exponent = unprocessedStack.shift(), // 被开方数
- radicand = unprocessedStack.shift();
- info.operand = [ radicand, exponent ];
- delete info.handler;
- return info;
- };
- });
- /*!
- * 求和函数处理器
- */
- define("impl/latex/handler/summation", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
- var extractFn = require("impl/latex/handler/lib/int-extract");
- return function(info, processedStack, unprocessedStack) {
- var params = extractFn(unprocessedStack);
- info.operand = [ params.exp, params.sup, params.sub ];
- delete info.handler;
- return info;
- };
- });
- /**
- * Kity Formula Latex解析器实现
- */
- define("impl/latex/latex", [ "parser", "impl/latex/base/latex-utils", "impl/latex/base/rpn", "impl/latex/base/tree", "impl/latex/define/pre", "impl/latex/pre/sqrt", "impl/latex/pre/int", "impl/latex/serialization", "impl/latex/define/reverse", "impl/latex/define/operator", "impl/latex/handler/script", "impl/latex/handler/func", "impl/latex/define/type", "impl/latex/handler/fraction", "impl/latex/handler/sqrt", "impl/latex/handler/summation", "impl/latex/handler/integration", "impl/latex/handler/brackets", "impl/latex/reverse/combination", "impl/latex/reverse/fraction", "impl/latex/reverse/func", "impl/latex/reverse/integration", "impl/latex/reverse/subscript", "impl/latex/reverse/superscript", "impl/latex/reverse/script", "impl/latex/reverse/sqrt", "impl/latex/reverse/summation", "impl/latex/reverse/brackets", "impl/latex/base/utils", "impl/latex/define/func" ], function(require, exports, module) {
- var Parser = require("parser").Parser, LatexUtils = require("impl/latex/base/latex-utils"), PRE_HANDLER = require("impl/latex/define/pre"), serialization = require("impl/latex/serialization"), OP_DEFINE = require("impl/latex/define/operator"), REVERSE_DEFINE = require("impl/latex/define/reverse"), Utils = require("impl/latex/base/utils");
- // data
- var leftChar = "", rightChar = "", clearCharPattern = new RegExp(leftChar + "|" + rightChar, "g"), leftCharPattern = new RegExp(leftChar, "g"), rightCharPattern = new RegExp(rightChar, "g");
- Parser.register("latex", Parser.implement({
- parse: function(data) {
- var units = this.split(this.format(data));
- units = this.parseToGroup(units);
- units = this.parseToStruct(units);
- return this.generateTree(units);
- },
- serialization: function(tree, options) {
- return serialization(tree, options);
- },
- expand: function(expandObj) {
- var parseObj = expandObj.parse, formatKey = null, preObj = expandObj.pre, reverseObj = expandObj.reverse;
- for (var key in parseObj) {
- if (!parseObj.hasOwnProperty(key)) {
- continue;
- }
- formatKey = key.replace(/\\/g, "");
- OP_DEFINE[formatKey] = parseObj[key];
- }
- for (var key in reverseObj) {
- if (!reverseObj.hasOwnProperty(key)) {
- continue;
- }
- REVERSE_DEFINE[key.replace(/\\/g, "")] = reverseObj[key];
- }
- // 预处理
- if (preObj) {
- for (var key in preObj) {
- if (!preObj.hasOwnProperty(key)) {
- continue;
- }
- PRE_HANDLER[key.replace(/\\/g, "")] = preObj[key];
- }
- }
- },
- // 格式化输入数据
- format: function(input) {
- // 清理多余的空格
- input = clearEmpty(input);
- // 处理输入的“{”和“}”
- input = input.replace(clearCharPattern, "").replace(/\\{/gi, leftChar).replace(/\\}/gi, rightChar);
- // 预处理器处理
- for (var key in PRE_HANDLER) {
- if (PRE_HANDLER.hasOwnProperty(key)) {
- input = PRE_HANDLER[key](input);
- }
- }
- return input;
- },
- split: function(data) {
- var units = [], pattern = /(?:\\[a-z]+\s*)|(?:[{}]\s*)|(?:[^\\{}]\s*)/gi, emptyPattern = /^\s+|\s+$/g, match = null;
- data = data.replace(emptyPattern, "");
- while (match = pattern.exec(data)) {
- match = match[0].replace(emptyPattern, "");
- if (match) {
- units.push(match);
- }
- }
- return units;
- },
- /**
- * 根据解析出来的语法单元生成树
- * @param units 单元
- * @return 生成的树对象
- */
- generateTree: function(units) {
- var tree = [], currentUnit = null;
- // 递归处理
- while (currentUnit = units.shift()) {
- if (Utils.isArray(currentUnit)) {
- tree.push(this.generateTree(currentUnit));
- } else {
- tree.push(currentUnit);
- }
- }
- tree = LatexUtils.toRPNExpression(tree);
- return LatexUtils.generateTree(tree);
- },
- parseToGroup: function(units) {
- var group = [], groupStack = [ group ], groupCount = 0, bracketsCount = 0;
- for (var i = 0, len = units.length; i < len; i++) {
- switch (units[i]) {
- case "{":
- groupCount++;
- groupStack.push(group);
- group.push([]);
- group = group[group.length - 1];
- break;
- case "}":
- groupCount--;
- group = groupStack.pop();
- break;
- // left-right分组
- case "\\left":
- bracketsCount++;
- groupStack.push(group);
- // 进入两层
- group.push([ [] ]);
- group = group[group.length - 1][0];
- group.type = "brackets";
- // 读取左括号
- i++;
- group.leftBrackets = units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}");
- break;
- case "\\right":
- bracketsCount--;
- // 读取右括号
- i++;
- group.rightBrackets = units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}");
- group = groupStack.pop();
- break;
- default:
- group.push(units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}"));
- break;
- }
- }
- if (groupCount !== 0) {
- throw new Error("Group Error!");
- }
- if (bracketsCount !== 0) {
- throw new Error("Brackets Error!");
- }
- return groupStack[0];
- },
- parseToStruct: function(units) {
- var structs = [];
- for (var i = 0, len = units.length; i < len; i++) {
- if (Utils.isArray(units[i])) {
- if (units[i].type === "brackets") {
- // 处理自动调整大小的括号组
- // 获取括号组定义
- structs.push(Utils.getBracketsDefine(units[i].leftBrackets, units[i].rightBrackets));
- // 处理内部表达式
- structs.push(this.parseToStruct(units[i]));
- } else {
- // 普通组
- structs.push(this.parseToStruct(units[i]));
- }
- } else {
- structs.push(parseStruct(units[i]));
- }
- }
- return structs;
- }
- }));
- /**
- * 把序列化的字符串表示法转化为中间格式的结构化表示
- */
- function parseStruct(str) {
- var type = Utils.getLatexType(str);
- switch (type) {
- case "operator":
- return Utils.getDefine(str);
- case "function":
- return Utils.getFuncDefine(str);
- default:
- // text
- return transformSpecialCharacters(str);
- }
- }
- // 转换特殊的文本字符
- function transformSpecialCharacters(char) {
- if (char.indexOf("\\") === 0) {
- return char + "\\";
- }
- return char;
- }
- function clearEmpty(data) {
- return data.replace(/\\\s+/, "").replace(/\s*([^a-z0-9\s])\s*/gi, function(match, symbol) {
- return symbol;
- });
- }
- });
- /**
- * “开方”预处理器
- */
- define("impl/latex/pre/int", [], function(require) {
- return function(input) {
- return input.replace(/\\(i+)nt(\b|[^a-zA-Z])/g, function(match, sign, suffix) {
- return "\\int " + sign.length + suffix;
- });
- };
- });
- /**
- * “开方”预处理器
- */
- define("impl/latex/pre/sqrt", [], function(require) {
- return function(input) {
- return input.replace(/\\sqrt\s*((?:\[[^\]]*\])?)/g, function(match, exponent) {
- return "\\sqrt{" + exponent.replace(/^\[|\]$/g, "") + "}";
- });
- };
- });
- /*!
- * 逆解析处理函数: brackets
- */
- define("impl/latex/reverse/brackets", [], function() {
- /**
- * operands中元素对照表
- * 0: 左符号
- * 1: 右符号
- * 2: 表达式
- */
- return function(operands) {
- return [ "\\left", operands[0], operands[2], "\\right", operands[1] ].join(" ");
- };
- });
- /*!
- * 逆解析处理函数:combination
- */
- define("impl/latex/reverse/combination", [], function() {
- var pattern = new RegExp("", "g");
- return function(operands, options) {
- if (this.attr["data-root"] || this.attr["data-placeholder"]) {
- return operands.join("");
- }
- return "{" + operands.join("") + "}";
- };
- });
- /*!
- * 逆解析处理函数: fraction
- */
- define("impl/latex/reverse/fraction", [], function() {
- return function(operands) {
- return "\\frac " + operands[0] + " " + operands[1];
- };
- });
- /*!
- * 逆解析处理函数: func
- */
- define("impl/latex/reverse/func", [], function() {
- /**
- * operands中元素对照表
- * 0: 函数名
- * 1: 表达式
- * 2: 上标
- * 3: 下标
- */
- return function(operands) {
- var result = [ "\\" + operands[0] ];
- // 上标
- if (operands[2]) {
- result.push("^" + operands[2]);
- }
- // 下标
- if (operands[3]) {
- result.push("_" + operands[3]);
- }
- result.push(" " + operands[1]);
- return result.join("");
- };
- });
- /*!
- * 逆解析处理函数: integration
- */
- define("impl/latex/reverse/integration", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 上标
- * 2: 下标
- */
- return function(operands) {
- var result = [ "\\int" ];
- // 上标
- if (operands[1]) {
- result.push("^" + operands[1]);
- }
- // 下标
- if (operands[2]) {
- result.push("_" + operands[2]);
- }
- result.push(" " + operands[0]);
- return operands.join("");
- };
- });
- /*!
- * 逆解析处理函数: script
- */
- define("impl/latex/reverse/script", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 上标
- * 2: 下标
- */
- return function(operands) {
- return operands[0] + "^" + operands[1] + "_" + operands[2];
- };
- });
- /*!
- * 逆解析处理函数: sqrt
- */
- define("impl/latex/reverse/sqrt", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 指数
- */
- return function(operands) {
- var result = [ "\\sqrt" ];
- // 上标
- if (operands[1]) {
- result.push("[" + operands[1] + "]");
- }
- result.push(" " + operands[0]);
- return result.join("");
- };
- });
- /*!
- * 逆解析处理函数: subscript
- */
- define("impl/latex/reverse/subscript", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 下标
- */
- return function(operands) {
- return operands[0] + "_" + operands[1];
- };
- });
- /*!
- * 逆解析处理函数: summation
- */
- define("impl/latex/reverse/summation", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 上标
- * 2: 下标
- */
- return function(operands) {
- var result = [ "\\sum" ];
- // 上标
- if (operands[1]) {
- result.push("^" + operands[1]);
- }
- // 下标
- if (operands[2]) {
- result.push("_" + operands[2]);
- }
- result.push(" " + operands[0]);
- return result.join("");
- };
- });
- /*!
- * 逆解析处理函数: superscript
- */
- define("impl/latex/reverse/superscript", [], function() {
- /**
- * operands中元素对照表
- * 0: 表达式
- * 1: 上标
- */
- return function(operands) {
- return operands[0] + "^" + operands[1];
- };
- });
- /**
- * Created by hn on 14-3-20.
- */
- define("impl/latex/serialization", [ "impl/latex/define/reverse", "impl/latex/reverse/combination", "impl/latex/reverse/fraction", "impl/latex/reverse/func", "impl/latex/reverse/integration", "impl/latex/reverse/subscript", "impl/latex/reverse/superscript", "impl/latex/reverse/script", "impl/latex/reverse/sqrt", "impl/latex/reverse/summation", "impl/latex/reverse/brackets" ], function(require) {
- var reverseHandlerTable = require("impl/latex/define/reverse"), specialCharPattern = /(\\[\w]+)\\/g;
- return function(tree, options) {
- return reverseParse(tree, options);
- };
- function reverseParse(tree, options) {
- var operands = [], originalOperands = null;
- // 字符串处理, 需要处理特殊字符
- if (typeof tree !== "object") {
- return tree.replace(specialCharPattern, function(match, group) {
- return group + " ";
- });
- }
- // combination需要特殊处理, 重复嵌套的combination节点要删除
- if (tree.name === "combination" && tree.operand.length === 1 && tree.operand[0].name === "combination") {
- tree = tree.operand[0];
- }
- originalOperands = tree.operand;
- for (var i = 0, len = originalOperands.length; i < len; i++) {
- if (originalOperands[i]) {
- operands.push(reverseParse(originalOperands[i]));
- } else {
- operands.push(originalOperands[i]);
- }
- }
- return reverseHandlerTable[tree.name].call(tree, operands, options);
- }
- });
- /*!
- * Kity Formula 公式表示法Parser接口
- */
- define("parser", [], function(require, exports, module) {
- // Parser 配置列表
- var CONF = {}, IMPL_POLL = {}, // 内部简单工具类
- Utils = {
- extend: function(target, sources) {
- var source = null;
- sources = [].slice.call(arguments, 1);
- for (var i = 0, len = sources.length; i < len; i++) {
- source = sources[i];
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- target[key] = source[key];
- }
- }
- }
- },
- setData: function(container, key, value) {
- if (typeof key === "string") {
- container[key] = value;
- } else if (typeof key === "object") {
- for (value in key) {
- if (key.hasOwnProperty(value)) {
- container[value] = key[value];
- }
- }
- } else {
- // 配置项类型错误
- throw new Error("invalid option");
- }
- }
- };
- /**
- * 解析器
- */
- var Parser = {
- use: function(type) {
- if (!IMPL_POLL[type]) {
- throw new Error("unknown parser type");
- }
- return this.proxy(IMPL_POLL[type]);
- },
- config: function(key, value) {
- Utils.setData(CONF, key, value);
- return this;
- },
- /**
- * 注册解析器实现
- * @param type 解析器所属类型
- * @param parserImpl 解析器实现
- */
- register: function(type, parserImpl) {
- IMPL_POLL[type.toLowerCase()] = parserImpl;
- return this;
- },
- // 提供构造器的实现的默认结构
- implement: function(parser) {
- var impl = function() {}, constructor = parser.constructor || function() {}, result = function() {
- ParserInterface.call(this);
- constructor.call(this);
- };
- impl.prototype = ParserInterface.prototype;
- result.prototype = new impl();
- delete parser.constructor;
- for (var key in parser) {
- if (key !== "constructor" && parser.hasOwnProperty(key)) {
- result.prototype[key] = parser[key];
- }
- }
- return result;
- },
- /**
- * 代理给定的parser实现
- * @private
- * @param parserImpl 需代理的parser实现
- */
- proxy: function(parserImpl) {
- return new ParserProxy(parserImpl);
- }
- };
- /**
- * parser实现的代理对象, 所有实现均通过该代理对象对外提供统一接口
- * @constructor
- * @param parserImpl 需代理的对象
- */
- function ParserProxy(parserImpl) {
- this.impl = new parserImpl();
- this.conf = {};
- }
- Utils.extend(ParserProxy.prototype, {
- config: function(key, value) {
- Utils.setData(this.conf, key, value);
- },
- /**
- * 设置特定解析器实现所需的配置项,参数也可以是一个Key-Value Mapping
- * @param key 配置项名称
- * @param value 配置项值
- */
- set: function(key, value) {
- this.impl.set(key, value);
- },
- parse: function(data) {
- var result = {
- config: {},
- // 调用实现获取解析树
- tree: this.impl.parse(data)
- };
- Utils.extend(result.config, CONF, this.conf);
- return result;
- },
- serialization: function(tree, options) {
- return this.impl.serialization(tree, options);
- },
- expand: function(obj) {
- this.impl.expand(obj);
- }
- });
- /**
- * 解析器所需实现的接口
- * @constructor
- */
- function ParserInterface() {
- this.conf = {};
- }
- Utils.extend(ParserInterface.prototype, {
- set: function(key, value) {
- Utils.extend(this.conf, key, value);
- },
- /**
- * 需要特定解析器实现, 该方法是解析器的核心方法,解析器的实现者应该完成该方法对给定数据进行解析
- * @param data 待解析的数据
- * @return 解析树, 具体格式庆参考Kity Formula Parser 的文档
- */
- parse: function(data) {
- throw new Error("Abstract function");
- }
- });
- // exports
- module.exports = {
- Parser: Parser,
- ParserInterface: ParserInterface
- };
- });
- /**
- * 模块暴露
- */
- ( function ( global ) {
- define( 'kf.start', function ( require ) {
- var Parser = require( "parser" ).Parser;
- // 初始化组件
- require( "impl/latex/latex" );
- global.kf.Parser = Parser;
- global.kf.Assembly = require( "assembly" );
- } );
- // build环境中才含有use
- try {
- use( 'kf.start' );
- } catch ( e ) {
- }
- } )( this );
- })();
|