Files
LifeFaq/app/services/markdown_render.py

124 lines
4.1 KiB
Python
Raw Normal View History

2024-12-11 20:34:20 +01:00
import markdown
2024-12-11 23:56:15 +01:00
from jinja2 import Environment, DictLoader
2024-12-11 20:34:20 +01:00
2024-12-11 23:56:15 +01:00
# Define Jinja2 custom functions
2024-12-11 20:34:20 +01:00
def img_left_overlay(src):
"""Render an image with overlay."""
return f'''
<div class="img-left-overlay">
2024-12-21 02:02:35 +01:00
<img src="{src}" alt="Overlay Image" loading="lazy">
2024-12-11 20:34:20 +01:00
<div class="overlay-text">Overlay Text</div>
</div>
'''
def box(title, content):
"""Render a box component."""
return f'''
<div class="box">
<strong>{title}</strong>
<p>{content}</p>
</div>
'''
def note(content):
"""Render a note component."""
return f'''
<div class="note">
<p>{content}</p>
</div>
'''
2024-12-13 21:52:50 +01:00
def link_to(title, url):
"""Render a box component."""
return f'''
<a href="{url}" target="_blank" rel="noopener noreferrer">{title}</a>
'''
2024-12-11 20:34:20 +01:00
def warning(content):
"""Render a warning component."""
return f'''
<div class="warning">
<p>{content}</p>
</div>
'''
2024-12-16 17:04:06 +01:00
def slider(options, images):
"""Render a slider using the provided HTML structure."""
2024-12-19 15:41:41 +01:00
import uuid
modal_id = uuid.uuid4().hex.upper()[0:6] # Lets create some uniq modals
2024-12-16 17:04:06 +01:00
width = options.get("width", 500)
height = options.get("height", 375)
2024-12-17 17:10:37 +01:00
html_content = []
2024-12-18 21:39:19 +01:00
html_content.append('<div class="button-stack">')
2024-12-17 19:06:34 +01:00
for i, val in enumerate(images):
2024-12-19 15:57:20 +01:00
modal_id = f"{modal_id}_{i}"
modal_id_next = f"{modal_id}_{i+1}"
if int(len(images))<=int(i+1):
modal_id_next = f"{modal_id}_0"
2024-12-17 22:34:05 +01:00
if i % 2 == 0:
2024-12-21 02:02:35 +01:00
html_content.append(f"""<button onclick="openModal('modal{modal_id}')" class="stacked-button"> <img src="{val}" alt="Lets do better" class="thumbnail" loading="lazy"></button>""".strip())
2024-12-17 22:34:05 +01:00
else:
2024-12-21 02:02:35 +01:00
html_content.append(f"""<button onclick="openModal('modal{modal_id}')" class="stacked-button"> <img src="{val}" alt="Lets do better" class="thumbnail" loading="lazy"></button>""".strip())
2024-12-20 23:20:49 +01:00
html_content.append(f"""<div class="modal" id="modal{modal_id}">
<div class="modal-content">
<h2>Modal {i}</h2>
2024-12-21 02:02:35 +01:00
<img src="{val}" alt="Lets do better" loading="lazy">
2024-12-19 20:20:07 +01:00
<div class="modal-buttons">
2024-12-20 23:20:49 +01:00
<button onclick="closeModal('modal{modal_id}')">Close</button>
<button class="next-btn" onclick="nextModal('modal{modal_id}', 'modal{modal_id_next}')">Next</button>
</div>
</div>
</div>""")
2024-12-17 22:03:47 +01:00
html_content.append( '</div>' )
2024-12-17 19:06:34 +01:00
html = '\n'.join( html_content )
return html
2024-12-16 17:04:06 +01:00
2024-12-11 23:56:15 +01:00
def create_jinja_environment():
2024-12-12 19:55:30 +01:00
"""Create and configure the Jinja2 environment."""
2024-12-11 23:56:15 +01:00
env = Environment(loader=DictLoader({"base_template": "{{ content | safe }}"}))
2024-12-11 20:34:20 +01:00
env.globals.update({
"img_left_overlay": img_left_overlay,
"box": box,
"note": note,
"warning": warning,
2024-12-13 21:52:50 +01:00
"link_to": link_to,
2024-12-16 17:04:06 +01:00
"slider": slider,
2024-12-11 20:34:20 +01:00
})
return env
2024-12-11 23:56:15 +01:00
def render_markdown_with_jinja(markdown_content: str):
"""
Convert Markdown to HTML and apply Jinja2 rendering for custom tags.
2024-12-11 20:34:20 +01:00
2024-12-11 23:56:15 +01:00
Args:
markdown_content (str): Raw Markdown content.
Returns:
tuple: Rendered HTML content and metadata as a dictionary.
"""
# Step 1: Convert Markdown to HTML and extract metadata
md = markdown.Markdown(extensions=["extra", "nl2br", "meta"])
2024-12-12 19:55:30 +01:00
intermediate_html = md.convert(markdown_content)
2024-12-11 23:56:15 +01:00
metadata = {key: " ".join(value) for key, value in md.Meta.items()} if md.Meta else {}
2024-12-12 19:55:30 +01:00
# Step 2: Pass the resulting HTML with Jinja2 custom tags through Jinja2
2024-12-11 20:34:20 +01:00
env = create_jinja_environment()
2024-12-17 17:10:37 +01:00
2024-12-11 23:56:15 +01:00
template = env.get_template("base_template")
2024-12-12 19:55:30 +01:00
final_html = template.render(content=intermediate_html)
2024-12-17 19:06:34 +01:00
#Step 3: Re-render final_html in Jinja2 for embedded tags like {{ box(...) }}
try:
final_output = env.from_string(final_html).render()
except:
print(final_html)
2024-12-11 20:34:20 +01:00
2024-12-12 19:55:30 +01:00
return final_output, metadata