Development update, December 2025

This is an update gathering together changes made to the Numbas software in the last few months.

Numbas runtime

I’ve tagged v9.1 of the Numbas runtime on GitHub.

Enhancements

  • There are new JME operators nand and nor. (documentation)
  • There is a new option for “match text pattern” parts, to allow the student to submit an empty answer. (issue, documentation)
  • The functions isnan and withintolerance now also work on complex numbers. (code)
  • The student is shown a confirmation dialog before following a “next part” link which will apply a penalty. (issue)
  • The functions sum and prod are now also defined on integers, decimals and rationals, and lcm and gcd on integers, so they’ll return the appropriate data type instead of always returning number values. (code)
  • The boolean operators and, or, implies, nand and nor are evaluated lazily, so if the left-hand argument determines the result, the right-hand side isn’t evaluated. (issue)
  • Images are always displayed on a white background, and there is a new “invert images in dark mode” display option. (issue, documentation)
  • In the default theme, scrollbars use the same colour as borders. (code)
  • There is a question variable variable_generation_run_number, to help with deterministically generating variable sets that satisfy a condition. (documentation)

Bug fixes

  • The function Numbas.loadStandaloneScript takes a type parameter. (code)
  • Fixed the dom binding handler so it copes with a list of nodes, such as a list of images produced in marking feedback. (code)
  • Fixed the score feedback object in the worksheet theme. (code)
  • The datetime binding handler deals with empty values. (code)
  • Fixed bugs in ExamDisplay.advance and reverse. (code)
  • Fixed Numbas.controls when working with the pre-2025 default theme. (code)
  • Fixed a bug which led to the page footer being rendered off the bottom of the page. (code)
  • \var and \simplify always put braces around the produced TeX. (code)
  • When rendering long variable names to TeX, underscores are escaped. (code)
  • A variable name consisting of a single underscore is rendered as \_ in TeX. (code)
  • SVG elements have font-size-adjust: none. (code)
  • Fixed the OK/cancel buttons on the “confirm end exam” modal dialog. (code)
  • In the worksheet theme, the “allow students to print their transcript” option is ignored, so all elements are always printed. (code)
  • SVG produced by MathJax is forced to have no background colour or filter. (code)
  • Fixed the background and text color on dialogs, when a custom colour scheme is used. (code)
  • Made sure the theme’s font-size-adjust style is not applied to MathJax output. (issue)
  • Fixed a bug affecting exams with the text <script> literally in their source. (issue)
  • Fixed loading extensions in standalone packages. (code)
  • Fixed the offline analysis page when loaded from the editor. (code)
  • In the old-default-2024 theme, fixed loading the storage attribute from <numbas-exam>. (code)
  • SVG images are always rendered with the text colour set to black, regardless of the chosen colour scheme. (issue)
  • Fixed a bug affecting the colour of text inside part feedback messages. (issue)
  • MathJax SVG output gets color: inherit to match the surrounding text. (issue)
  • Fixed a bug to do with the timing of the image lightbox code. (code)
  • In the default theme, fixed a layout bug affecting print media. (code)
  • Added a polyfill for Promise.withResolvers, to ensure compatibility with older browsers. (code)
  • Fixed a bug affecting the “OK” button on dialogs in Chrome. (code)
  • Fixed the LaTeX rendering of the set function. (code)
  • The parser looks for any opening bracket character when trying to find a matching bracket. (code)
  • The method Scope.getFunction applies function synonyms. (code)
  • Fixed a bug with highlight colours when using the white-on-black colour scheme. (code, issue)
  • Updated the Norwegian Bokmål translation with better phrasing, thanks to Lars Hansson. (code)
  • Gap-fill parts don’t show an extra, empty expected answer box. (issue)
  • The old-default-2024 theme doesn’t use shadowRoot. (code)
  • The LaTeX rendering copes with MathJax’s asynchronous processing model. (code)
  • The package build time is added to the URL for the numbas-mathjax script, so new versions are fetched instead of using an old version from the browser cache. (code)
  • The unit tests now check for functions whose randomness is not explicitly stated. (code)
  • The JavaScript function Numbas.math.Fraction checks for denominator undefined, using a default of 1. (code)
  • Fixed a bug to do with page breaks between questions in the worksheet theme. (issue)
  • Fixed a bug which meant the random number generator seed wasn’t loaded from attempt suspend data. (issue)
  • The test for whether an expression is deterministic or random looks inside the body of anonymous functions. (code)

Extensions

  • I updated all first-party extensions to state whether JME functions are deterministic or random.
  • Eukleides:
    • There is a new style command, aligned.
    • The text function now takes an optional angle argument. (code)
    • SVG elements produced by the extension now have an xmlns attribute. (code)
    • Pointer enter/leave event handlers are always added to diagrams, even if they’re not animated. (code)
    • There is a new grid function which lays subdiagrams out on a grid. (code)
    • Diagrams are inside a render container element, so external transformations can be applied. (code)
    • Fill and stroke colours on elements are set in CSS, so they’re not overridden by styles inherited from parent elements. (code)
    • Fixed the rendering of filled arcs. (code)
  • GeoGebra:
    • GeoGebra applets force the style text-align: start. (code)
    • When creating an applet, it waits for the container element to be made before injecting the GeoGebra applet. (code)
  • JSXGraph: updated to JSXGraph 1.12.0. (code)
  • Linear algebra: it uses the Fraction data type from the Numbas core, instead of its own version. (code)
  • Programming:
    • Replaced the Ace editor with CodeMirror 6. (code)
    • Fixed max-width of the code-editor element on narrow viewports. (code)
    • Fixed loading question resources in pyodide. (code)
    • Only the first megabyte of code output is kept. (code)

Numbas editor

I’ve tagged v9.1 of the Numbas editor on GitHub.

  • Documentation: added a link to the generic runtime example page. (documentation)
  • Fixed a bug affecting previews of exams accessed through a token. (code)
  • Fixed a bug in the resource uploader interface. (code)
  • Superusers are shown a link to the admin site in the top-nav dropdown. (code)
  • The admin interface can show exams using a particular theme. (code)
  • Various other improvements to the admin interface. (code)
  • The custom part type editor knows about functions provided by extensions. (code)
  • Fixed the “empty your basket” button. (code)
  • Fixed a bug to do with updating the rich content editor. (code)
  • Documented the methods, events and properties of the <numbas-exam> element. (documentation)
  • Documented numbas-theme.json (documentation)
  • Added an example of embedding an exam with extension data. (documentation)
  • Updated the initial styles.css for a new theme. (code)
  • Fixed a bug affecting data exports, to do with the profile’s preferred MathJax URLs. (issue)
  • When finding undefined variables, consider all variables defined in the base scope as bound. (code)
  • Fixed the check for being inside a maths environment, used by the instant LaTeX preview in the rich content editor. (code)
  • When loading a question group, it now copes with the variable_overrides list not being long enough. (code)
  • Fixed a bug to do with variables defined using destructuring syntax. (code)
  • A reversion record is no longer created for every change. Instead, they’re only created when you explicitly set a checkpoint. (code)
  • Fixed the “Upload a new theme” button when you have no existing themes. (code)
  • The editor doesn’t repeatedly try to load failed extensions; failed extensions don’t stop the page loading. (code)
  • Fixed a race condition with loading extensions in the custom part type editor. (code)
  • Improved the behaviour of the LaTeX preview inside \begin{…} environments. (code)
  • The measurement of auto-sized input elements accounts for the element’s border style. (code)
  • The question editor copes with multiple definitions of functions with the same name. (code)
  • Variables are considered random if they’re not explicitly deterministic and if they use a random function. (code)
  • Function definition errors are cleared before redefining them. (code)
  • Fixed a bug in the access controls for custom part types. (code)

Numbas LTI provider

I’ve tagged v4.4 of the Numbas LTI provider on GitHub.

Enhancements

  • When the “Invalid Nonce” error is thrown on launching an LTI link, a hint about cache settings is shown. (code)
  • Report filenames use the YYYY-MM-DD format for dates. (code)
  • The access change form always shows the usernames and emails textareas, in addition to the searchable list. (issue)
  • The attempts table is now sortable. (issue)

Bug fixes

  • Fixed a bug which meant users with an instructor role were sometimes reuqired to use the lockdown app to view a resource. (code)
  • Fixed the user score report records so that null values can be recorded. (code)
  • Fixed a syntax typo in the Docker installation instructions. (issue)
  • Fixed a bug with getting the end time of attempts which have not been started. (code)
  • Fixed loading attempt data in the re-mark page. (code)
  • The re-mark page doesn’t try to re-mark attempts with no suspend data. (code)
  • Documented the LOCKDOWN_APP.minimum_versions setting in the upgrade instructions. (code)
  • Fixed the link to install the Numbas lockdown app. (code)
  • The re-marking page loads extensions and catches errors thrown while re-marking an attempt. (code)
  • Changed the pylti1p3 package to pylti1p3next. (code)
  • SCORM data listing: when the filter pattern is invalid, no elements are matched. (issue)
  • An attempt is always shown as ‘Complete’ if it was automatically ended. (code)
  • Attempt SCORM data is only saved to local storage once the attempt has been fully initialised. This resolves a race condition when the same attempt is opened twice very quickly, and Websockets aren’t available. (code)
  • Fixed the Blackboard LTI documentation link. (code)
  • Requests to the LTI platform can time out. This fixes a bug where request handler processes would get stuck indefinitely waiting for a request that will not complete. (code)

Numbas LTI provider Docker

  • Changed the installation instructions to recommend only running one huey container. (code)
  • Added lockdown app minimum versions to settings.py. (code)
  • Fixed the postgres version (a data migration is needed for existing installations). (code, documentation)
  • Added a healthcheck to the postgres container. (code)