@mieweb/wikigdrive
Version:
Google Drive to MarkDown synchronization
74 lines (73 loc) • 2.41 kB
JavaScript
import { create, all } from 'mathjs';
const math = create(all);
math.import({
if: (a, b, c) => a ? b : c
}, {});
function cleanUpFormula(formula) {
return formula
.replace(/\?f/g, 'f')
.replace(/\$[\d]+/g, '0');
}
export function extractPath(drawEnhancedGeometry, logwidth, logheight) {
// const pathSource: string = drawEnhancedGeometry.path2 || drawEnhancedGeometry.path;
const pathSource = drawEnhancedGeometry.path;
const equations = drawEnhancedGeometry.equations || [];
const variables = {};
if (Array.isArray(equations)) {
for (const equation of equations) {
variables[equation.name] = cleanUpFormula(equation.formula);
}
}
variables['logwidth'] = String(logwidth);
variables['logheight'] = String(logheight);
let change = true;
while (change) {
change = false;
for (const k in variables) {
try {
const nevValue = math.evaluate(variables[k], variables);
if (nevValue !== variables[k]) {
variables[k] = nevValue;
change = true;
}
}
catch (ignore) { /* empty */ }
}
}
const evaluateVariable = (name) => {
const scope = Object.assign({}, variables, {});
let value = name;
let retry = 1;
while (retry > 0) {
if (typeof value === 'string' && value in scope) {
value = scope[value];
}
if (typeof value === 'number') {
break;
}
retry--;
value = value.replace(/\?f/g, 'f');
const newValue = math.evaluate(value, scope);
if (newValue !== value) {
retry++;
}
value = newValue;
}
return value;
};
let loopLimit = 1000; // to avoid infinite loop
let path = pathSource;
while (true) {
const matches = path.match('\\?f[\\d]+');
if (!matches) {
break;
}
const variable = matches[0].slice(1);
const calculatedValue = evaluateVariable(variable);
path = path.replace('?' + variable, calculatedValue);
if (loopLimit-- < 0) {
console.error('loopLimit is out, looks like you have got an infinite loop here');
}
}
return path.replace(/ N$/, '');
}