Merge branch 'main' into feature/brightspots

This commit is contained in:
Tim Grelka
2026-02-15 13:22:23 +01:00
committed by GitHub
2 changed files with 165 additions and 68 deletions
+154 -65
View File
@@ -1,69 +1,158 @@
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
var macros = { function formatThousands(input) {
",": (context) => context.future()?.text === " " ? "{\\char`,}" : "\\char`,",
"\\qty": "{#1\\,\\mathrm{#2}}", let s = String(input).trim();
"\\qtyrange": "{#1\\text{--}#2\\,\\mathrm{#3}}",
"\\unit": "{\\mathrm{#1}}", // Extract exponent (e or E) and convert to \cdot 10^{...}
"\\num": "{#1}", let exponent = "";
"\\squared": "{^{2}}", const expMatch = s.match(/([eE])([+-]?\d+)$/);
"\\cubed": "{^{3}}", if (expMatch) {
"\\per": "/", let expValue = expMatch[2];
"\\percent": "\\%",
"\\tera": "\\text{T}", // Remove leading "+"
"\\giga": "\\text{G}", if (expValue[0] === "+") {
"\\mega": "\\text{M}", expValue = expValue.slice(1);
"\\kilo": "\\text{k}", }
"\\dezi": "\\text{d}",
"\\centi": "\\text{c}", // Parse exponent as a numeric value
"\\milli": "\\text{m}", const expNum = parseInt(expValue, 10);
"\\micro": "\\text{μ}",
"\\nano": "\\text{n}", // Suppress exponent if it is 0 (no \cdot 10^0 shown)
"\\pico": "\\text{p}", if (expNum !== 0) {
"\\kilogram": "\\text{kg}", exponent = "\\cdot 10^{" + expNum + "}";
"\\gram": "\\text{g}", }
"\\meter": "\\text{m}",
"\\second": "\\text{s}", s = s.slice(0, -expMatch[0].length);
"\\hour": "\\text{h}", }
"\\ampere": "\\text{A}",
"\\kelvin": "\\text{K}", // Sign (+, -, \pm). Also accept "\\pm" (double-escaped backslash) and optional whitespace.
"\\mol": "\\text{mol}", let sign = "";
"\\bel": "\\text{B}", const pmMatch = s.match(/^(?:\\\\pm|\\pm)\s*/);
"\\dezibel": "\\text{dB}", if (pmMatch) {
"\\dB": "\\text{dB}", sign = "\\pm";
"\\dBm": "\\text{dBm}", s = s.slice(pmMatch[0].length);
"\\dBu": "\\text{dBu}", } else if (s[0] === "+" || s[0] === "-") {
"\\dBW": "\\text{dBW}", sign = s[0];
"\\dBi": "\\text{dBi}", s = s.slice(1);
"\\dBd": "\\text{dBd}", }
"\\candela": "\\text{cd}",
"\\newton": "\\text{N}", // Find decimal point (last . or ,)
"\\hertz": "\\text{Hz}", let intPart = s;
"\\pascal": "\\text{Pa}", let fracSep = "";
"\\volt": "\\text{V}", let fracDigits = "";
"\\watt": "\\text{W}", const decMatch = s.match(/([.,])(\d+)$/);
"\\joule": "\\text{J}", if (decMatch) {
"\\henry": "\\text{H}", intPart = s.slice(0, decMatch.index);
"\\farad": "\\text{F}", fracSep = decMatch[1];
"\\coulomb": "\\text{C}", fracDigits = decMatch[2];
"\\ohm": "\\Omega", }
"\\Ohm": "\\Omega",
"\\weber": "\\text{Wb}", // Thousand grouping in integer part
"\\tesla": "\\text{T}", if (intPart.length >= 5) {
"\\bit": "\\text{b}", intPart = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, "\\,");
"\\baud": "\\text{Bd}", }
"\\degree": "^\\circ",
"\\degreeCelsius": "^\\circ\\text{C}", // 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 sign + intPart + (fracDigits ? (fracSep + fracDigits) : "") + exponent;
}
var macros = {
",": (context) => context.future()?.text === " " ? "{\\char`,}" : "\\char`,",
"\\num": (context) => {
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);
if (unit.startsWith("\\degree")) {
return formattedNum + "\\mathrm{" + unit + "}";
} else {
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);
if (unit.startsWith("\\degree")) {
return aFmt + "\\text{--}\\," + bFmt + "\\mathrm{" + unit + "}";
} else {
return aFmt + "\\,\\text{--}\\," + bFmt + "\\,\\mathrm{" + unit + "}";
}
},
"\\unit": "{\\mathrm{#1}}",
"\\squared": "{^{2}}",
"\\cubed": "{^{3}}",
"\\per": "/",
"\\percent": "\\%",
"\\tera": "\\text{T}",
"\\giga": "\\text{G}",
"\\mega": "\\text{M}",
"\\kilo": "\\text{k}",
"\\dezi": "\\text{d}",
"\\centi": "\\text{c}",
"\\milli": "\\text{m}",
"\\micro": "\\text{μ}",
"\\nano": "\\text{n}",
"\\pico": "\\text{p}",
"\\kilogram": "\\text{kg}",
"\\gram": "\\text{g}",
"\\meter": "\\text{m}",
"\\second": "\\text{s}",
"\\hour": "\\text{h}",
"\\ampere": "\\text{A}",
"\\kelvin": "\\text{K}",
"\\mol": "\\text{mol}",
"\\bel": "\\text{B}",
"\\dezibel": "\\text{dB}",
"\\dB": "\\text{dB}",
"\\dBm": "\\text{dBm}",
"\\dBu": "\\text{dBu}",
"\\dBW": "\\text{dBW}",
"\\dBi": "\\text{dBi}",
"\\dBd": "\\text{dBd}",
"\\candela": "\\text{cd}",
"\\newton": "\\text{N}",
"\\hertz": "\\text{Hz}",
"\\pascal": "\\text{Pa}",
"\\volt": "\\text{V}",
"\\watt": "\\text{W}",
"\\joule": "\\text{J}",
"\\henry": "\\text{H}",
"\\farad": "\\text{F}",
"\\coulomb": "\\text{C}",
"\\ohm": "\\Omega",
"\\Ohm": "\\Omega",
"\\weber": "\\text{Wb}",
"\\tesla": "\\text{T}",
"\\bit": "\\text{b}",
"\\baud": "\\text{Bd}",
"\\degreeCelsius": "\\,\\degree\\text{C}",
};
renderMathInElement(document.body, {
delimiters: [
{ left: '$$', right: '$$', display: true }, // Note: $$ has to come before $
{ left: '$', right: '$', display: false },
{ left: '\\[', right: '\\]', display: true },
{ left: "\\(", right: "\\)", display: false },
],
throwOnError: false,
macros: macros
});
renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true}, // Note: $$ has to come before $
{left: '$', right: '$', display: false},
{left: '\\[', right: '\\]', display: true},
{left: "\\(", right: "\\)", display: false},
],
throwOnError : false,
macros: macros
});
}); });
+11 -3
View File
@@ -1,5 +1,6 @@
import json import json
import random import random
import re
import shutil import shutil
from pathlib import Path from pathlib import Path
@@ -124,8 +125,7 @@ class Build:
page_template = self.env.get_template("html/page.html") page_template = self.env.get_template("html/page.html")
return page_template.render(content=content, course_wrapper=course_wrapper, sidebar=sidebar) return page_template.render(content=content, course_wrapper=course_wrapper, sidebar=sidebar)
def __picture_handler(self, id): def __copy_picture(self, id):
self.config.p_build_pictures.mkdir(parents=True, exist_ok=True)
file = f"{id}.svg" file = f"{id}.svg"
try: try:
shutil.copyfile(self.config.p_data_pictures / file, self.config.p_build_pictures / file) shutil.copyfile(self.config.p_data_pictures / file, self.config.p_build_pictures / file)
@@ -136,6 +136,10 @@ class Build:
except FileNotFoundError: except FileNotFoundError:
tqdm.write(f"\033[31mPicture #{id} not found\033[0m") tqdm.write(f"\033[31mPicture #{id} not found\033[0m")
def __picture_handler(self, id):
self.config.p_build_pictures.mkdir(parents=True, exist_ok=True)
return self.__copy_picture(id)
def __photo_handler(self, id): def __photo_handler(self, id):
self.config.p_build_photos.mkdir(parents=True, exist_ok=True) self.config.p_build_photos.mkdir(parents=True, exist_ok=True)
file = f"{id}.png" file = f"{id}.png"
@@ -170,7 +174,11 @@ class Build:
def __include_handler(self, include): def __include_handler(self, include):
with (self.config.p_data_html / f"{include}.html").open() as file: with (self.config.p_data_html / f"{include}.html").open() as file:
return file.read() code = file.read()
svg_list = re.findall(r"(\d+)\.svg", code or "")
for id in svg_list:
self.__copy_picture(id)
return code
def __build_section( def __build_section(
self, self,