SymbolNode.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.createSymbolNode = void 0;
  7. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  8. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  9. var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
  10. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  11. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  12. var _string = require("../../utils/string.js");
  13. var _customs = require("../../utils/customs.js");
  14. var _factory = require("../../utils/factory.js");
  15. var _latex = require("../../utils/latex.js");
  16. function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
  17. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  18. var name = 'SymbolNode';
  19. var dependencies = ['math', '?Unit', 'Node'];
  20. var createSymbolNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  21. var math = _ref.math,
  22. Unit = _ref.Unit,
  23. Node = _ref.Node;
  24. /**
  25. * Check whether some name is a valueless unit like "inch".
  26. * @param {string} name
  27. * @return {boolean}
  28. */
  29. function isValuelessUnit(name) {
  30. return Unit ? Unit.isValuelessUnit(name) : false;
  31. }
  32. var SymbolNode = /*#__PURE__*/function (_Node) {
  33. (0, _inherits2["default"])(SymbolNode, _Node);
  34. var _super = _createSuper(SymbolNode);
  35. /**
  36. * @constructor SymbolNode
  37. * @extends {Node}
  38. * A symbol node can hold and resolve a symbol
  39. * @param {string} name
  40. * @extends {Node}
  41. */
  42. function SymbolNode(name) {
  43. var _this;
  44. (0, _classCallCheck2["default"])(this, SymbolNode);
  45. _this = _super.call(this);
  46. // validate input
  47. if (typeof name !== 'string') {
  48. throw new TypeError('String expected for parameter "name"');
  49. }
  50. _this.name = name;
  51. return _this;
  52. }
  53. (0, _createClass2["default"])(SymbolNode, [{
  54. key: "type",
  55. get: function get() {
  56. return 'SymbolNode';
  57. }
  58. }, {
  59. key: "isSymbolNode",
  60. get: function get() {
  61. return true;
  62. }
  63. /**
  64. * Compile a node into a JavaScript function.
  65. * This basically pre-calculates as much as possible and only leaves open
  66. * calculations which depend on a dynamic scope with variables.
  67. * @param {Object} math Math.js namespace with functions and constants.
  68. * @param {Object} argNames An object with argument names as key and `true`
  69. * as value. Used in the SymbolNode to optimize
  70. * for arguments from user assigned functions
  71. * (see FunctionAssignmentNode) or special symbols
  72. * like `end` (see IndexNode).
  73. * @return {function} Returns a function which can be called like:
  74. * evalNode(scope: Object, args: Object, context: *)
  75. */
  76. }, {
  77. key: "_compile",
  78. value: function _compile(math, argNames) {
  79. var name = this.name;
  80. if (argNames[name] === true) {
  81. // this is a FunctionAssignment argument
  82. // (like an x when inside the expression of a function
  83. // assignment `f(x) = ...`)
  84. return function (scope, args, context) {
  85. return args[name];
  86. };
  87. } else if (name in math) {
  88. return function (scope, args, context) {
  89. return scope.has(name) ? scope.get(name) : (0, _customs.getSafeProperty)(math, name);
  90. };
  91. } else {
  92. var isUnit = isValuelessUnit(name);
  93. return function (scope, args, context) {
  94. return scope.has(name) ? scope.get(name) : isUnit ? new Unit(null, name) : SymbolNode.onUndefinedSymbol(name);
  95. };
  96. }
  97. }
  98. /**
  99. * Execute a callback for each of the child nodes of this node
  100. * @param {function(child: Node, path: string, parent: Node)} callback
  101. */
  102. }, {
  103. key: "forEach",
  104. value: function forEach(callback) {
  105. // nothing to do, we don't have any children
  106. }
  107. /**
  108. * Create a new SymbolNode with children produced by the given callback.
  109. * Trivial since a SymbolNode has no children
  110. * @param {function(child: Node, path: string, parent: Node) : Node} callback
  111. * @returns {SymbolNode} Returns a clone of the node
  112. */
  113. }, {
  114. key: "map",
  115. value: function map(callback) {
  116. return this.clone();
  117. }
  118. /**
  119. * Throws an error 'Undefined symbol {name}'
  120. * @param {string} name
  121. */
  122. }, {
  123. key: "clone",
  124. value:
  125. /**
  126. * Create a clone of this node, a shallow copy
  127. * @return {SymbolNode}
  128. */
  129. function clone() {
  130. return new SymbolNode(this.name);
  131. }
  132. /**
  133. * Get string representation
  134. * @param {Object} options
  135. * @return {string} str
  136. * @override
  137. */
  138. }, {
  139. key: "_toString",
  140. value: function _toString(options) {
  141. return this.name;
  142. }
  143. /**
  144. * Get HTML representation
  145. * @param {Object} options
  146. * @return {string} str
  147. * @override
  148. */
  149. }, {
  150. key: "toHTML",
  151. value: function toHTML(options) {
  152. var name = (0, _string.escape)(this.name);
  153. if (name === 'true' || name === 'false') {
  154. return '<span class="math-symbol math-boolean">' + name + '</span>';
  155. } else if (name === 'i') {
  156. return '<span class="math-symbol math-imaginary-symbol">' + name + '</span>';
  157. } else if (name === 'Infinity') {
  158. return '<span class="math-symbol math-infinity-symbol">' + name + '</span>';
  159. } else if (name === 'NaN') {
  160. return '<span class="math-symbol math-nan-symbol">' + name + '</span>';
  161. } else if (name === 'null') {
  162. return '<span class="math-symbol math-null-symbol">' + name + '</span>';
  163. } else if (name === 'undefined') {
  164. return '<span class="math-symbol math-undefined-symbol">' + name + '</span>';
  165. }
  166. return '<span class="math-symbol">' + name + '</span>';
  167. }
  168. /**
  169. * Get a JSON representation of the node
  170. * @returns {Object}
  171. */
  172. }, {
  173. key: "toJSON",
  174. value: function toJSON() {
  175. return {
  176. mathjs: 'SymbolNode',
  177. name: this.name
  178. };
  179. }
  180. /**
  181. * Instantiate a SymbolNode from its JSON representation
  182. * @param {Object} json An object structured like
  183. * `{"mathjs": "SymbolNode", name: "x"}`,
  184. * where mathjs is optional
  185. * @returns {SymbolNode}
  186. */
  187. }, {
  188. key: "_toTex",
  189. value:
  190. /**
  191. * Get LaTeX representation
  192. * @param {Object} options
  193. * @return {string} str
  194. * @override
  195. */
  196. function _toTex(options) {
  197. var isUnit = false;
  198. if (typeof math[this.name] === 'undefined' && isValuelessUnit(this.name)) {
  199. isUnit = true;
  200. }
  201. var symbol = (0, _latex.toSymbol)(this.name, isUnit);
  202. if (symbol[0] === '\\') {
  203. // no space needed if the symbol starts with '\'
  204. return symbol;
  205. }
  206. // the space prevents symbols from breaking stuff like '\cdot'
  207. // if it's written right before the symbol
  208. return ' ' + symbol;
  209. }
  210. }], [{
  211. key: "onUndefinedSymbol",
  212. value: function onUndefinedSymbol(name) {
  213. throw new Error('Undefined symbol ' + name);
  214. }
  215. }, {
  216. key: "fromJSON",
  217. value: function fromJSON(json) {
  218. return new SymbolNode(json.name);
  219. }
  220. }]);
  221. return SymbolNode;
  222. }(Node);
  223. return SymbolNode;
  224. }, {
  225. isClass: true,
  226. isNode: true
  227. });
  228. exports.createSymbolNode = createSymbolNode;