From 6695e7e8ab4f1224a55d5694c4ed25ae23376f8a Mon Sep 17 00:00:00 2001 From: Boris Date: Mon, 30 Mar 2026 22:13:19 +0300 Subject: [PATCH] Render chemical formulas with proper subscript notation Adds a template filter that cleans up spaced-out formulas from scraping and wraps subscript numbers in tags for proper display. Co-Authored-By: Claude Opus 4.6 --- dailystone/templates/dailystone/stone.html | 14 +++++++--- dailystone/templatetags/__init__.py | 0 dailystone/templatetags/chem.py | 31 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 dailystone/templatetags/__init__.py create mode 100644 dailystone/templatetags/chem.py diff --git a/dailystone/templates/dailystone/stone.html b/dailystone/templates/dailystone/stone.html index afa673e..f05357c 100644 --- a/dailystone/templates/dailystone/stone.html +++ b/dailystone/templates/dailystone/stone.html @@ -1,6 +1,7 @@ + {% load chem %} {% if mineral %}{{ mineral.name }} — Daily Stone{% else %}Daily Stone{% endif %} @@ -98,10 +99,17 @@ .formula { font-size: 1.15rem; - font-family: 'Courier New', monospace; + font-family: 'Georgia', serif; color: var(--text-secondary); margin-bottom: 0.5rem; - letter-spacing: 0.02em; + letter-spacing: 0.03em; + } + + .formula sub { + font-size: 0.7em; + vertical-align: baseline; + position: relative; + top: 0.3em; } /* Photo gallery */ @@ -312,7 +320,7 @@
{% if is_random %}Random Stone{% else %}Daily Stone{% endif %}

{{ mineral.name }}

- {% if mineral.formula %}
{{ mineral.formula }}
{% endif %} + {% if mineral.formula %}
{{ mineral.formula|chem_formula }}
{% endif %}
{{ today|date:"F j, Y" }}
diff --git a/dailystone/templatetags/__init__.py b/dailystone/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dailystone/templatetags/chem.py b/dailystone/templatetags/chem.py new file mode 100644 index 0000000..f648529 --- /dev/null +++ b/dailystone/templatetags/chem.py @@ -0,0 +1,31 @@ +import re + +from django import template +from django.utils.html import escape +from django.utils.safestring import mark_safe + +register = template.Library() + + +@register.filter +def chem_formula(value): + """Render a chemical formula with proper subscript numbers.""" + if not value: + return value + text = escape(value) + # Remove spaces around parentheses and brackets + text = re.sub(r'\s*\(\s*', '(', text) + text = re.sub(r'\s*\)\s*', ')', text) + text = re.sub(r'\s*\[\s*', '[', text) + text = re.sub(r'\s*\]\s*', ']', text) + # Remove spaces between a letter and a following number + text = re.sub(r'([A-Za-z])\s+(\d)', r'\1\2', text) + # Remove spaces between a number and a following letter + text = re.sub(r'(\d)\s+([A-Za-z])', r'\1\2', text) + # Remove spaces between closing paren/bracket and a number + text = re.sub(r'([)\]])\s+(\d)', r'\1\2', text) + # Normalize middot spacing + text = re.sub(r'\s*[·•]\s*', '·', text) + # Subscript numbers after letters or closing parens/brackets + text = re.sub(r'([A-Za-z)\]])(\d+)', r'\1\2', text) + return mark_safe(text)