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

View file

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

View file

@ -1,24 +1,17 @@
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from pygments.styles import get_all_styles
from .utils import PYGMENTS_VERSION_SLUG from .utils import PYGMENTS_VERSION_SLUG
class PygmentsStylesTestCase(TestCase): class PygmentsStylesTestCase(TestCase):
def test_accessible(self) -> None: url = reverse("code-block:styles")
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")
def test_unknown_style(self) -> None: def test_accessible(self) -> None:
response = self.client.get(reverse("code-block:styles", args=["not-a-style"])) response = self.client.get(self.url)
self.assertEqual(response.status_code, 404) 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: def test_url_contains_version(self) -> None:
for style in get_all_styles(): self.assertIn(PYGMENTS_VERSION_SLUG, self.url)
with self.subTest(style=style):
url = reverse("code-block:styles", args=[style])
self.assertIn(PYGMENTS_VERSION_SLUG, url)

View file

@ -8,7 +8,7 @@ app_name = "code-block"
urlpatterns = [ urlpatterns = [
# HACK: Bake the pygments version into the URL, without needing a custom method # HACK: Bake the pygments version into the URL, without needing a custom method
path( path(
f"pygments-<slug:name>.{PYGMENTS_VERSION_SLUG}.css", f"pygments.{PYGMENTS_VERSION_SLUG}.css",
pygments_styles, pygments_styles,
name="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 django.views.decorators.cache import cache_page
from pygments.formatters.html import HtmlFormatter from pygments.formatters.html import HtmlFormatter
from pygments.util import ClassNotFound
@cache_page(3600) @cache_page(3600)
def pygments_styles(request: HttpRequest, name: str) -> HttpResponse: def pygments_styles(request: HttpRequest) -> HttpResponse:
try: default_styles = (
formatter = HtmlFormatter(style=name) HtmlFormatter(style="default")
except ClassNotFound: .get_style_defs("html:not(.dark-mode) .highlight")
# Raising an exception here bypasses the cache header .split("\n")
raise Http404 )
return HttpResponse( dark_styles = (
formatter.get_style_defs("." + formatter.cssclass), content_type="text/css" HtmlFormatter(style="monokai")
.get_style_defs("html.dark-mode .highlight")
.split("\n")
)
return HttpResponse(
"".join(OrderedSet(default_styles + dark_styles)), content_type="text/css"
) )