Unify pygments stylesheet

It's less generic and less cool, but this bakes the styles for dark and
light into a single stylesheet, and deals with switching without any JS.
This commit is contained in:
Jake Howard 2022-08-31 23:02:13 +01:00
parent 488369a247
commit 5d370a0712
Signed by: jake
GPG key ID: 57AFB45680EDD477
5 changed files with 24 additions and 35 deletions

View file

@ -6,9 +6,6 @@ const darkModeToggle = document.getElementById("dark-mode-toggle");
const matchesDarkMode = window.matchMedia("(prefers-color-scheme: dark)");
const darkModeCodeStyles = document.getElementById("pygments-dark");
const lightModeCodeStyles = document.getElementById("pygments-light");
function handleDarkMode(darkMode) {
window.localStorage.setItem(STORAGE_KEY, darkMode.toString());
@ -17,11 +14,6 @@ function handleDarkMode(darkMode) {
} else {
htmlTag.classList.remove(DARK_MODE_CLASS);
}
if (darkModeCodeStyles) {
darkModeCodeStyles.sheet.disabled = !darkMode;
lightModeCodeStyles.sheet.disabled = darkMode;
}
}
if (window.localStorage.getItem(STORAGE_KEY) === null) {

View file

@ -13,8 +13,7 @@
{% block extra_css %}
<link rel="stylesheet" type="text/css" href="{% static 'css/lite-youtube-embed.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'contrib/shareon/shareon.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% url 'code-block:styles' 'default' %}" id="pygments-light">
<link rel="stylesheet" type="text/css" href="{% url 'code-block:styles' 'monokai' %}" id="pygments-dark">
<link rel="stylesheet" type="text/css" href="{% url 'code-block:styles' %}">
{% endblock %}
{% block extra_js %}

View file

@ -1,24 +1,17 @@
from django.test import TestCase
from django.urls import reverse
from pygments.styles import get_all_styles
from .utils import PYGMENTS_VERSION_SLUG
class PygmentsStylesTestCase(TestCase):
def test_accessible(self) -> None:
for style in get_all_styles():
with self.subTest(style=style):
response = self.client.get(reverse("code-block:styles", args=[style]))
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Cache-Control"], "max-age=3600")
url = reverse("code-block:styles")
def test_unknown_style(self) -> None:
response = self.client.get(reverse("code-block:styles", args=["not-a-style"]))
self.assertEqual(response.status_code, 404)
def test_accessible(self) -> None:
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Cache-Control"], "max-age=3600")
self.assertEqual(response["Content-Type"], "text/css")
def test_url_contains_version(self) -> None:
for style in get_all_styles():
with self.subTest(style=style):
url = reverse("code-block:styles", args=[style])
self.assertIn(PYGMENTS_VERSION_SLUG, url)
self.assertIn(PYGMENTS_VERSION_SLUG, self.url)

View file

@ -8,7 +8,7 @@ app_name = "code-block"
urlpatterns = [
# HACK: Bake the pygments version into the URL, without needing a custom method
path(
f"pygments-<slug:name>.{PYGMENTS_VERSION_SLUG}.css",
f"pygments.{PYGMENTS_VERSION_SLUG}.css",
pygments_styles,
name="styles",
)

View file

@ -1,16 +1,21 @@
from django.http import Http404, HttpRequest, HttpResponse
from django.http import HttpRequest, HttpResponse
from django.utils.datastructures import OrderedSet
from django.views.decorators.cache import cache_page
from pygments.formatters.html import HtmlFormatter
from pygments.util import ClassNotFound
@cache_page(3600)
def pygments_styles(request: HttpRequest, name: str) -> HttpResponse:
try:
formatter = HtmlFormatter(style=name)
except ClassNotFound:
# Raising an exception here bypasses the cache header
raise Http404
return HttpResponse(
formatter.get_style_defs("." + formatter.cssclass), content_type="text/css"
def pygments_styles(request: HttpRequest) -> HttpResponse:
default_styles = (
HtmlFormatter(style="default")
.get_style_defs("html:not(.dark-mode) .highlight")
.split("\n")
)
dark_styles = (
HtmlFormatter(style="monokai")
.get_style_defs("html.dark-mode .highlight")
.split("\n")
)
return HttpResponse(
"".join(OrderedSet(default_styles + dark_styles)), content_type="text/css"
)