kityformula-parser.all.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. /*!
  2. * ====================================================
  3. * kityformula-editor - v1.0.0 - 2014-04-03
  4. * https://github.com/HanCong03/kityformula-editor
  5. * GitHub: https://github.com/kitygraph/kityformula-editor.git
  6. * Copyright (c) 2014 Baidu Kity Group; Licensed MIT
  7. * ====================================================
  8. */
  9. (function () {
  10. /**
  11. * cmd 内部定义
  12. * build用
  13. */
  14. // 模块存储
  15. var _modules = {};
  16. function define ( id, deps, factory ) {
  17. _modules[ id ] = {
  18. exports: {},
  19. value: null,
  20. factory: null
  21. };
  22. if ( arguments.length === 2 ) {
  23. factory = deps;
  24. }
  25. if ( _modules.toString.call( factory ) === '[object Object]' ) {
  26. _modules[ id ][ 'value' ] = factory;
  27. } else if ( typeof factory === 'function' ) {
  28. _modules[ id ][ 'factory' ] = factory;
  29. } else {
  30. throw new Error( 'define函数未定义的行为' );
  31. }
  32. }
  33. function require ( id ) {
  34. var module = _modules[ id ],
  35. exports = null;
  36. if ( !module ) {
  37. return null;
  38. }
  39. if ( module.value ) {
  40. return module.value;
  41. }
  42. exports = module.factory.call( null, require, module.exports, module );
  43. // return 值不为空, 则以return值为最终值
  44. if ( exports ) {
  45. module.exports = exports;
  46. }
  47. module.value = module.exports;
  48. return module.value;
  49. }
  50. function use ( id ) {
  51. return require( id );
  52. }
  53. /*!
  54. * 装配器
  55. */
  56. define("assembly", [], function(require, exports, module) {
  57. var CONSTRUCT_MAPPING = {}, CURSOR_CHAR = "";
  58. function Assembly(container, config) {
  59. this.formula = new kf.Formula(container, config);
  60. }
  61. Assembly.prototype.generateBy = function(data) {
  62. var tree = data.tree, objTree = {}, selectInfo = {}, mapping = {};
  63. if (typeof tree === "string") {
  64. objTree = new kf.TextExpression(tree);
  65. this.formula.appendExpression(objTree);
  66. } else {
  67. this.formula.appendExpression(generateExpression(tree, deepCopy(tree), objTree, mapping, selectInfo));
  68. return {
  69. select: selectInfo,
  70. parsedTree: tree,
  71. tree: objTree,
  72. mapping: mapping
  73. };
  74. }
  75. };
  76. Assembly.prototype.regenerateBy = function(data) {
  77. this.formula.clearExpressions();
  78. return this.generateBy(data);
  79. };
  80. /**
  81. * 根据提供的树信息生成表达式
  82. * @param tree 中间格式的解析树
  83. * @return {kf.Expression} 生成的表达式
  84. */
  85. function generateExpression(originTree, tree, objTree, mapping, selectInfo) {
  86. var currentOperand = null, exp = null, // 记录光标位置
  87. cursorLocation = [], operand = tree.operand || [], constructor = null, constructorProxy;
  88. objTree.operand = [];
  89. // 文本表达式已经不需要再处理了
  90. if (tree.name.indexOf("text") === -1) {
  91. // 处理操作数
  92. for (var i = 0, len = operand.length; i < len; i++) {
  93. currentOperand = operand[i];
  94. //TODO 光标定位, 配合编辑器, 后期应该考虑是否有更佳的方案来实现
  95. if (currentOperand === CURSOR_CHAR) {
  96. cursorLocation.push(i);
  97. if (!selectInfo.hasOwnProperty("startOffset")) {
  98. // 字符串中的开始偏移是需要修正的
  99. selectInfo.startOffset = i;
  100. }
  101. selectInfo.endOffset = i;
  102. if (tree.attr && tree.attr.id) {
  103. selectInfo.groupId = tree.attr.id;
  104. }
  105. continue;
  106. }
  107. if (!currentOperand) {
  108. operand[i] = createObject("empty");
  109. objTree.operand.push(operand[i]);
  110. } else if (typeof currentOperand === "string") {
  111. // 括号表达式不能对前2个参数做处理, 这两个参数是代表括号类型
  112. if (tree.name === "brackets" && i < 2) {
  113. operand[i] = currentOperand;
  114. } else {
  115. operand[i] = createObject("text", currentOperand);
  116. }
  117. objTree.operand.push(operand[i]);
  118. } else {
  119. objTree.operand.push({});
  120. operand[i] = arguments.callee(originTree.operand[i], currentOperand, objTree.operand[objTree.operand.length - 1], mapping, selectInfo);
  121. }
  122. }
  123. while (i = cursorLocation.length) {
  124. i = cursorLocation[i - 1];
  125. operand.splice(i, 1);
  126. cursorLocation.length--;
  127. originTree.operand.splice(i, 1);
  128. }
  129. }
  130. constructor = getConstructor(tree.name);
  131. if (!constructor) {
  132. throw new Error("operator type error: not found " + tree.operator);
  133. }
  134. constructorProxy = function() {};
  135. constructorProxy.prototype = constructor.prototype;
  136. exp = new constructorProxy();
  137. constructor.apply(exp, operand);
  138. objTree.func = exp;
  139. // 调用配置函数
  140. for (var fn in tree.callFn) {
  141. if (!tree.callFn.hasOwnProperty(fn) || !exp[fn]) {
  142. continue;
  143. }
  144. exp[fn].apply(exp, tree.callFn[fn]);
  145. }
  146. if (tree.attr) {
  147. if (tree.attr.id) {
  148. mapping[tree.attr.id] = {
  149. objGroup: exp,
  150. strGroup: originTree
  151. };
  152. }
  153. exp.setAttr(tree.attr);
  154. }
  155. return exp;
  156. }
  157. function createObject(type, value) {
  158. switch (type) {
  159. case "empty":
  160. return new kf.EmptyExpression();
  161. case "text":
  162. return new kf.TextExpression(value);
  163. }
  164. }
  165. /**
  166. * 根据操作符获取对应的构造器
  167. */
  168. function getConstructor(name) {
  169. return CONSTRUCT_MAPPING[name] || kf[name.replace(/^[a-z]/i, function(match) {
  170. return match.toUpperCase();
  171. }).replace(/-([a-z])/gi, function(match, char) {
  172. return char.toUpperCase();
  173. }) + "Expression"];
  174. }
  175. function deepCopy(source) {
  176. var target = {};
  177. if ({}.toString.call(source) === "[object Array]") {
  178. target = [];
  179. for (var i = 0, len = source.length; i < len; i++) {
  180. target[i] = doCopy(source[i]);
  181. }
  182. } else {
  183. for (var key in source) {
  184. if (!source.hasOwnProperty(key)) {
  185. continue;
  186. }
  187. target[key] = doCopy(source[key]);
  188. }
  189. }
  190. return target;
  191. }
  192. function doCopy(source) {
  193. if (!source) {
  194. return source;
  195. }
  196. if (typeof source !== "object") {
  197. return source;
  198. }
  199. return deepCopy(source);
  200. }
  201. return {
  202. use: function(container, config) {
  203. return new Assembly(container, config);
  204. }
  205. };
  206. });
  207. /**
  208. * latex实现工具包
  209. */
  210. 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) {
  211. return {
  212. toRPNExpression: require("impl/latex/base/rpn"),
  213. generateTree: require("impl/latex/base/tree")
  214. };
  215. });
  216. /**
  217. * 逆波兰表达式转换函数
  218. */
  219. 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) {
  220. var Utils = require("impl/latex/base/utils");
  221. return function(units) {
  222. var signStack = [], TYPE = require("impl/latex/define/type"), currentUnit = null;
  223. // 先处理函数
  224. units = processFunction(units);
  225. while (currentUnit = units.shift()) {
  226. // 移除brackets中外层包裹的combination节点
  227. if (currentUnit.name === "combination" && currentUnit.operand.length === 1 && currentUnit.operand[0].name === "brackets") {
  228. currentUnit = currentUnit.operand[0];
  229. }
  230. if (Utils.isArray(currentUnit)) {
  231. signStack.push(arguments.callee(currentUnit));
  232. continue;
  233. }
  234. signStack.push(currentUnit);
  235. }
  236. // 要处理brackets被附加的包裹元素
  237. return signStack;
  238. };
  239. /**
  240. * “latex函数”处理器
  241. * @param units 单元组
  242. * @returns {Array} 处理过后的单元组
  243. */
  244. function processFunction(units) {
  245. var processed = [], currentUnit = null;
  246. while ((currentUnit = units.pop()) !== undefined) {
  247. if (currentUnit && typeof currentUnit === "object" && currentUnit.sign === false) {
  248. // 预先处理不可作为独立符号的函数
  249. var tt = currentUnit.handler(currentUnit, [], processed.reverse());
  250. processed.unshift(tt);
  251. processed.reverse();
  252. } else {
  253. processed.push(currentUnit);
  254. }
  255. }
  256. return processed.reverse();
  257. }
  258. });
  259. /**
  260. * 从单元组构建树
  261. */
  262. 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) {
  263. var TYPE = require("impl/latex/define/type"), mergeHandler = require("impl/latex/handler/combination"), Utils = require("impl/latex/base/utils");
  264. return function(units) {
  265. var currentUnit = null, nextUnit = null, tree = [];
  266. for (var i = 0, len = units.length; i < len; i++) {
  267. if (Utils.isArray(units[i])) {
  268. units[i] = arguments.callee(units[i]);
  269. }
  270. }
  271. while (currentUnit = units.shift()) {
  272. if (typeof currentUnit === "object" && currentUnit.handler) {
  273. // 后操作数
  274. tree.push(currentUnit.handler(currentUnit, tree, units));
  275. } else {
  276. tree.push(currentUnit);
  277. }
  278. }
  279. return mergeHandler(tree);
  280. };
  281. });
  282. /**
  283. * 通用工具包
  284. */
  285. 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) {
  286. var OPERATOR_LIST = require("impl/latex/define/operator"), FUNCTION_LIST = require("impl/latex/define/func"), FUNCTION_HANDLER = require("impl/latex/handler/func"), Utils = {
  287. // 根据输入的latex字符串, 检测出该字符串所对应的kf的类型
  288. getLatexType: function(str) {
  289. str = str.replace(/^\\/, "");
  290. // 操作符
  291. if (OPERATOR_LIST[str]) {
  292. return "operator";
  293. }
  294. if (FUNCTION_LIST[str]) {
  295. return "function";
  296. }
  297. return "text";
  298. },
  299. isArray: function(obj) {
  300. return obj && Object.prototype.toString.call(obj) === "[object Array]";
  301. },
  302. getDefine: function(str) {
  303. return Utils.extend({}, OPERATOR_LIST[str.replace("\\", "")]);
  304. },
  305. getFuncDefine: function(str) {
  306. return {
  307. name: "function",
  308. params: str.replace(/^\\/, ""),
  309. handler: FUNCTION_HANDLER
  310. };
  311. },
  312. getBracketsDefine: function(leftBrackets, rightBrackets) {
  313. return Utils.extend({
  314. params: [ leftBrackets, rightBrackets ]
  315. }, OPERATOR_LIST["brackets"]);
  316. },
  317. extend: function(target, sources) {
  318. for (var key in sources) {
  319. if (sources.hasOwnProperty(key)) {
  320. target[key] = sources[key];
  321. }
  322. }
  323. return target;
  324. }
  325. };
  326. return Utils;
  327. });
  328. /**
  329. * 定义括号类型, 对于属于括号类型的符号或表达式, 则可以应用brackets函数处理
  330. */
  331. define("impl/latex/define/brackets", [], function(require, exports, module) {
  332. var t = true;
  333. return {
  334. ".": t,
  335. "{": t,
  336. "}": t,
  337. "[": t,
  338. "]": t,
  339. "(": t,
  340. ")": t,
  341. "|": t
  342. };
  343. });
  344. /**
  345. * 函数列表
  346. */
  347. define("impl/latex/define/func", [], function(require, exports, module) {
  348. return {
  349. sin: 1,
  350. cos: 1,
  351. arccos: 1,
  352. cosh: 1,
  353. det: 1,
  354. inf: 1,
  355. limsup: 1,
  356. Pr: 1,
  357. tan: 1,
  358. arcsin: 1,
  359. cot: 1,
  360. dim: 1,
  361. ker: 1,
  362. ln: 1,
  363. sec: 1,
  364. tanh: 1,
  365. arctan: 1,
  366. coth: 1,
  367. exp: 1,
  368. lg: 1,
  369. log: 1,
  370. arg: 1,
  371. csc: 1,
  372. gcd: 1,
  373. lim: 1,
  374. max: 1,
  375. sinh: 1,
  376. cos: 1,
  377. deg: 1,
  378. hom: 1,
  379. liminf: 1,
  380. min: 1,
  381. sup: 1
  382. };
  383. });
  384. /**
  385. * 操作符列表
  386. */
  387. 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) {
  388. var scriptHandler = require("impl/latex/handler/script"), funcHandler = require("impl/latex/handler/func"), TYPE = require("impl/latex/define/type");
  389. return {
  390. "^": {
  391. name: "superscript",
  392. type: TYPE.OP,
  393. handler: scriptHandler
  394. },
  395. _: {
  396. name: "subscript",
  397. type: TYPE.OP,
  398. handler: scriptHandler
  399. },
  400. frac: {
  401. name: "fraction",
  402. type: TYPE.FN,
  403. sign: false,
  404. handler: require("impl/latex/handler/fraction")
  405. },
  406. sqrt: {
  407. name: "radical",
  408. type: TYPE.FN,
  409. sign: false,
  410. handler: require("impl/latex/handler/sqrt")
  411. },
  412. sum: {
  413. name: "summation",
  414. type: TYPE.FN,
  415. traversal: "rtl",
  416. handler: require("impl/latex/handler/summation")
  417. },
  418. "int": {
  419. name: "integration",
  420. type: TYPE.FN,
  421. traversal: "rtl",
  422. handler: require("impl/latex/handler/integration")
  423. },
  424. brackets: {
  425. name: "brackets",
  426. type: "TYPE.FN",
  427. handler: require("impl/latex/handler/brackets")
  428. }
  429. };
  430. });
  431. /**
  432. * 预处理器列表
  433. */
  434. define("impl/latex/define/pre", [ "impl/latex/pre/sqrt", "impl/latex/pre/int" ], function(require, exports, module) {
  435. return {
  436. // 方根预处理器
  437. sqrt: require("impl/latex/pre/sqrt"),
  438. // 积分预处理器
  439. "int": require("impl/latex/pre/int")
  440. };
  441. });
  442. /*!
  443. * 逆解析对照表
  444. */
  445. 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) {
  446. return {
  447. combination: require("impl/latex/reverse/combination"),
  448. fraction: require("impl/latex/reverse/fraction"),
  449. "function": require("impl/latex/reverse/func"),
  450. integration: require("impl/latex/reverse/integration"),
  451. subscript: require("impl/latex/reverse/subscript"),
  452. superscript: require("impl/latex/reverse/superscript"),
  453. script: require("impl/latex/reverse/script"),
  454. radical: require("impl/latex/reverse/sqrt"),
  455. summation: require("impl/latex/reverse/summation"),
  456. brackets: require("impl/latex/reverse/brackets")
  457. };
  458. });
  459. /**
  460. * 操作符类型定义
  461. */
  462. define("impl/latex/define/type", [], function(require, exports, module) {
  463. return {
  464. OP: 1,
  465. FN: 2
  466. };
  467. });
  468. /*!
  469. * 括号处理器
  470. */
  471. define("impl/latex/handler/brackets", [ "impl/latex/define/brackets" ], function(require, exports, module) {
  472. var BRACKETS_TYPE = require("impl/latex/define/brackets");
  473. return function(info, processedStack, unprocessedStack) {
  474. // 括号验证
  475. for (var i = 0, len = info.params.length; i < len; i++) {
  476. if (!(info.params[i] in BRACKETS_TYPE)) {
  477. throw new Error("Brackets: invalid params");
  478. }
  479. }
  480. info.operand = info.params;
  481. info.params[2] = unprocessedStack.shift();
  482. delete info.handler;
  483. delete info.params;
  484. return info;
  485. };
  486. });
  487. /*!
  488. * 合并处理(特殊处理函数)
  489. */
  490. define("impl/latex/handler/combination", [], function(require, exports, module) {
  491. return function() {
  492. if (arguments[0].length === 0) {
  493. return null;
  494. }
  495. return {
  496. name: "combination",
  497. operand: arguments[0]
  498. };
  499. };
  500. });
  501. /*!
  502. * 分数函数处理器
  503. */
  504. define("impl/latex/handler/fraction", [], function(require, exports, module) {
  505. // 处理函数接口
  506. return function(info, processedStack, unprocessedStack) {
  507. var numerator = unprocessedStack.shift(), // 分子
  508. denominator = unprocessedStack.shift();
  509. // 分母
  510. if (numerator === undefined || denominator === undefined) {
  511. throw new Error("Frac: Syntax Error");
  512. }
  513. info.operand = [ numerator, denominator ];
  514. delete info.handler;
  515. return info;
  516. };
  517. });
  518. /*!
  519. * 函数表达式处理器
  520. */
  521. define("impl/latex/handler/func", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
  522. var extractFn = require("impl/latex/handler/lib/int-extract");
  523. // 处理函数接口
  524. return function(info, processedStack, unprocessedStack) {
  525. var params = extractFn(unprocessedStack);
  526. info.operand = [ info.params, params.exp, params.sup, params.sub ];
  527. delete info.params;
  528. delete info.handler;
  529. return info;
  530. };
  531. });
  532. /*!
  533. * 积分函数处理器
  534. */
  535. define("impl/latex/handler/integration", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
  536. var extractFn = require("impl/latex/handler/lib/int-extract");
  537. return function(info, processedStack, unprocessedStack) {
  538. var count = unprocessedStack.shift(), params = extractFn(unprocessedStack);
  539. info.operand = [ params.exp, params.sup, params.sub ];
  540. // 参数配置调用
  541. info.callFn = {
  542. setType: [ count | 0 ]
  543. };
  544. delete info.handler;
  545. return info;
  546. };
  547. });
  548. /**
  549. * 积分参数提取函数
  550. */
  551. define("impl/latex/handler/lib/int-extract", [], function(require, exports, module) {
  552. return function(units) {
  553. var sup = units.shift() || null, sub = null, exp = null;
  554. if (sup !== null) {
  555. if (typeof sup === "string") {
  556. exp = sup;
  557. sup = null;
  558. } else {
  559. if (sup.name === "superscript") {
  560. sup = units.shift() || null;
  561. if (sup) {
  562. sub = units.shift() || null;
  563. if (sub) {
  564. if (sub.name === "subscript") {
  565. sub = units.shift() || null;
  566. exp = units.shift() || null;
  567. } else {
  568. exp = sub;
  569. sub = null;
  570. }
  571. }
  572. }
  573. } else if (sup.name === "subscript") {
  574. sub = units.shift() || null;
  575. if (sub) {
  576. sup = units.shift() || null;
  577. if (sup) {
  578. if (sup.name === "superscript") {
  579. sup = units.shift() || null;
  580. exp = units.shift() || null;
  581. } else {
  582. exp = sup;
  583. sup = null;
  584. }
  585. }
  586. }
  587. } else {
  588. exp = sup;
  589. sup = null;
  590. }
  591. }
  592. }
  593. return {
  594. sub: sub,
  595. sup: sup,
  596. exp: exp
  597. };
  598. };
  599. });
  600. /*!
  601. * 上下标操作符函数处理
  602. */
  603. define("impl/latex/handler/script", [], function(require, exports, module) {
  604. // 处理函数接口
  605. return function(info, processedStack, unprocessedStack) {
  606. var base = processedStack.pop(), script = unprocessedStack.shift() || null;
  607. if (!script) {
  608. throw new Error("Missing script");
  609. }
  610. base = base || "";
  611. if (base.name === info.name || base.name === "script") {
  612. throw new Error("script error");
  613. }
  614. // 执行替换
  615. if (base.name === "subscript") {
  616. base.name = "script";
  617. base.operand[2] = base.operand[1];
  618. base.operand[1] = script;
  619. return base;
  620. } else if (base.name === "superscript") {
  621. base.name = "script";
  622. base.operand[2] = script;
  623. return base;
  624. }
  625. info.operand = [ base, script ];
  626. // 删除处理器
  627. delete info.handler;
  628. return info;
  629. };
  630. });
  631. /*!
  632. * 方根函数处理器
  633. */
  634. define("impl/latex/handler/sqrt", [], function(require, exports, module) {
  635. // 处理函数接口
  636. return function(info, processedStack, unprocessedStack) {
  637. var exponent = unprocessedStack.shift(), // 被开方数
  638. radicand = unprocessedStack.shift();
  639. info.operand = [ radicand, exponent ];
  640. delete info.handler;
  641. return info;
  642. };
  643. });
  644. /*!
  645. * 求和函数处理器
  646. */
  647. define("impl/latex/handler/summation", [ "impl/latex/handler/lib/int-extract" ], function(require, exports, module) {
  648. var extractFn = require("impl/latex/handler/lib/int-extract");
  649. return function(info, processedStack, unprocessedStack) {
  650. var params = extractFn(unprocessedStack);
  651. info.operand = [ params.exp, params.sup, params.sub ];
  652. delete info.handler;
  653. return info;
  654. };
  655. });
  656. /**
  657. * Kity Formula Latex解析器实现
  658. */
  659. 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) {
  660. 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");
  661. // data
  662. var leftChar = "￸", rightChar = "", clearCharPattern = new RegExp(leftChar + "|" + rightChar, "g"), leftCharPattern = new RegExp(leftChar, "g"), rightCharPattern = new RegExp(rightChar, "g");
  663. Parser.register("latex", Parser.implement({
  664. parse: function(data) {
  665. var units = this.split(this.format(data));
  666. units = this.parseToGroup(units);
  667. units = this.parseToStruct(units);
  668. return this.generateTree(units);
  669. },
  670. serialization: function(tree, options) {
  671. return serialization(tree, options);
  672. },
  673. expand: function(expandObj) {
  674. var parseObj = expandObj.parse, formatKey = null, preObj = expandObj.pre, reverseObj = expandObj.reverse;
  675. for (var key in parseObj) {
  676. if (!parseObj.hasOwnProperty(key)) {
  677. continue;
  678. }
  679. formatKey = key.replace(/\\/g, "");
  680. OP_DEFINE[formatKey] = parseObj[key];
  681. }
  682. for (var key in reverseObj) {
  683. if (!reverseObj.hasOwnProperty(key)) {
  684. continue;
  685. }
  686. REVERSE_DEFINE[key.replace(/\\/g, "")] = reverseObj[key];
  687. }
  688. // 预处理
  689. if (preObj) {
  690. for (var key in preObj) {
  691. if (!preObj.hasOwnProperty(key)) {
  692. continue;
  693. }
  694. PRE_HANDLER[key.replace(/\\/g, "")] = preObj[key];
  695. }
  696. }
  697. },
  698. // 格式化输入数据
  699. format: function(input) {
  700. // 清理多余的空格
  701. input = clearEmpty(input);
  702. // 处理输入的“{”和“}”
  703. input = input.replace(clearCharPattern, "").replace(/\\{/gi, leftChar).replace(/\\}/gi, rightChar);
  704. // 预处理器处理
  705. for (var key in PRE_HANDLER) {
  706. if (PRE_HANDLER.hasOwnProperty(key)) {
  707. input = PRE_HANDLER[key](input);
  708. }
  709. }
  710. return input;
  711. },
  712. split: function(data) {
  713. var units = [], pattern = /(?:\\[a-z]+\s*)|(?:[{}]\s*)|(?:[^\\{}]\s*)/gi, emptyPattern = /^\s+|\s+$/g, match = null;
  714. data = data.replace(emptyPattern, "");
  715. while (match = pattern.exec(data)) {
  716. match = match[0].replace(emptyPattern, "");
  717. if (match) {
  718. units.push(match);
  719. }
  720. }
  721. return units;
  722. },
  723. /**
  724. * 根据解析出来的语法单元生成树
  725. * @param units 单元
  726. * @return 生成的树对象
  727. */
  728. generateTree: function(units) {
  729. var tree = [], currentUnit = null;
  730. // 递归处理
  731. while (currentUnit = units.shift()) {
  732. if (Utils.isArray(currentUnit)) {
  733. tree.push(this.generateTree(currentUnit));
  734. } else {
  735. tree.push(currentUnit);
  736. }
  737. }
  738. tree = LatexUtils.toRPNExpression(tree);
  739. return LatexUtils.generateTree(tree);
  740. },
  741. parseToGroup: function(units) {
  742. var group = [], groupStack = [ group ], groupCount = 0, bracketsCount = 0;
  743. for (var i = 0, len = units.length; i < len; i++) {
  744. switch (units[i]) {
  745. case "{":
  746. groupCount++;
  747. groupStack.push(group);
  748. group.push([]);
  749. group = group[group.length - 1];
  750. break;
  751. case "}":
  752. groupCount--;
  753. group = groupStack.pop();
  754. break;
  755. // left-right分组
  756. case "\\left":
  757. bracketsCount++;
  758. groupStack.push(group);
  759. // 进入两层
  760. group.push([ [] ]);
  761. group = group[group.length - 1][0];
  762. group.type = "brackets";
  763. // 读取左括号
  764. i++;
  765. group.leftBrackets = units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}");
  766. break;
  767. case "\\right":
  768. bracketsCount--;
  769. // 读取右括号
  770. i++;
  771. group.rightBrackets = units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}");
  772. group = groupStack.pop();
  773. break;
  774. default:
  775. group.push(units[i].replace(leftCharPattern, "{").replace(rightCharPattern, "}"));
  776. break;
  777. }
  778. }
  779. if (groupCount !== 0) {
  780. throw new Error("Group Error!");
  781. }
  782. if (bracketsCount !== 0) {
  783. throw new Error("Brackets Error!");
  784. }
  785. return groupStack[0];
  786. },
  787. parseToStruct: function(units) {
  788. var structs = [];
  789. for (var i = 0, len = units.length; i < len; i++) {
  790. if (Utils.isArray(units[i])) {
  791. if (units[i].type === "brackets") {
  792. // 处理自动调整大小的括号组
  793. // 获取括号组定义
  794. structs.push(Utils.getBracketsDefine(units[i].leftBrackets, units[i].rightBrackets));
  795. // 处理内部表达式
  796. structs.push(this.parseToStruct(units[i]));
  797. } else {
  798. // 普通组
  799. structs.push(this.parseToStruct(units[i]));
  800. }
  801. } else {
  802. structs.push(parseStruct(units[i]));
  803. }
  804. }
  805. return structs;
  806. }
  807. }));
  808. /**
  809. * 把序列化的字符串表示法转化为中间格式的结构化表示
  810. */
  811. function parseStruct(str) {
  812. var type = Utils.getLatexType(str);
  813. switch (type) {
  814. case "operator":
  815. return Utils.getDefine(str);
  816. case "function":
  817. return Utils.getFuncDefine(str);
  818. default:
  819. // text
  820. return transformSpecialCharacters(str);
  821. }
  822. }
  823. // 转换特殊的文本字符
  824. function transformSpecialCharacters(char) {
  825. if (char.indexOf("\\") === 0) {
  826. return char + "\\";
  827. }
  828. return char;
  829. }
  830. function clearEmpty(data) {
  831. return data.replace(/\\\s+/, "").replace(/\s*([^a-z0-9\s])\s*/gi, function(match, symbol) {
  832. return symbol;
  833. });
  834. }
  835. });
  836. /**
  837. * “开方”预处理器
  838. */
  839. define("impl/latex/pre/int", [], function(require) {
  840. return function(input) {
  841. return input.replace(/\\(i+)nt(\b|[^a-zA-Z])/g, function(match, sign, suffix) {
  842. return "\\int " + sign.length + suffix;
  843. });
  844. };
  845. });
  846. /**
  847. * “开方”预处理器
  848. */
  849. define("impl/latex/pre/sqrt", [], function(require) {
  850. return function(input) {
  851. return input.replace(/\\sqrt\s*((?:\[[^\]]*\])?)/g, function(match, exponent) {
  852. return "\\sqrt{" + exponent.replace(/^\[|\]$/g, "") + "}";
  853. });
  854. };
  855. });
  856. /*!
  857. * 逆解析处理函数: brackets
  858. */
  859. define("impl/latex/reverse/brackets", [], function() {
  860. /**
  861. * operands中元素对照表
  862. * 0: 左符号
  863. * 1: 右符号
  864. * 2: 表达式
  865. */
  866. return function(operands) {
  867. return [ "\\left", operands[0], operands[2], "\\right", operands[1] ].join(" ");
  868. };
  869. });
  870. /*!
  871. * 逆解析处理函数:combination
  872. */
  873. define("impl/latex/reverse/combination", [], function() {
  874. var pattern = new RegExp("", "g");
  875. return function(operands, options) {
  876. if (this.attr["data-root"] || this.attr["data-placeholder"]) {
  877. return operands.join("");
  878. }
  879. return "{" + operands.join("") + "}";
  880. };
  881. });
  882. /*!
  883. * 逆解析处理函数: fraction
  884. */
  885. define("impl/latex/reverse/fraction", [], function() {
  886. return function(operands) {
  887. return "\\frac " + operands[0] + " " + operands[1];
  888. };
  889. });
  890. /*!
  891. * 逆解析处理函数: func
  892. */
  893. define("impl/latex/reverse/func", [], function() {
  894. /**
  895. * operands中元素对照表
  896. * 0: 函数名
  897. * 1: 表达式
  898. * 2: 上标
  899. * 3: 下标
  900. */
  901. return function(operands) {
  902. var result = [ "\\" + operands[0] ];
  903. // 上标
  904. if (operands[2]) {
  905. result.push("^" + operands[2]);
  906. }
  907. // 下标
  908. if (operands[3]) {
  909. result.push("_" + operands[3]);
  910. }
  911. result.push(" " + operands[1]);
  912. return result.join("");
  913. };
  914. });
  915. /*!
  916. * 逆解析处理函数: integration
  917. */
  918. define("impl/latex/reverse/integration", [], function() {
  919. /**
  920. * operands中元素对照表
  921. * 0: 表达式
  922. * 1: 上标
  923. * 2: 下标
  924. */
  925. return function(operands) {
  926. var result = [ "\\int" ];
  927. // 上标
  928. if (operands[1]) {
  929. result.push("^" + operands[1]);
  930. }
  931. // 下标
  932. if (operands[2]) {
  933. result.push("_" + operands[2]);
  934. }
  935. result.push(" " + operands[0]);
  936. return operands.join("");
  937. };
  938. });
  939. /*!
  940. * 逆解析处理函数: script
  941. */
  942. define("impl/latex/reverse/script", [], function() {
  943. /**
  944. * operands中元素对照表
  945. * 0: 表达式
  946. * 1: 上标
  947. * 2: 下标
  948. */
  949. return function(operands) {
  950. return operands[0] + "^" + operands[1] + "_" + operands[2];
  951. };
  952. });
  953. /*!
  954. * 逆解析处理函数: sqrt
  955. */
  956. define("impl/latex/reverse/sqrt", [], function() {
  957. /**
  958. * operands中元素对照表
  959. * 0: 表达式
  960. * 1: 指数
  961. */
  962. return function(operands) {
  963. var result = [ "\\sqrt" ];
  964. // 上标
  965. if (operands[1]) {
  966. result.push("[" + operands[1] + "]");
  967. }
  968. result.push(" " + operands[0]);
  969. return result.join("");
  970. };
  971. });
  972. /*!
  973. * 逆解析处理函数: subscript
  974. */
  975. define("impl/latex/reverse/subscript", [], function() {
  976. /**
  977. * operands中元素对照表
  978. * 0: 表达式
  979. * 1: 下标
  980. */
  981. return function(operands) {
  982. return operands[0] + "_" + operands[1];
  983. };
  984. });
  985. /*!
  986. * 逆解析处理函数: summation
  987. */
  988. define("impl/latex/reverse/summation", [], function() {
  989. /**
  990. * operands中元素对照表
  991. * 0: 表达式
  992. * 1: 上标
  993. * 2: 下标
  994. */
  995. return function(operands) {
  996. var result = [ "\\sum" ];
  997. // 上标
  998. if (operands[1]) {
  999. result.push("^" + operands[1]);
  1000. }
  1001. // 下标
  1002. if (operands[2]) {
  1003. result.push("_" + operands[2]);
  1004. }
  1005. result.push(" " + operands[0]);
  1006. return result.join("");
  1007. };
  1008. });
  1009. /*!
  1010. * 逆解析处理函数: superscript
  1011. */
  1012. define("impl/latex/reverse/superscript", [], function() {
  1013. /**
  1014. * operands中元素对照表
  1015. * 0: 表达式
  1016. * 1: 上标
  1017. */
  1018. return function(operands) {
  1019. return operands[0] + "^" + operands[1];
  1020. };
  1021. });
  1022. /**
  1023. * Created by hn on 14-3-20.
  1024. */
  1025. 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) {
  1026. var reverseHandlerTable = require("impl/latex/define/reverse"), specialCharPattern = /(\\[\w]+)\\/g;
  1027. return function(tree, options) {
  1028. return reverseParse(tree, options);
  1029. };
  1030. function reverseParse(tree, options) {
  1031. var operands = [], originalOperands = null;
  1032. // 字符串处理, 需要处理特殊字符
  1033. if (typeof tree !== "object") {
  1034. return tree.replace(specialCharPattern, function(match, group) {
  1035. return group + " ";
  1036. });
  1037. }
  1038. // combination需要特殊处理, 重复嵌套的combination节点要删除
  1039. if (tree.name === "combination" && tree.operand.length === 1 && tree.operand[0].name === "combination") {
  1040. tree = tree.operand[0];
  1041. }
  1042. originalOperands = tree.operand;
  1043. for (var i = 0, len = originalOperands.length; i < len; i++) {
  1044. if (originalOperands[i]) {
  1045. operands.push(reverseParse(originalOperands[i]));
  1046. } else {
  1047. operands.push(originalOperands[i]);
  1048. }
  1049. }
  1050. return reverseHandlerTable[tree.name].call(tree, operands, options);
  1051. }
  1052. });
  1053. /*!
  1054. * Kity Formula 公式表示法Parser接口
  1055. */
  1056. define("parser", [], function(require, exports, module) {
  1057. // Parser 配置列表
  1058. var CONF = {}, IMPL_POLL = {}, // 内部简单工具类
  1059. Utils = {
  1060. extend: function(target, sources) {
  1061. var source = null;
  1062. sources = [].slice.call(arguments, 1);
  1063. for (var i = 0, len = sources.length; i < len; i++) {
  1064. source = sources[i];
  1065. for (var key in source) {
  1066. if (source.hasOwnProperty(key)) {
  1067. target[key] = source[key];
  1068. }
  1069. }
  1070. }
  1071. },
  1072. setData: function(container, key, value) {
  1073. if (typeof key === "string") {
  1074. container[key] = value;
  1075. } else if (typeof key === "object") {
  1076. for (value in key) {
  1077. if (key.hasOwnProperty(value)) {
  1078. container[value] = key[value];
  1079. }
  1080. }
  1081. } else {
  1082. // 配置项类型错误
  1083. throw new Error("invalid option");
  1084. }
  1085. }
  1086. };
  1087. /**
  1088. * 解析器
  1089. */
  1090. var Parser = {
  1091. use: function(type) {
  1092. if (!IMPL_POLL[type]) {
  1093. throw new Error("unknown parser type");
  1094. }
  1095. return this.proxy(IMPL_POLL[type]);
  1096. },
  1097. config: function(key, value) {
  1098. Utils.setData(CONF, key, value);
  1099. return this;
  1100. },
  1101. /**
  1102. * 注册解析器实现
  1103. * @param type 解析器所属类型
  1104. * @param parserImpl 解析器实现
  1105. */
  1106. register: function(type, parserImpl) {
  1107. IMPL_POLL[type.toLowerCase()] = parserImpl;
  1108. return this;
  1109. },
  1110. // 提供构造器的实现的默认结构
  1111. implement: function(parser) {
  1112. var impl = function() {}, constructor = parser.constructor || function() {}, result = function() {
  1113. ParserInterface.call(this);
  1114. constructor.call(this);
  1115. };
  1116. impl.prototype = ParserInterface.prototype;
  1117. result.prototype = new impl();
  1118. delete parser.constructor;
  1119. for (var key in parser) {
  1120. if (key !== "constructor" && parser.hasOwnProperty(key)) {
  1121. result.prototype[key] = parser[key];
  1122. }
  1123. }
  1124. return result;
  1125. },
  1126. /**
  1127. * 代理给定的parser实现
  1128. * @private
  1129. * @param parserImpl 需代理的parser实现
  1130. */
  1131. proxy: function(parserImpl) {
  1132. return new ParserProxy(parserImpl);
  1133. }
  1134. };
  1135. /**
  1136. * parser实现的代理对象, 所有实现均通过该代理对象对外提供统一接口
  1137. * @constructor
  1138. * @param parserImpl 需代理的对象
  1139. */
  1140. function ParserProxy(parserImpl) {
  1141. this.impl = new parserImpl();
  1142. this.conf = {};
  1143. }
  1144. Utils.extend(ParserProxy.prototype, {
  1145. config: function(key, value) {
  1146. Utils.setData(this.conf, key, value);
  1147. },
  1148. /**
  1149. * 设置特定解析器实现所需的配置项,参数也可以是一个Key-Value Mapping
  1150. * @param key 配置项名称
  1151. * @param value 配置项值
  1152. */
  1153. set: function(key, value) {
  1154. this.impl.set(key, value);
  1155. },
  1156. parse: function(data) {
  1157. var result = {
  1158. config: {},
  1159. // 调用实现获取解析树
  1160. tree: this.impl.parse(data)
  1161. };
  1162. Utils.extend(result.config, CONF, this.conf);
  1163. return result;
  1164. },
  1165. serialization: function(tree, options) {
  1166. return this.impl.serialization(tree, options);
  1167. },
  1168. expand: function(obj) {
  1169. this.impl.expand(obj);
  1170. }
  1171. });
  1172. /**
  1173. * 解析器所需实现的接口
  1174. * @constructor
  1175. */
  1176. function ParserInterface() {
  1177. this.conf = {};
  1178. }
  1179. Utils.extend(ParserInterface.prototype, {
  1180. set: function(key, value) {
  1181. Utils.extend(this.conf, key, value);
  1182. },
  1183. /**
  1184. * 需要特定解析器实现, 该方法是解析器的核心方法,解析器的实现者应该完成该方法对给定数据进行解析
  1185. * @param data 待解析的数据
  1186. * @return 解析树, 具体格式庆参考Kity Formula Parser 的文档
  1187. */
  1188. parse: function(data) {
  1189. throw new Error("Abstract function");
  1190. }
  1191. });
  1192. // exports
  1193. module.exports = {
  1194. Parser: Parser,
  1195. ParserInterface: ParserInterface
  1196. };
  1197. });
  1198. /**
  1199. * 模块暴露
  1200. */
  1201. ( function ( global ) {
  1202. define( 'kf.start', function ( require ) {
  1203. var Parser = require( "parser" ).Parser;
  1204. // 初始化组件
  1205. require( "impl/latex/latex" );
  1206. global.kf.Parser = Parser;
  1207. global.kf.Assembly = require( "assembly" );
  1208. } );
  1209. // build环境中才含有use
  1210. try {
  1211. use( 'kf.start' );
  1212. } catch ( e ) {
  1213. }
  1214. } )( this );
  1215. })();