/** * try to parse a GCode config string into a number * @param str the string to try parsing * @returns a number if parsing happened correctly or undefined */ function parseNumber(str: string): number | undefined { if (!/^(\d|\.)+$/g.test(str)) { return undefined } const float = parseFloat(str) const int = parseInt(str, 10) if (isNaN(int)) { return undefined } if (int !== float) { return float } return int } /** * decode a print time to a number of seconds * @param text the text to decode * @returns the number of seconds in the text */ function decodeTime(text: string): number { let timeInSec = 0 for (const it of text.split(' ')) { const lastChar = it.charAt(it.length - 1) const time = parseInt(it.slice(0, it.length - 1), 10) switch (lastChar) { case 'm': timeInSec += time * 60 break; case 's': timeInSec += time break; case 'h': timeInSec += time * 60 * 60 break; case 'd': timeInSec += time * 60 * 60 * 24 break; default: throw new Error(`error parsing time ${it} (${time})`) } } return timeInSec } export function getParams(data: string) { // get the configuration lines const lines = data.split('\n').filter((it) => it.startsWith(';') && it.includes('=')) // create the config object const obj: Record = {} // loop through eacj config for (const line of lines) { // get its key and value const [key, value] = line.split('=', 2).map((it) => it.slice(1).trim()) // sip if it has no key or value if (!key || !value) { continue } // process the key let realKey = key // replace spaces by _ .replace(/ /g, '_') // remove unparseable characters .replace(/\[|\]|\(|\)/g, '') // process the value const realValue = parseNumber(value) ?? value // add an offset if the key is already cited let offset = 0 while (obj[`${realKey}${offset > 0 ? `_${offset}` : ''}`] && obj[`${realKey}${offset > 0 ? `_${offset}` : ''}`] !== realValue) { offset++ } // chnge the key to add the offset if (offset > 0) { realKey = `${realKey}_${offset}` } // detect key collisions if (obj[realKey] && obj[realKey] !== realValue) { throw new Error(`Key collision ${key}=${realValue} ${realKey}=${obj[realKey]}`) } // set the value to the key obj[realKey] = realValue // transform the time to a number of seconds if (realKey === 'estimated_printing_time_normal_mode') { obj['estimated_printing_time_seconds'] = decodeTime(value) } } return obj }