Qwick Maffs

Support basic arithmetic in your numeric inputs.

Try it yourself (Press enter or leave the input to evaluate):

Documentation

QwickMaffs has two functions, `bind` to , `exec`. This takes the text in the input and a set of configuration options.

Binding to an input

The bind function is the easy way to use QwickMaffs. It take an input and makes it so it automatically processes the any math term when the user presses enter or the input looses focus. It also adds an undo feature, where pressing ESC during editing reverts all changes since the input gained focus.


import { bind } `qwick-maffs/input.js`;

const qmInput = bind(input, {
	// See `exec` below for more options.

	// Set to `true` to remove the undo feature of the ESC key
	noUndo: false,

	onValueChanged(val: number) {
		// Called when an expression is executed successfully
	}

	onError(err: QMError /* -> see Error handling */) {
		// Called when an invalid expression was entered
	}, 

	onUndo(prev: string) {
		// Called when the user pressed ESC and the value was reset. `prev` contains the text value
		// before the undo was executed.
	}
});

// qmInput here is the same object as input, but with addition type info for TypeScript, so it
// can type-check the custom html events

qmInput.addEventListener('qmvaluechange', (e) => {
	// Same as the `onValueChanged` callback in `bind`. The value can be accessed through
	// `e.details`
});

qmInput.addEventListener('qmerror', (e) => {
	// Same as the `onError` callback in `bind`. The error can be accessed through `e.details`
});

qmInput.addEventListener('qmundo', (e) => {
	// Same as the `onUndo` callback in `bind`. The previous value can be accessed through
	// `e.details`
});
			

Manual Usage

The exec function can be used to execute a math expression.


const result = QuickMaffs.exec('4 + 5 * 6', {
	// Every property here is optional. I'm showing the default values here. If
	// all options remain default, the object can be omited entirely.

	decimalSep: /[,.]/, // The allowed decimal separator. This must always be a
	                    // single character in length.

	// Makes it exec will not return these errors. The parser will instead try to take a best guess
	// at what the user tried to accomplish.
	// E.g. MultipleNumbers will multiply the numbers, and UnbalancedParenthesis will be balanced
	// automatically
	ignoreErrors: QwickMaffs.Errors.MultipleNumbers | QwickMaffs.Errors.UnbalancedParenthesis,

	// Sets the operators supported in the expression. Here, we take all default operators and add
	// "%", which divides a number by 100
	operators: [
		...QwickMaffs.DefaultOptions.operators,
		{
			op: '%',
			assoc: 'suffix',
			precedence: 3,
			apply: (x) => x / 100,
		},
	],

	// Constant values available. Here, we add a constant "e".
	constants: {
		...QwickMaffs.DefaultOptions.constants,
		e: Math.E,
	},
	
	// Functions available. Functions are called by their name followed by
	// parenthesis with the parameters.
	// Here, we add `min` and `max` function.
	functions: {
		...QwickMaffs.DefaultOptions.functions,
		min: Math.min,
		max: Math.max,
	}
});
			

The return value can either be a number value if the execution was successful, or an error object. The function will not throw exceptions.

The errors returned will have the shape { pos: number, error: number }, where pos is the string position at which the error occurred and error is an error code. QwickMaffs.Errors contains an enum of all possible error codes. Error codes passed to the ignoreErrors will never be returned. Instead, QwickMaffs will attempt to silently fix the issue.

Errors

UnbalancedParenthesis (Code: 1)

A closing parenthesis without a preceding opening, or an opening parenthesis that is never closed.

If ignored: An unexpected closing parenthesis will insert a new opening parenthesis at the very start. An unclosed parenthesis will insert a new closing parenthesis at the end.

UnexpectedSymbol (Code: 2)

A symbol was used that the parser could not interpret.

If ignored: The symbol will be ignored.

IncorrectNumberOfParameters (Code: 4)

An operator is missing it's left or right parameter.

MultipleNumbers (Code: 8)

The computation resulted in more than one number. (E.g. the user entered `8 4`).

If ignored: The values will be multiplied, allowing syntax like (`8(4)`, but operator ordering my not be as expected)

NoNumbers (Code: 16)

The returned no numbers (Like an empty input)

If ignored: 0 is returned.

Fork me on Github

Available under MIT licence