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)