BlockNode.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import _defineProperty from "@babel/runtime/helpers/defineProperty";
  2. import { isNode } from '../../utils/is.js';
  3. import { forEach, map } from '../../utils/array.js';
  4. import { factory } from '../../utils/factory.js';
  5. var name = 'BlockNode';
  6. var dependencies = ['ResultSet', 'Node'];
  7. export var createBlockNode = /* #__PURE__ */factory(name, dependencies, _ref => {
  8. var {
  9. ResultSet,
  10. Node
  11. } = _ref;
  12. class BlockNode extends Node {
  13. /**
  14. * @constructor BlockNode
  15. * @extends {Node}
  16. * Holds a set with blocks
  17. * @param {Array.<{node: Node} | {node: Node, visible: boolean}>} blocks
  18. * An array with blocks, where a block is constructed as an
  19. * Object with properties block, which is a Node, and visible,
  20. * which is a boolean. The property visible is optional and
  21. * is true by default
  22. */
  23. constructor(blocks) {
  24. super();
  25. // validate input, copy blocks
  26. if (!Array.isArray(blocks)) throw new Error('Array expected');
  27. this.blocks = blocks.map(function (block) {
  28. var node = block && block.node;
  29. var visible = block && block.visible !== undefined ? block.visible : true;
  30. if (!isNode(node)) throw new TypeError('Property "node" must be a Node');
  31. if (typeof visible !== 'boolean') {
  32. throw new TypeError('Property "visible" must be a boolean');
  33. }
  34. return {
  35. node,
  36. visible
  37. };
  38. });
  39. }
  40. get type() {
  41. return name;
  42. }
  43. get isBlockNode() {
  44. return true;
  45. }
  46. /**
  47. * Compile a node into a JavaScript function.
  48. * This basically pre-calculates as much as possible and only leaves open
  49. * calculations which depend on a dynamic scope with variables.
  50. * @param {Object} math Math.js namespace with functions and constants.
  51. * @param {Object} argNames An object with argument names as key and `true`
  52. * as value. Used in the SymbolNode to optimize
  53. * for arguments from user assigned functions
  54. * (see FunctionAssignmentNode) or special symbols
  55. * like `end` (see IndexNode).
  56. * @return {function} Returns a function which can be called like:
  57. * evalNode(scope: Object, args: Object, context: *)
  58. */
  59. _compile(math, argNames) {
  60. var evalBlocks = map(this.blocks, function (block) {
  61. return {
  62. evaluate: block.node._compile(math, argNames),
  63. visible: block.visible
  64. };
  65. });
  66. return function evalBlockNodes(scope, args, context) {
  67. var results = [];
  68. forEach(evalBlocks, function evalBlockNode(block) {
  69. var result = block.evaluate(scope, args, context);
  70. if (block.visible) {
  71. results.push(result);
  72. }
  73. });
  74. return new ResultSet(results);
  75. };
  76. }
  77. /**
  78. * Execute a callback for each of the child blocks of this node
  79. * @param {function(child: Node, path: string, parent: Node)} callback
  80. */
  81. forEach(callback) {
  82. for (var i = 0; i < this.blocks.length; i++) {
  83. callback(this.blocks[i].node, 'blocks[' + i + '].node', this);
  84. }
  85. }
  86. /**
  87. * Create a new BlockNode whose children are the results of calling
  88. * the provided callback function for each child of the original node.
  89. * @param {function(child: Node, path: string, parent: Node): Node} callback
  90. * @returns {BlockNode} Returns a transformed copy of the node
  91. */
  92. map(callback) {
  93. var blocks = [];
  94. for (var i = 0; i < this.blocks.length; i++) {
  95. var block = this.blocks[i];
  96. var node = this._ifNode(callback(block.node, 'blocks[' + i + '].node', this));
  97. blocks[i] = {
  98. node,
  99. visible: block.visible
  100. };
  101. }
  102. return new BlockNode(blocks);
  103. }
  104. /**
  105. * Create a clone of this node, a shallow copy
  106. * @return {BlockNode}
  107. */
  108. clone() {
  109. var blocks = this.blocks.map(function (block) {
  110. return {
  111. node: block.node,
  112. visible: block.visible
  113. };
  114. });
  115. return new BlockNode(blocks);
  116. }
  117. /**
  118. * Get string representation
  119. * @param {Object} options
  120. * @return {string} str
  121. * @override
  122. */
  123. _toString(options) {
  124. return this.blocks.map(function (param) {
  125. return param.node.toString(options) + (param.visible ? '' : ';');
  126. }).join('\n');
  127. }
  128. /**
  129. * Get a JSON representation of the node
  130. * @returns {Object}
  131. */
  132. toJSON() {
  133. return {
  134. mathjs: name,
  135. blocks: this.blocks
  136. };
  137. }
  138. /**
  139. * Instantiate an BlockNode from its JSON representation
  140. * @param {Object} json
  141. * An object structured like
  142. * `{"mathjs": "BlockNode", blocks: [{node: ..., visible: false}, ...]}`,
  143. * where mathjs is optional
  144. * @returns {BlockNode}
  145. */
  146. static fromJSON(json) {
  147. return new BlockNode(json.blocks);
  148. }
  149. /**
  150. * Get HTML representation
  151. * @param {Object} options
  152. * @return {string} str
  153. * @override
  154. */
  155. toHTML(options) {
  156. return this.blocks.map(function (param) {
  157. return param.node.toHTML(options) + (param.visible ? '' : '<span class="math-separator">;</span>');
  158. }).join('<span class="math-separator"><br /></span>');
  159. }
  160. /**
  161. * Get LaTeX representation
  162. * @param {Object} options
  163. * @return {string} str
  164. */
  165. _toTex(options) {
  166. return this.blocks.map(function (param) {
  167. return param.node.toTex(options) + (param.visible ? '' : ';');
  168. }).join('\\;\\;\n');
  169. }
  170. }
  171. _defineProperty(BlockNode, "name", name);
  172. return BlockNode;
  173. }, {
  174. isClass: true,
  175. isNode: true
  176. });