UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

80 lines (77 loc) 3.47 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.variablesFromItemBody = exports.parseFormulaDecimalSeparator = exports.formulaSyntaxError = void 0; var _uniq = _interopRequireDefault(require("lodash/uniq")); var _util = require("../components/formula/common/util"); var _quizI18n = require("@instructure/quiz-i18n"); var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message")); var variablesFromItemBody = exports.variablesFromItemBody = function variablesFromItemBody(itemBody) { var body = itemBody || ''; var matches = body.match(/`[A-Za-z]\w*`/g) || []; var matchesWithoutBackticks = matches.map(function (match) { return match.replace(/`/g, ''); }); return (0, _uniq["default"])(matchesWithoutBackticks).sort(); }; var formulaSyntaxError = exports.formulaSyntaxError = function formulaSyntaxError(variables, formula) { var substitutions = {}; variables.forEach(function (varName) { return substitutions[varName] = 1; }); try { // TODO: This will fail if nothing has called components/formula/Edit/util/loadMathJs() yet. // we should either change this function signature to return a promise and do // loadMathjs().then(mathjs => mathjs.eval...) or make sure it is always preloaded by // the time we get here., var math = _util.mathjsLoadingWrapper.mathjs; // This parses the formula detecting if the locale uses comma as separator var parsedFormula = parseFormulaDecimalSeparator(window.document.documentElement.lang || 'en-US', formula); // we replace function e() with the constant e // and function pi() with the constant pi // this is to match legacy canvas quizzes behavior which accepted both e/pi and e()/pi() var node = math.parse(parsedFormula); var transformed = node.transform(function (node, path, parent) { if (node.isFunctionNode && node.fn.isSymbolNode && node.fn.name === 'e') { return new math.expression.node.ConstantNode(Math.E); } else if (node.isFunctionNode && node.fn.isSymbolNode && node.fn.name === 'pi') { return new math.expression.node.ConstantNode(Math.PI); } else { return node; } }); var compiled = transformed.compile(); compiled.eval(substitutions); } catch (e) { var message = e.message; console.error('Formula Error: ' + e.message); var match = message.match(/Undefined symbol ([A-Za-z]+)/); if (match) { return (0, _formatMessage["default"])('Undefined symbol {symbol}', { symbol: match[1] }); } match = message.match(/Unexpected end of expression/); if (match) { return (0, _formatMessage["default"])('Unexpected end of expression'); } match = message.match(/Unexpected operator ([^\s]+)/); if (match) { return (0, _formatMessage["default"])('Unexpected operator {operator}', { operator: match[1] }); } return (0, _formatMessage["default"])('Invalid formula'); } return null; }; var parseFormulaDecimalSeparator = exports.parseFormulaDecimalSeparator = function parseFormulaDecimalSeparator(locale, formula) { var _Decimal$getDelimiter = _quizI18n.Decimal.getDelimiters(locale), decimal = _Decimal$getDelimiter.decimal; if (decimal === '.') { return formula; } return formula.replace(/(\d+),(\d+)/g, '$1.$2'); };