From 5d370a0712a1ccde3c20a32c5e6e5aab0264727c Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 31 Aug 2022 23:02:13 +0100 Subject: [PATCH] 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. --- static/src/js/dark-mode.js | 8 ------ .../common/templates/common/content_page.html | 3 +-- website/contrib/code_block/tests.py | 21 ++++++---------- website/contrib/code_block/urls.py | 2 +- website/contrib/code_block/views.py | 25 +++++++++++-------- 5 files changed, 24 insertions(+), 35 deletions(-) diff --git a/static/src/js/dark-mode.js b/static/src/js/dark-mode.js index 99a4e4c..3efe6f4 100644 --- a/static/src/js/dark-mode.js +++ b/static/src/js/dark-mode.js @@ -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) { diff --git a/website/common/templates/common/content_page.html b/website/common/templates/common/content_page.html index 38324b5..db7adac 100644 --- a/website/common/templates/common/content_page.html +++ b/website/common/templates/common/content_page.html @@ -13,8 +13,7 @@ {% block extra_css %} - - + {% endblock %} {% block extra_js %} diff --git a/website/contrib/code_block/tests.py b/website/contrib/code_block/tests.py index 8ec43e5..60a7f5d 100644 --- a/website/contrib/code_block/tests.py +++ b/website/contrib/code_block/tests.py @@ -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) diff --git a/website/contrib/code_block/urls.py b/website/contrib/code_block/urls.py index f9e3882..bbbb571 100644 --- a/website/contrib/code_block/urls.py +++ b/website/contrib/code_block/urls.py @@ -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-.{PYGMENTS_VERSION_SLUG}.css", + f"pygments.{PYGMENTS_VERSION_SLUG}.css", pygments_styles, name="styles", ) diff --git a/website/contrib/code_block/views.py b/website/contrib/code_block/views.py index 034ccb0..ffa20f4 100644 --- a/website/contrib/code_block/views.py +++ b/website/contrib/code_block/views.py @@ -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" )