feature: thousand separators and exponent to support siunitx
This commit is contained in:
+81
-3
@@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user