generated from hjess/PythonTemplateProject
https enforcement
This commit is contained in:
52
app.py
52
app.py
@@ -4,14 +4,17 @@ from fastapi.responses import HTMLResponse
|
|||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from markdown_render import MarkdownRenderer
|
||||||
|
|
||||||
|
|
||||||
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
|
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
md_renderer = MarkdownRenderer()
|
||||||
|
|
||||||
# Mount static files
|
# Mount static files
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
app.add_middleware( HTTPSRedirectMiddleware )
|
#app.add_middleware( HTTPSRedirectMiddleware )
|
||||||
|
|
||||||
# Templates directory
|
# Templates directory
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
@@ -20,6 +23,51 @@ templates = Jinja2Templates(directory="templates")
|
|||||||
with open("mock_data.json") as file:
|
with open("mock_data.json") as file:
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
|
|
||||||
|
@app.get("/test", response_class=HTMLResponse)
|
||||||
|
async def mark_test():
|
||||||
|
markdown_content = """
|
||||||
|
# Custom Tags Test
|
||||||
|
|
||||||
|
Here is an image overlay:
|
||||||
|
{img-left-overlay: src=my-cat.png}
|
||||||
|
|
||||||
|
Here is a box:
|
||||||
|
{box: title=Important, content=This is a reusable box.}
|
||||||
|
|
||||||
|
And a note:
|
||||||
|
{note: content=This is a note for the user.}
|
||||||
|
|
||||||
|
Warning section:
|
||||||
|
{warning: content=Pay attention to this warning!}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Render Markdown content
|
||||||
|
rendered_html = md_renderer.render( markdown_content )
|
||||||
|
|
||||||
|
# Wrap in a basic template
|
||||||
|
template = f"""
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Markdown Tags</title>
|
||||||
|
<style>
|
||||||
|
.img-left-overlay img {{ width: 300px; }}
|
||||||
|
.box {{ border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9; }}
|
||||||
|
.note {{ background-color: #e7f3fe; border-left: 4px solid #2196F3; padding: 10px; }}
|
||||||
|
.warning {{ background-color: #fff3cd; border-left: 4px solid #ffeb3b; padding: 10px; }}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
{rendered_html}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
return HTMLResponse( content = template )
|
||||||
|
|
||||||
# Index route
|
# Index route
|
||||||
@app.get("/", response_class=HTMLResponse)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
async def get_index(request: Request):
|
async def get_index(request: Request):
|
||||||
@@ -28,6 +76,8 @@ async def get_index(request: Request):
|
|||||||
{"request": request, "data": data, "page_title": "Forside", "author": "Henrik"}
|
{"request": request, "data": data, "page_title": "Forside", "author": "Henrik"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Category route
|
# Category route
|
||||||
@app.get("/category/{category_name}", response_class=HTMLResponse)
|
@app.get("/category/{category_name}", response_class=HTMLResponse)
|
||||||
async def get_category(request: Request, category_name: str):
|
async def get_category(request: Request, category_name: str):
|
||||||
|
|||||||
101
markdown_render.py
Normal file
101
markdown_render.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
from markdown_it import MarkdownIt
|
||||||
|
import re
|
||||||
|
|
||||||
|
class MarkdownRenderer:
|
||||||
|
def render_img_left_overlay(self, params):
|
||||||
|
src = params.get("src", "")
|
||||||
|
return f'''
|
||||||
|
<div class="img-left-overlay">
|
||||||
|
<img src="{src}" alt="Overlay Image">
|
||||||
|
<div class="overlay-text">Overlay Text</div>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def render_box(self, params):
|
||||||
|
title = params.get("title", "Box")
|
||||||
|
content = params.get("content", "")
|
||||||
|
return f'''
|
||||||
|
<div class="box">
|
||||||
|
<strong>{title}</strong>
|
||||||
|
<p>{content}</p>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def render_note(self, params):
|
||||||
|
content = params.get("content", "")
|
||||||
|
return f'''
|
||||||
|
<div class="note">
|
||||||
|
<p>{content}</p>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def render_warning(self, params):
|
||||||
|
content = params.get("content", "")
|
||||||
|
return f'''
|
||||||
|
<div class="warning">
|
||||||
|
⚠️ <p>{content}</p>
|
||||||
|
</div>
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.md = MarkdownIt()
|
||||||
|
self.TAG_RENDERERS = {
|
||||||
|
"img-left-overlay": self.render_img_left_overlay,
|
||||||
|
"box": self.render_box,
|
||||||
|
"note": self.render_note,
|
||||||
|
"warning": self.render_warning,
|
||||||
|
}
|
||||||
|
self._add_custom_tags_plugin()
|
||||||
|
print("Custom Markdown renderer initialized!")
|
||||||
|
|
||||||
|
def _add_custom_tags_plugin(self):
|
||||||
|
def custom_tag_rule(state, silent):
|
||||||
|
# Match custom tags
|
||||||
|
pattern = r"^\{(\w+):\s*([^}]*)\}$"
|
||||||
|
line = state.src[state.pos:].strip()
|
||||||
|
print(f"Parsing line: '{line}'") # Debug current line
|
||||||
|
|
||||||
|
match = re.match(pattern, line)
|
||||||
|
if not match:
|
||||||
|
print("No match for custom tag.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
tag_name = match.group(1)
|
||||||
|
params_raw = match.group(2)
|
||||||
|
print(f"Matched tag: {tag_name}, Params: {params_raw}")
|
||||||
|
|
||||||
|
# Parse parameters
|
||||||
|
params = {}
|
||||||
|
for pair in params_raw.split(","):
|
||||||
|
if "=" in pair:
|
||||||
|
key, value = pair.split("=", 1)
|
||||||
|
params[key.strip()] = value.strip()
|
||||||
|
|
||||||
|
# Check if the tag_name exists in TAG_RENDERERS
|
||||||
|
if tag_name in self.TAG_RENDERERS:
|
||||||
|
print(f"Tag '{tag_name}' found. Creating token...")
|
||||||
|
token = state.push("custom_tag", "", 0)
|
||||||
|
token.meta = {"tag_name": tag_name, "params": params}
|
||||||
|
state.pos += len(line)
|
||||||
|
return True
|
||||||
|
|
||||||
|
print(f"Tag '{tag_name}' not found in TAG_RENDERERS.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def render_custom_tag(tokens, idx, options, env, *args):
|
||||||
|
token = tokens[idx]
|
||||||
|
tag_name = token.meta["tag_name"]
|
||||||
|
params = token.meta["params"]
|
||||||
|
print(f"Rendering tag '{tag_name}' with params: {params}")
|
||||||
|
if tag_name in self.TAG_RENDERERS:
|
||||||
|
return self.TAG_RENDERERS[tag_name](params)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# Register the plugin
|
||||||
|
self.md.inline.ruler.before("emphasis", "custom_tags", custom_tag_rule)
|
||||||
|
self.md.add_render_rule("custom_tag", render_custom_tag)
|
||||||
|
print("Custom tag plugin registered!")
|
||||||
|
|
||||||
|
def render(self, markdown_content):
|
||||||
|
print("Rendering Markdown content...")
|
||||||
|
return self.md.render(markdown_content)
|
||||||
18
test_markdown_render.py
Normal file
18
test_markdown_render.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from markdown_render import MarkdownRenderer
|
||||||
|
|
||||||
|
# Initialize MarkdownRenderer
|
||||||
|
renderer = MarkdownRenderer()
|
||||||
|
|
||||||
|
# Test Markdown input
|
||||||
|
markdown_content = """
|
||||||
|
{img-left-overlay: src=my-cat.png}
|
||||||
|
{box: title=Test Box, content=This is a test.}
|
||||||
|
{note: content=This is a note.}
|
||||||
|
{warning: content=Be careful!}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Render to HTML
|
||||||
|
print("Rendering Markdown...")
|
||||||
|
html_output = renderer.render(markdown_content)
|
||||||
|
print("Rendered HTML:")
|
||||||
|
print(html_output)
|
||||||
Reference in New Issue
Block a user