cdn loaded latex math

This commit is contained in:
2025-10-10 13:20:32 +02:00
parent 71ee0c1c85
commit ea3da89d18
5 changed files with 281 additions and 3 deletions

View File

@@ -7,7 +7,6 @@ from pathlib import Path
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
import base64 import base64
import random import random
import time
import yaml import yaml
import marko import marko
@@ -19,6 +18,9 @@ from hashes.hashes import hash_list
from htmlhandler import htmlhandler as Handler from htmlhandler import htmlhandler as Handler
from lua import plugin_manager from lua import plugin_manager
# Import your LaTeX extension
from hashes.util.LaTeXRenderer import LaTeXExtension
plugin_manager = plugin_manager.PluginManager() plugin_manager = plugin_manager.PluginManager()
plugin_manager.load_all() # load plugins 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(): if not RUST_PARSER_PATH.exists():
RUST_PARSER_PATH = ROOT / "fastmd" / "target" / "debug" / f"fastmd{exe_ext}" RUST_PARSER_PATH = ROOT / "fastmd" / "target" / "debug" / f"fastmd{exe_ext}"
# Python Markdown parser with table support # Python Markdown parser with table support AND LaTeX extension
markdown_parser = marko.Markdown(extensions=[GFM]) markdown_parser = marko.Markdown(extensions=[GFM, LaTeXExtension()])
# Threshold for switching to Rust parser (number of lines) # Threshold for switching to Rust parser (number of lines)
RUST_PARSER_THRESHOLD = 1000 RUST_PARSER_THRESHOLD = 1000

View File

@@ -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<div class="math-block">$$\n' + self.render_children(element) + '$$</div>\n'
class LaTeXExtension:
logger.log_debug("Did shit at __init__ for latexextension")
elements = [BlockFormula, Paragraph]
parser_mixins = []
renderer_mixins = [Renderer]

View File

@@ -20,6 +20,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.11.0/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.11.0/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script>
<!-- remove if causing issues --> <!-- remove if causing issues -->
<script src="../js/post/lazyimg.js"></script> <script src="../js/post/lazyimg.js"></script>
<script src="../js/shared/theme.js"></script> <script src="../js/shared/theme.js"></script>

104
lua/luarails.lua Normal file
View File

@@ -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, "&", "&amp;")
s = string.gsub(s, "<", "&lt;")
s = string.gsub(s, ">", "&gt;")
s = string.gsub(s, '"', "&quot;")
s = string.gsub(s, "'", "&#39;")
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")

128
markdown/Rotation.md Normal file
View File

@@ -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