From ea3da89d18ef78eb31e3b4d97037882fd2552e8e Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Fri, 10 Oct 2025 13:20:32 +0200 Subject: [PATCH] cdn loaded latex math --- PyPost.py | 8 ++- hashes/util/LaTeXRenderer.py | 42 ++++++++++++ html/base/template.html | 2 + lua/luarails.lua | 104 ++++++++++++++++++++++++++++ markdown/Rotation.md | 128 +++++++++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 hashes/util/LaTeXRenderer.py create mode 100644 lua/luarails.lua create mode 100644 markdown/Rotation.md diff --git a/PyPost.py b/PyPost.py index 074d0f0..77ee0f9 100644 --- a/PyPost.py +++ b/PyPost.py @@ -7,7 +7,6 @@ from pathlib import Path from jinja2 import Environment, FileSystemLoader import base64 import random -import time import yaml import marko @@ -19,6 +18,9 @@ from hashes.hashes import hash_list from htmlhandler import htmlhandler as Handler from lua import plugin_manager +# Import your LaTeX extension +from hashes.util.LaTeXRenderer import LaTeXExtension + plugin_manager = plugin_manager.PluginManager() plugin_manager.load_all() # load plugins @@ -35,8 +37,8 @@ RUST_PARSER_PATH = ROOT / "fastmd" / "target" / "release" / f"fastmd{exe_ext}" if not RUST_PARSER_PATH.exists(): RUST_PARSER_PATH = ROOT / "fastmd" / "target" / "debug" / f"fastmd{exe_ext}" -# Python Markdown parser with table support -markdown_parser = marko.Markdown(extensions=[GFM]) +# Python Markdown parser with table support AND LaTeX extension +markdown_parser = marko.Markdown(extensions=[GFM, LaTeXExtension()]) # Threshold for switching to Rust parser (number of lines) RUST_PARSER_THRESHOLD = 1000 diff --git a/hashes/util/LaTeXRenderer.py b/hashes/util/LaTeXRenderer.py new file mode 100644 index 0000000..0285441 --- /dev/null +++ b/hashes/util/LaTeXRenderer.py @@ -0,0 +1,42 @@ +# latex_extension.py +import marko +import marko.block +import marko.inline +from marko.md_renderer import MarkdownRenderer +import re +from log.Logger import Logger +logger = Logger() + +class BlockFormula(marko.block.BlockElement): + pattern = re.compile(r"\$\$ *\n([\s\S]+?)^\$\$ *$", re.MULTILINE) + def __init__(self, match): + logger.log_debug("Did shit at __init__ for blockformula") + self.children = [marko.inline.RawText(match.group(1))] + @classmethod + def match(cls, source): + return source.expect_re(cls.pattern) + @classmethod + def parse(cls, source): + logger.log_debug("Did some shit with Latex") + match = source.match + source.consume() + return match + +class Paragraph(marko.block.Paragraph): + override = True + @classmethod + def break_paragraph(cls, source, lazy=False): + if BlockFormula.match(source): + return True + return super().break_paragraph(source, lazy=lazy) + +class Renderer: + def render_block_formula(self, element): + # Render as HTML with MathJax-compatible format + return '\n
$$\n' + self.render_children(element) + '$$
\n' + +class LaTeXExtension: + logger.log_debug("Did shit at __init__ for latexextension") + elements = [BlockFormula, Paragraph] + parser_mixins = [] + renderer_mixins = [Renderer] \ No newline at end of file diff --git a/html/base/template.html b/html/base/template.html index f2997e7..d77baa3 100644 --- a/html/base/template.html +++ b/html/base/template.html @@ -20,6 +20,8 @@ + + diff --git a/lua/luarails.lua b/lua/luarails.lua new file mode 100644 index 0000000..79cee48 --- /dev/null +++ b/lua/luarails.lua @@ -0,0 +1,104 @@ +-- Guardrails and safe patterns for plugin development + +-- Safe string operations +function safe_concat(...) + local result = {} + for i, v in ipairs({...}) do + if v ~= nil then + table.insert(result, tostring(v)) + end + end + return table.concat(result) +end + +-- Safe table operations +function table_contains(tbl, value) + for _, v in ipairs(tbl) do + if v == value then return true end + end + return false +end + +function table_keys(tbl) + local keys = {} + for k, _ in pairs(tbl) do + table.insert(keys, k) + end + return keys +end + +function table_values(tbl) + local values = {} + for _, v in pairs(tbl) do + table.insert(values, v) + end + return values +end + +-- Safe string escaping +function escape_html(str) + if str == nil then return "" end + local s = tostring(str) + s = string.gsub(s, "&", "&") + s = string.gsub(s, "<", "<") + s = string.gsub(s, ">", ">") + s = string.gsub(s, '"', """) + s = string.gsub(s, "'", "'") + return s +end + +-- Pattern validation +function is_valid_filename(name) + if name == nil or name == "" then return false end + -- Block directory traversal + if string.match(name, "%.%.") then return false end + if string.match(name, "/") or string.match(name, "\\\\") then return false end + return true +end + +-- Safe error handling wrapper +function try_catch(fn, catch_fn) + local status, err = pcall(fn) + if not status and catch_fn then + catch_fn(err) + end + return status +end + +-- Request validation +function validate_request(req, required_fields) + if type(req) ~= "table" then return false, "Request must be a table" end + for _, field in ipairs(required_fields) do + if req[field] == nil then + return false, "Missing required field: " .. field + end + end + return true, nil +end + +-- Rate limiting helper (simple in-memory) +_rate_limits = _rate_limits or {} +function check_rate_limit(key, max_calls, window_seconds) + local now = os.time() + if _rate_limits[key] == nil then + _rate_limits[key] = {count = 1, window_start = now} + return true + end + + local rl = _rate_limits[key] + if now - rl.window_start > window_seconds then + -- Reset window + rl.count = 1 + rl.window_start = now + return true + end + + if rl.count >= max_calls then + return false + end + + rl.count = rl.count + 1 + return true +end + +log("Lua guardrails initialized") diff --git a/markdown/Rotation.md b/markdown/Rotation.md new file mode 100644 index 0000000..023283a --- /dev/null +++ b/markdown/Rotation.md @@ -0,0 +1,128 @@ +--- +summary: "Würfelrotation mit Matrizen die Multipliziert werden erkläret" +--- + +# Rotation eines Würfels um die x-Achse + +Wir wollen verstehen, wie man einen Würfel im Raum um die x-Achse dreht. + +## 1. Punkte eines Würfels + +Ein Würfel hat 8 Eckpunkte. Wenn wir den Würfel in der Mitte des Koordinatensystems platzieren, können wir die Punkte als Vektoren schreiben: + +$$ +\mathbf{A} = (1, 1, 1), \quad +\mathbf{B} = (1, 1, -1), \quad +\mathbf{C} = (1, -1, 1), \quad +\mathbf{D} = (1, -1, -1) +$$ + +$$ +\mathbf{E} = (-1, 1, 1), \quad +\mathbf{F} = (-1, 1, -1), \quad +\mathbf{G} = (-1, -1, 1), \quad +\mathbf{H} = (-1, -1, -1) +$$ + +Jeder Punkt hat drei Koordinaten +$$ +(x', y', z') +$$ + +## 2. Rotationsmatrix um die x-Achse + +Wenn wir einen Punkt + +$$ +\mathbf{v} = \begin{pmatrix} x \\ y \\ z \end{pmatrix} +$$ + +um die x-Achse um einen Winkel $\theta$ drehen wollen, benutzen wir die Rotationsmatrix: + +$$ +R_x(\theta) = +\begin{pmatrix} +1 & 0 & 0 \\ +0 & \cos\theta & -\sin\theta \\ +0 & \sin\theta & \cos\theta +\end{pmatrix} +$$ + +**Hinweis:** +- Die x-Koordinate bleibt gleich, weil wir um die x-Achse drehen. +- y und z verändern sich je nach Winkel $\theta$. + +## 3. Berechnung des neuen Punktes + +Der neue Punkt $\mathbf{v}'$ nach der Drehung ist: + +$$ +\mathbf{v}' = R_x(\theta) \mathbf{v} = +\begin{pmatrix} +1 & 0 & 0 \\ +0 & \cos\theta & -\sin\theta \\ +0 & \sin\theta & \cos\theta +\end{pmatrix} +\begin{pmatrix} x \\ y \\ z \end{pmatrix} = +\begin{pmatrix} +x \\ +y \cos\theta - z \sin\theta \\ +y \sin\theta + z \cos\theta +\end{pmatrix} +$$ + +## 4. Beispiel + +Drehen wir den Punkt + +$$ +\mathbf{A} = (1,1,1) +$$ + +um + +$$ +\theta = 90^\circ = \frac{\pi}{2} +$$ + +Dann gilt: + +$$ +\cos \theta = 0, \quad \sin \theta = 1 +$$ + +$$ +\mathbf{A}' = +\begin{pmatrix} +1 \\ +1 \cdot 0 - 1 \cdot 1 \\ +1 \cdot 1 + 1 \cdot 0 +\end{pmatrix} = +\begin{pmatrix} +1 \\ -1 \\ 1 +\end{pmatrix} +$$ + +## 5. Tabelle aller Punkte nach Rotation + +$$ +\begin{array}{c|c} +\text{Originalpunkt} & \text{Punkt nach Rotation} \\ +\hline +A (1,1,1) & (1,-1,1) \\ +B (1,1,-1) & (1,-1,-1) \\ +C (1,-1,1) & (1,-1,-1) \\ +D (1,-1,-1) & (1,1,-1) \\ +E (-1,1,1) & (-1,-1,1) \\ +F (-1,1,-1) & (-1,-1,-1) \\ +G (-1,-1,1) & (-1,1,1) \\ +H (-1,-1,-1) & (-1,1,-1) \\ +\end{array} +$$ + +## Fazit + +- x bleibt unverändert +- y und z ändern sich je nach Winkel +- Rotationsmatrizen sind ein mächtiges Werkzeug, um Objekte im 3D-Raum zu bewegen +