feature: thousand separators and exponent to support siunitx

This commit is contained in:
Matthias Jung
2026-02-09 20:31:23 +01:00
parent c591afb6e9
commit 0d89da119e
+81 -3
View File
@@ -1,11 +1,88 @@
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
function formatThousands(input) {
let s = String(input).trim();
// Extract exponent (e or E) and convert to \cdot 10^{...}
let exponent = "";
const expMatch = s.match(/([eE])([+-]?\d+)$/);
if (expMatch) {
let expValue = expMatch[2];
// Remove leading "+"
if (expValue[0] === "+") {
expValue = expValue.slice(1);
}
// Exponent numerisch prüfen
const expNum = parseInt(expValue, 10);
// e0 → komplett unterdrücken
if (expNum !== 0) {
exponent = "\\cdot 10^{" + expNum + "}";
}
s = s.slice(0, -expMatch[0].length);
}
// Sign
let sign = "";
if (s[0] === "+" || s[0] === "-") {
sign = s[0];
s = s.slice(1);
}
// Find decimal point (last . or ,)
let intPart = s;
let fracSep = "";
let fracDigits = "";
const decMatch = s.match(/([.,])(\d+)$/);
if (decMatch) {
intPart = s.slice(0, decMatch.index);
fracSep = decMatch[1];
fracDigits = decMatch[2];
}
// Thousand grouping in integer part
if (intPart.length >= 5) {
intPart = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, "\\,");
}
// Thousand grouping in fractional part (from left in 3-digit blocks)
if (fracDigits.length >= 4) {
fracDigits = fracDigits.replace(/(\d{3})(?=\d)/g, "$1\\,");
}
// Reassemble
return res = sign + intPart + (fracDigits ? (fracSep + fracDigits) : "") + exponent;
}
var macros = { var macros = {
",": (context) => context.future()?.text === " " ? "{\\char`,}" : "\\char`,", ",": (context) => context.future()?.text === " " ? "{\\char`,}" : "\\char`,",
"\\qty": "{#1\\,\\mathrm{#2}}", "\\num": (context) => {
"\\qtyrange": "{#1\\text{--}#2\\,\\mathrm{#3}}", const [arg] = context.consumeArgs(1);
const raw = arg.reverse().map(t => t.text).join("");
return formatThousands(raw);
},
"\\qty": (context) => {
const [numTok, unitTok] = context.consumeArgs(2);
const rawNum = numTok.reverse().map(t => t.text).join("");
const unit = unitTok.reverse().map(t => t.text).join("");
const formattedNum = formatThousands(rawNum);
return formattedNum + "\\,\\mathrm{" + unit + "}";
},
"\\qtyrange": (context) => {
const [aTok, bTok, unitTok] = context.consumeArgs(3);
const aRaw = aTok.reverse().map(t => t.text).join("");
const bRaw = bTok.reverse().map(t => t.text).join("");
const unit = unitTok.reverse().map(t => t.text).join("");
const aFmt = formatThousands(aRaw);
const bFmt = formatThousands(bRaw);
return aFmt + "\\,\\text{--}\\," + bFmt + "\\,\\mathrm{" + unit + "}";
},
"\\unit": "{\\mathrm{#1}}", "\\unit": "{\\mathrm{#1}}",
"\\num": "{#1}",
"\\squared": "{^{2}}", "\\squared": "{^{2}}",
"\\cubed": "{^{3}}", "\\cubed": "{^{3}}",
"\\per": "/", "\\per": "/",
@@ -66,4 +143,5 @@ document.addEventListener("DOMContentLoaded", function() {
throwOnError: false, throwOnError: false,
macros: macros macros: macros
}); });
}); });