From 8748a968b383164ac4c5fd18564acbae01860daf Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Tue, 18 Aug 2020 09:37:13 +0200 Subject: [PATCH] Add code highlighting with auto dark mode switch --- articles/models.py | 3 +- articles/static/code-dark.css | 78 +++++++++++++++++++++++++++ articles/static/code-light.css | 78 +++++++++++++++++++++++++++ articles/static/toggle-dark-mode.js | 21 ++++++++ articles/templates/articles/base.html | 3 ++ requirements.txt | 1 + 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 articles/static/code-dark.css create mode 100644 articles/static/code-light.css create mode 100644 articles/static/toggle-dark-mode.js diff --git a/articles/models.py b/articles/models.py index a19c67b..abf4b26 100644 --- a/articles/models.py +++ b/articles/models.py @@ -7,6 +7,7 @@ from django.db import models from django.template.defaultfilters import slugify from django.urls import reverse from django.utils import timezone +from markdown.extensions.codehilite import CodeHiliteExtension class User(AbstractUser): @@ -59,7 +60,7 @@ class Article(models.Model): return html.split("")[0] def get_formatted_content(self): - md = markdown.Markdown(extensions=["extra"]) + md = markdown.Markdown(extensions=["extra", CodeHiliteExtension(linenums=True)]) content = self.content content = re.sub(r"(\s)#(\w+)", r"\1\#\2", content) return md.convert(content) diff --git a/articles/static/code-dark.css b/articles/static/code-dark.css new file mode 100644 index 0000000..884c926 --- /dev/null +++ b/articles/static/code-dark.css @@ -0,0 +1,78 @@ +.codehilite .hll { background-color: #073642 } +.codehilite { background: #002b36; color: #839496 } +.codehilite .c { color: #586e75; font-style: italic } /* Comment */ +.codehilite .err { color: #839496; background-color: #dc322f } /* Error */ +.codehilite .esc { color: #839496 } /* Escape */ +.codehilite .g { color: #839496 } /* Generic */ +.codehilite .k { color: #859900 } /* Keyword */ +.codehilite .l { color: #839496 } /* Literal */ +.codehilite .n { color: #839496 } /* Name */ +.codehilite .o { color: #586e75 } /* Operator */ +.codehilite .x { color: #839496 } /* Other */ +.codehilite .p { color: #839496 } /* Punctuation */ +.codehilite .ch { color: #586e75; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #586e75; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #d33682 } /* Comment.Preproc */ +.codehilite .cpf { color: #586e75 } /* Comment.PreprocFile */ +.codehilite .c1 { color: #586e75; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #586e75; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #dc322f } /* Generic.Deleted */ +.codehilite .ge { color: #839496; font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #dc322f } /* Generic.Error */ +.codehilite .gh { color: #839496; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #859900 } /* Generic.Inserted */ +.codehilite .go { color: #839496 } /* Generic.Output */ +.codehilite .gp { color: #839496 } /* Generic.Prompt */ +.codehilite .gs { color: #839496; font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #839496; text-decoration: underline } /* Generic.Subheading */ +.codehilite .gt { color: #268bd2 } /* Generic.Traceback */ +.codehilite .kc { color: #2aa198 } /* Keyword.Constant */ +.codehilite .kd { color: #2aa198 } /* Keyword.Declaration */ +.codehilite .kn { color: #cb4b16 } /* Keyword.Namespace */ +.codehilite .kp { color: #859900 } /* Keyword.Pseudo */ +.codehilite .kr { color: #859900 } /* Keyword.Reserved */ +.codehilite .kt { color: #b58900 } /* Keyword.Type */ +.codehilite .ld { color: #839496 } /* Literal.Date */ +.codehilite .m { color: #2aa198 } /* Literal.Number */ +.codehilite .s { color: #2aa198 } /* Literal.String */ +.codehilite .na { color: #839496 } /* Name.Attribute */ +.codehilite .nb { color: #268bd2 } /* Name.Builtin */ +.codehilite .nc { color: #268bd2 } /* Name.Class */ +.codehilite .no { color: #268bd2 } /* Name.Constant */ +.codehilite .nd { color: #268bd2 } /* Name.Decorator */ +.codehilite .ni { color: #268bd2 } /* Name.Entity */ +.codehilite .ne { color: #268bd2 } /* Name.Exception */ +.codehilite .nf { color: #268bd2 } /* Name.Function */ +.codehilite .nl { color: #268bd2 } /* Name.Label */ +.codehilite .nn { color: #268bd2 } /* Name.Namespace */ +.codehilite .nx { color: #839496 } /* Name.Other */ +.codehilite .py { color: #839496 } /* Name.Property */ +.codehilite .nt { color: #268bd2 } /* Name.Tag */ +.codehilite .nv { color: #268bd2 } /* Name.Variable */ +.codehilite .ow { color: #859900 } /* Operator.Word */ +.codehilite .w { color: #839496 } /* Text.Whitespace */ +.codehilite .mb { color: #2aa198 } /* Literal.Number.Bin */ +.codehilite .mf { color: #2aa198 } /* Literal.Number.Float */ +.codehilite .mh { color: #2aa198 } /* Literal.Number.Hex */ +.codehilite .mi { color: #2aa198 } /* Literal.Number.Integer */ +.codehilite .mo { color: #2aa198 } /* Literal.Number.Oct */ +.codehilite .sa { color: #2aa198 } /* Literal.String.Affix */ +.codehilite .sb { color: #2aa198 } /* Literal.String.Backtick */ +.codehilite .sc { color: #2aa198 } /* Literal.String.Char */ +.codehilite .dl { color: #2aa198 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #586e75 } /* Literal.String.Doc */ +.codehilite .s2 { color: #2aa198 } /* Literal.String.Double */ +.codehilite .se { color: #2aa198 } /* Literal.String.Escape */ +.codehilite .sh { color: #2aa198 } /* Literal.String.Heredoc */ +.codehilite .si { color: #2aa198 } /* Literal.String.Interpol */ +.codehilite .sx { color: #2aa198 } /* Literal.String.Other */ +.codehilite .sr { color: #cb4b16 } /* Literal.String.Regex */ +.codehilite .s1 { color: #2aa198 } /* Literal.String.Single */ +.codehilite .ss { color: #2aa198 } /* Literal.String.Symbol */ +.codehilite .bp { color: #268bd2 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #268bd2 } /* Name.Function.Magic */ +.codehilite .vc { color: #268bd2 } /* Name.Variable.Class */ +.codehilite .vg { color: #268bd2 } /* Name.Variable.Global */ +.codehilite .vi { color: #268bd2 } /* Name.Variable.Instance */ +.codehilite .vm { color: #268bd2 } /* Name.Variable.Magic */ +.codehilite .il { color: #2aa198 } /* Literal.Number.Integer.Long */ diff --git a/articles/static/code-light.css b/articles/static/code-light.css new file mode 100644 index 0000000..adba359 --- /dev/null +++ b/articles/static/code-light.css @@ -0,0 +1,78 @@ +.codehilite .hll { background-color: #eee8d5 } +.codehilite { background: #fdf6e3; color: #657b83 } +.codehilite .c { color: #93a1a1; font-style: italic } /* Comment */ +.codehilite .err { color: #657b83; background-color: #dc322f } /* Error */ +.codehilite .esc { color: #657b83 } /* Escape */ +.codehilite .g { color: #657b83 } /* Generic */ +.codehilite .k { color: #859900 } /* Keyword */ +.codehilite .l { color: #657b83 } /* Literal */ +.codehilite .n { color: #657b83 } /* Name */ +.codehilite .o { color: #93a1a1 } /* Operator */ +.codehilite .x { color: #657b83 } /* Other */ +.codehilite .p { color: #657b83 } /* Punctuation */ +.codehilite .ch { color: #93a1a1; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #93a1a1; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #d33682 } /* Comment.Preproc */ +.codehilite .cpf { color: #93a1a1 } /* Comment.PreprocFile */ +.codehilite .c1 { color: #93a1a1; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #93a1a1; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #dc322f } /* Generic.Deleted */ +.codehilite .ge { color: #657b83; font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #dc322f } /* Generic.Error */ +.codehilite .gh { color: #657b83; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #859900 } /* Generic.Inserted */ +.codehilite .go { color: #657b83 } /* Generic.Output */ +.codehilite .gp { color: #657b83 } /* Generic.Prompt */ +.codehilite .gs { color: #657b83; font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #657b83; text-decoration: underline } /* Generic.Subheading */ +.codehilite .gt { color: #268bd2 } /* Generic.Traceback */ +.codehilite .kc { color: #2aa198 } /* Keyword.Constant */ +.codehilite .kd { color: #2aa198 } /* Keyword.Declaration */ +.codehilite .kn { color: #cb4b16 } /* Keyword.Namespace */ +.codehilite .kp { color: #859900 } /* Keyword.Pseudo */ +.codehilite .kr { color: #859900 } /* Keyword.Reserved */ +.codehilite .kt { color: #b58900 } /* Keyword.Type */ +.codehilite .ld { color: #657b83 } /* Literal.Date */ +.codehilite .m { color: #2aa198 } /* Literal.Number */ +.codehilite .s { color: #2aa198 } /* Literal.String */ +.codehilite .na { color: #657b83 } /* Name.Attribute */ +.codehilite .nb { color: #268bd2 } /* Name.Builtin */ +.codehilite .nc { color: #268bd2 } /* Name.Class */ +.codehilite .no { color: #268bd2 } /* Name.Constant */ +.codehilite .nd { color: #268bd2 } /* Name.Decorator */ +.codehilite .ni { color: #268bd2 } /* Name.Entity */ +.codehilite .ne { color: #268bd2 } /* Name.Exception */ +.codehilite .nf { color: #268bd2 } /* Name.Function */ +.codehilite .nl { color: #268bd2 } /* Name.Label */ +.codehilite .nn { color: #268bd2 } /* Name.Namespace */ +.codehilite .nx { color: #657b83 } /* Name.Other */ +.codehilite .py { color: #657b83 } /* Name.Property */ +.codehilite .nt { color: #268bd2 } /* Name.Tag */ +.codehilite .nv { color: #268bd2 } /* Name.Variable */ +.codehilite .ow { color: #859900 } /* Operator.Word */ +.codehilite .w { color: #657b83 } /* Text.Whitespace */ +.codehilite .mb { color: #2aa198 } /* Literal.Number.Bin */ +.codehilite .mf { color: #2aa198 } /* Literal.Number.Float */ +.codehilite .mh { color: #2aa198 } /* Literal.Number.Hex */ +.codehilite .mi { color: #2aa198 } /* Literal.Number.Integer */ +.codehilite .mo { color: #2aa198 } /* Literal.Number.Oct */ +.codehilite .sa { color: #2aa198 } /* Literal.String.Affix */ +.codehilite .sb { color: #2aa198 } /* Literal.String.Backtick */ +.codehilite .sc { color: #2aa198 } /* Literal.String.Char */ +.codehilite .dl { color: #2aa198 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #93a1a1 } /* Literal.String.Doc */ +.codehilite .s2 { color: #2aa198 } /* Literal.String.Double */ +.codehilite .se { color: #2aa198 } /* Literal.String.Escape */ +.codehilite .sh { color: #2aa198 } /* Literal.String.Heredoc */ +.codehilite .si { color: #2aa198 } /* Literal.String.Interpol */ +.codehilite .sx { color: #2aa198 } /* Literal.String.Other */ +.codehilite .sr { color: #cb4b16 } /* Literal.String.Regex */ +.codehilite .s1 { color: #2aa198 } /* Literal.String.Single */ +.codehilite .ss { color: #2aa198 } /* Literal.String.Symbol */ +.codehilite .bp { color: #268bd2 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #268bd2 } /* Name.Function.Magic */ +.codehilite .vc { color: #268bd2 } /* Name.Variable.Class */ +.codehilite .vg { color: #268bd2 } /* Name.Variable.Global */ +.codehilite .vi { color: #268bd2 } /* Name.Variable.Instance */ +.codehilite .vm { color: #268bd2 } /* Name.Variable.Magic */ +.codehilite .il { color: #2aa198 } /* Literal.Number.Integer.Long */ diff --git a/articles/static/toggle-dark-mode.js b/articles/static/toggle-dark-mode.js new file mode 100644 index 0000000..503ac2e --- /dev/null +++ b/articles/static/toggle-dark-mode.js @@ -0,0 +1,21 @@ +function activateDarkMode() { + console.log("Activating dark mode"); + document.getElementById("code-dark").removeAttribute("disabled"); +} + +function activateLightMode() { + console.log("Activating light mode"); + document.getElementById("code-dark").setAttribute("disabled", "true"); +} + +function darkModeListener(e) { + if (e.matches) { + activateDarkMode(); + } else { + activateLightMode(); + } +} + +let mql = window.matchMedia("(prefers-color-scheme: dark)"); +darkModeListener(mql); +mql.addListener(darkModeListener); diff --git a/articles/templates/articles/base.html b/articles/templates/articles/base.html index ee74d78..094587f 100644 --- a/articles/templates/articles/base.html +++ b/articles/templates/articles/base.html @@ -6,6 +6,9 @@ {% block title %}Home{% endblock %} | Gab's Notes + + + diff --git a/requirements.txt b/requirements.txt index 0546b15..a4ff4a9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ django==3.1 markdown==3.2.2 gunicorn==20.0.4 +Pygments==2.6.1