From d1470e089bfb062aa8d37e9c1a73f2f8ee24328a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 24 Nov 2025 00:19:30 -0500 Subject: [PATCH 1/2] style: use Neovim theme for codeblock highlighting close https://github.com/neovim/neovim.github.io/issues/388 --- README.md | 13 +++ hugo.toml | 11 ++- layouts/_default/baseof.html | 2 + static/css/neovim-hi.css | 102 +++++++++++----------- static/highlight/styles/neovim.min.css | 112 +++++++++++++++++++++++-- 5 files changed, 179 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index e57e640..5e27dd3 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,16 @@ Notes: - The javascript and UI container were setup in [this commit](https://github.com/neovim/neovim.github.io/commit/ce9aef12eb1c98135965e3a9c5c792bf9e506a76). - The docs pages don't use the layout so they also need to [manually include](https://github.com/neovim/neovim/pull/23839) the javascript and define a UI container. - Admin: https://www.algolia.com/apps/X185E15FPG/dashboard +- Codeblock highlighting + - The highlighting for the generated help docs (`/doc/user/`) is done by: + - `static/css/neovim-hi.css` + - `static/highlight/styles/neovim.min.css` + - [gen_help_html.lua](https://github.com/neovim/neovim/blob/a88c7962a82f1427aa90d1c0a08514423516f9f2/src/gen/gen_help_html.lua#L884-L887) + references those css files. + - Hugo can provide highlighting for markdown codeblocks, see the `[markup]` section in `hugo.toml`. + - To list/generate Hugo syntax themes: + ``` + hugo gen chromastyles --style nord > static/css/syntax.css + ``` + - To use the them, commit `static/css/syntax.css` and enable it by uncommenting this line: https://github.com/neovim/neovim.github.io/blob/eb266d7929eff8693cc05ca96732a2daf431e834/layouts/_default/baseof.html#L27 + - And fiddle with the `[markup]` section in `hugo.toml`. diff --git a/hugo.toml b/hugo.toml index 971f399..3fe5b34 100644 --- a/hugo.toml +++ b/hugo.toml @@ -18,9 +18,14 @@ title = 'Neovim' feed = "/news/index.xml" [markup] - [markup.goldmark] - [markup.goldmark.renderer] - unsafe = true + # [markup.goldmark] + # [markup.goldmark.renderer] + # unsafe = true + + # XXX: somehow this accidentally enables use of the Neovim palette (css/neovim-hi.css), + # presumably those css classes match whatever Hugo is using to provide syntax highlighting. + [markup.highlight] + noClasses = false [[menus.main]] name = "About" diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 9982672..fc9f678 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -24,6 +24,8 @@ + + {{ if ne .RelPermalink "/404.html" }} diff --git a/static/css/neovim-hi.css b/static/css/neovim-hi.css index 991fad1..bf7cf73 100644 --- a/static/css/neovim-hi.css +++ b/static/css/neovim-hi.css @@ -1,69 +1,71 @@ +/* + * Neovim color palette for highlighting markdown codeblocks. + * For use with Hugo. + * See also: static/highlight/styles/neovim.min.css + * License: Apache-2.0 + */ :root { - /* regular */ - --hi-black: #565f89; - --hi-red: #8c4351; - --hi-green: #145126; - --hi-yellow: #965027; - --hi-blue: #0f2d86; - --hi-purple: #5a4a78; - --hi-cyan: #166775; - --hi-white: #444; + /* Neovim dark palette - regular/non-bright */ + --hi-black: #2c2e33; + --hi-red: #5e0009; + --hi-green: #015825; + --hi-yellow: #6e5600; + --hi-blue: #005078; + --hi-cyan: #007676; + --hi-white: #4f5258; - /* bright */ - --hi-b-black: #565f89; - --hi-b-red: #8c4351; - --hi-b-green: #005136; - --hi-b-yellow: #8f5e15; - --hi-b-blue: #34548a; - --hi-b-purple: #5329a2; - --hi-b-cyan: #166775; - --hi-b-white: #343b58; + /* Neovim dark palette - bright */ + --hi-b-black: #4f5258; + --hi-b-red: #5e0009; + --hi-b-green: #015825; + --hi-b-yellow: #6e5600; + --hi-b-blue: #005078; + --hi-b-cyan: #007676; + --hi-b-white: #9b9ea4; } @media (prefers-color-scheme: dark) { :root { - /* regular */ - --hi-black: #565f89; - --hi-red: #f7768e; - --hi-green: #73daca; - --hi-yellow: #a7d012 ; - --hi-blue: #7aa2f7; - --hi-purple: #bb9af7; - --hi-cyan: #4baebf; - --hi-white: #9aa5ce; + /* Neovim light palette - regular/non-bright */ + --hi-black: #9b9ea4; + --hi-red: #ffbcb5; + --hi-green: #aaedb7; + --hi-yellow: #f4d88c; + --hi-blue: #9fd8ff; + --hi-cyan: #83efef; + --hi-white: #d7dae1; - /* bright */ - --hi-b-black: #565f89; - --hi-b-red: #f7768e; - --hi-b-green: #9ece6a; - --hi-b-yellow: #ff9e64; - --hi-b-blue: #7aa2f7; - --hi-b-purple: #bb9af7; - --hi-b-cyan: #2ac3de; - --hi-b-white: #c0caf5; + /* Neovim light palette - bright */ + --hi-b-black: #c4c6cd; + --hi-b-red: #ffbcb5; + --hi-b-green: #aaedb7; + --hi-b-yellow: #f4d88c; + --hi-b-blue: #9fd8ff; + --hi-b-cyan: #83efef; + --hi-b-white: #ebeef5; } } -/*! zenburn syntax highlighting - from http://userstyles.org/styles/88895/github-zenburn */ +/*! Neovim-based syntax highlighting */ .highlight,.highlight pre,.highlight table { color: var(--hi-b-white) !important; } -.highlight .err { color: var(--hi-yellow) !important; } -.highlight .cs { color:#dca3a3 !important; } +.highlight .err { color: var(--hi-b-red) !important; } +.highlight .cs { color: var(--hi-cyan) !important; } .highlight .nf { color: var(--hi-b-blue) !important; } -.highlight .c,.highlight .cm,.highlight .c1 { color: var(--hi-white) !important; } +.highlight .c,.highlight .cm,.highlight .c1 { color: #9b9ea4 !important; } .highlight .g,.highlight .l,.highlight .x,.highlight .ge,.highlight .gs,.highlight .ld,.highlight .ni, .highlight .nl,.highlight .nx,.highlight .py,.highlight .n,.highlight .go, -.highlight .h { color: var(--hi-cyan) !important; } -.highlight .k { color: var(--hi-b-yellow) !important; } -.highlight .s1 { color:#bc8383 !important; } -.highlight .nb,.highlight .bp { color: var(--hi-yellow) !important; } -.highlight .nc,.highlight .nn { color:var(--hi-cyan) !important; } -.highlight .o,.highlight .p,.highlight .na,.highlight .ne { color: var(--hi-purple) !important; } -.highlight .gp,.highlight .w,.highlight .gh,.highlight .gu { color:#656555 !important; } +.highlight .h { color: var(--hi-b-cyan) !important; } +.highlight .k { color: var(--hi-b-blue) !important; } +.highlight .s1 { color: var(--hi-b-green) !important; } +.highlight .nb,.highlight .bp { color: var(--hi-b-yellow) !important; } +.highlight .nc,.highlight .nn { color: var(--hi-b-cyan) !important; } +.highlight .o,.highlight .p,.highlight .na,.highlight .ne { color: var(--hi-b-blue) !important; } +.highlight .gp,.highlight .w,.highlight .gh,.highlight .gu { color: var(--hi-white) !important; } .highlight .cp,.highlight .s,.highlight .sb,.highlight .sc,.highlight .sd,.highlight .s2,.highlight .se, .highlight .sh,.highlight .si,.highlight .ss,.highlight .kc,.highlight .kd,.highlight .kn,.highlight .kp, -.highlight .kr,.highlight .kt,.highlight .nt,.highlight .ow { color: var(--hi-green) !important; } +.highlight .kr,.highlight .kt,.highlight .nt,.highlight .ow { color: var(--hi-b-green) !important; } .highlight .gr,.highlight .gt,.highlight .m,.highlight .mf,.highlight .mh,.highlight .mi, -.highlight .mo,.highlight .sr,.highlight .il { color:#9c6363 !important; } +.highlight .mo,.highlight .sr,.highlight .il { color: var(--hi-b-cyan) !important; } .highlight .no,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi,.highlight .nd, -.highlight .sx { color:#dfaf8f !important; } +.highlight .sx { color: var(--hi-b-yellow) !important; } diff --git a/static/highlight/styles/neovim.min.css b/static/highlight/styles/neovim.min.css index 36a0c3e..4528925 100644 --- a/static/highlight/styles/neovim.min.css +++ b/static/highlight/styles/neovim.min.css @@ -1,9 +1,105 @@ /*! - Theme: neovim - origin: https://github.com/highlightjs/highlight.js/blob/main/src/styles/tokyo-night-dark.css - Description: Original highlight.js style - Author: (c) Henri Vandersleyen - Author: (c) Dave Lage - License: BSD 3-Clause License - Touched: 2022 -*/:root{--hljs-black:#565f89;--hljs-red:#8c4351;--hljs-green:#33635c;--hljs-yellow:#965027;--hljs-blue:#0f2d86;--hljs-purple:#5a4a78;--hljs-cyan:#166775;--hljs-white:#444;--hljs-b-black:#565f89;--hljs-b-red:#8c4351;--hljs-b-green:#005136;--hljs-b-yellow:#8f5e15;--hljs-b-blue:#34548a;--hljs-b-purple:#5329a2;--hljs-b-cyan:#166775;--hljs-b-white:#343b58}@media (color-index:48){:root{--hljs-black:#565f89;--hljs-red:#f7768e;--hljs-green:#73daca;--hljs-yellow:#e18e11;--hljs-blue:#7aa2f7;--hljs-purple:#bb9af7;--hljs-cyan:#2ac3de;--hljs-white:#9aa5ce;--hljs-b-black:#565f89;--hljs-b-red:#f7768e;--hljs-b-green:#9ece6a;--hljs-b-yellow:#ff9e64;--hljs-b-blue:#7aa2f7;--hljs-b-purple:#bb9af7;--hljs-b-cyan:#2ac3de;--hljs-b-white:#c0caf5}}@media (color:48842621){:root{--hljs-black:#565f89;--hljs-red:#f7768e;--hljs-green:#73daca;--hljs-yellow:#e18e11;--hljs-blue:#7aa2f7;--hljs-purple:#bb9af7;--hljs-cyan:#2ac3de;--hljs-white:#9aa5ce;--hljs-b-black:#565f89;--hljs-b-red:#f7768e;--hljs-b-green:#9ece6a;--hljs-b-yellow:#ff9e64;--hljs-b-blue:#7aa2f7;--hljs-b-purple:#bb9af7;--hljs-b-cyan:#2ac3de;--hljs-b-white:#c0caf5}}@media (color-index:48){:root{--hljs-black:#565f89;--hljs-red:#f7768e;--hljs-green:#73daca;--hljs-yellow:#e18e11;--hljs-blue:#7aa2f7;--hljs-purple:#bb9af7;--hljs-cyan:#2ac3de;--hljs-white:#9aa5ce;--hljs-b-black:#565f89;--hljs-b-red:#f7768e;--hljs-b-green:#9ece6a;--hljs-b-yellow:#ff9e64;--hljs-b-blue:#7aa2f7;--hljs-b-purple:#bb9af7;--hljs-b-cyan:#2ac3de;--hljs-b-white:#c0caf5}}@media (color:48842621){:root{--hljs-black:#565f89;--hljs-red:#f7768e;--hljs-green:#73daca;--hljs-yellow:#e18e11;--hljs-blue:#7aa2f7;--hljs-purple:#bb9af7;--hljs-cyan:#2ac3de;--hljs-white:#9aa5ce;--hljs-b-black:#565f89;--hljs-b-red:#f7768e;--hljs-b-green:#9ece6a;--hljs-b-yellow:#ff9e64;--hljs-b-blue:#7aa2f7;--hljs-b-purple:#bb9af7;--hljs-b-cyan:#2ac3de;--hljs-b-white:#c0caf5}}@media (prefers-color-scheme:dark){:root{--hljs-black:#565f89;--hljs-red:#f7768e;--hljs-green:#73daca;--hljs-yellow:#e18e11;--hljs-blue:#7aa2f7;--hljs-purple:#bb9af7;--hljs-cyan:#2ac3de;--hljs-white:#9aa5ce;--hljs-b-black:#565f89;--hljs-b-red:#f7768e;--hljs-b-green:#9ece6a;--hljs-b-yellow:#ff9e64;--hljs-b-blue:#7aa2f7;--hljs-b-purple:#bb9af7;--hljs-b-cyan:#2ac3de;--hljs-b-white:#c0caf5}}.hljs-meta,.hljs-comment{color:#444;color:var(--hljs-white)}.hljs-tag,.hljs-doctag,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-template-tag,.hljs-selector-pseudo,.hljs-selector-attr,.hljs-variable.language_,.hljs-deletion{color:var(--hlsjs-red)}.hljs-variable,.hljs-template-variable,.hljs-number,.hljs-literal,.hljs-type,.hljs-params,.hljs-link{color:#0f2d86;color:var(--hljs-blue)}.hljs-built_in,.hljs-attribute{color:#8f5e15;color:var(--hljs-b-yellow);color:#005136;color:var(--hljs-b-green)}.hljs-selector-tag{color:#166775;color:var(--hljs-b-cyan)}.hljs-keyword,.hljs-title.function_,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-subst,.hljs-property{color:#0f2d86;color:var(--hljs-blue)}.hljs-selector-tag{color:#33635c;color:var(--hljs-green)}.hljs-quote,.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#005136;color:var(--hljs-b-green)}.hljs-code,.hljs-function,.hljs-formula,.hljs-section{color:#0f2d86;color:var(--hljs-blue)}.hljs-name,.hljs-keyword,.hljs-operator,.hljs-keyword,.hljs-char.escape_,.hljs-attr{color:#166775;color:var(--hljs-cyan)}.hljs-punctuation{color:#343b58;color:var(--hljs-b-white)}.hljs{color:#343b58;color:var(--hljs-b-white)}@media (color-index:48){.hljs{color:#343b58;color:var(--hljs-b-white)}}@media (color:48842621){.hljs{color:#343b58;color:var(--hljs-b-white)}}@media (color-index:48){.hljs{color:#343b58;color:var(--hljs-b-white)}}@media (color:48842621){.hljs{color:#343b58;color:var(--hljs-b-white)}}@media (prefers-color-scheme:dark){.hljs{color:#343b58;color:var(--hljs-b-white)}}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} + * Neovim color palette for highlighting markdown codeblocks. + * For use with "highlight.js" (used by the :help docs generated HTML). + * See also: static/css/neovim-hi.css + * License: Apache-2.0 + */ + +:root { + --hljs-black: #2c2e33; + --hljs-red: #5e0009; + --hljs-green: #015825; + --hljs-yellow: #6e5600; + --hljs-blue: #005078; + --hljs-cyan: #007676; + --hljs-white: #4f5258; + --hljs-b-black: #4f5258; + --hljs-b-red: #5e0009; + --hljs-b-green: #015825; + --hljs-b-yellow: #6e5600; + --hljs-b-blue: #005078; + --hljs-b-cyan: #007676; + --hljs-b-white: #9b9ea4 +} + +@media (prefers-color-scheme: dark) { + :root { + --hljs-black: #9b9ea4; + --hljs-red: #ffbcb5; + --hljs-green: #aaedb7; + --hljs-yellow: #f4d88c; + --hljs-blue: #9fd8ff; + --hljs-cyan: #83efef; + --hljs-white: #d7dae1; + --hljs-b-black: #c4c6cd; + --hljs-b-red: #ffbcb5; + --hljs-b-green: #aaedb7; + --hljs-b-yellow: #f4d88c; + --hljs-b-blue: #9fd8ff; + --hljs-b-cyan: #83efef; + --hljs-b-white: #ebeef5 + } + + .hljs-meta, .hljs-comment { + color: #9b9ea4 + } + + .hljs-tag, .hljs-doctag, .hljs-selector-id, .hljs-selector-class, .hljs-regexp, .hljs-template-tag, .hljs-selector-pseudo, .hljs-selector-attr, .hljs-variable.language_, .hljs-deletion { + color: var(--hljs-b-red) + } + + .hljs-variable, .hljs-template-variable, .hljs-number, .hljs-literal, .hljs-type, .hljs-params, .hljs-link { + color: #9fd8ff; + color: var(--hljs-b-blue) + } + + .hljs-built_in, .hljs-attribute { + color: #f4d88c; + color: var(--hljs-b-yellow); + color: #aaedb7; + color: var(--hljs-b-green) + } + + .hljs-selector-tag { + color: #83efef; + color: var(--hljs-b-cyan) + } + + .hljs-keyword, .hljs-title.function_, .hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__, .hljs-subst, .hljs-property { + color: #9fd8ff; + color: var(--hljs-b-blue) + } + + .hljs-quote, .hljs-string, .hljs-symbol, .hljs-bullet, .hljs-addition { + color: #aaedb7; + color: var(--hljs-b-green) + } + + .hljs-code, .hljs-function, .hljs-formula, .hljs-section { + color: #9fd8ff; + color: var(--hljs-b-blue) + } + + .hljs-name, .hljs-keyword, .hljs-operator, .hljs-char.escape_, .hljs-attr { + color: #83efef; + color: var(--hljs-b-cyan) + } + + .hljs-punctuation { + color: #ebeef5; + color: var(--hljs-b-white) + } + + .hljs { + color: #ebeef5; + color: var(--hljs-b-white) + } +} + +.hljs-emphasis { + font-style: italic +} + +.hljs-strong { + font-weight: bold +} From 6b8639c7a24d113d918b4fb585cb5f80392ca493 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 24 Nov 2025 00:48:28 -0500 Subject: [PATCH 2/2] style: adjust colors - light-mode comments => gray - light-mode normal text => darker - light-mode strings => quirky seagreen instead of boring forest green --- static/highlight/styles/neovim.min.css | 85 ++++++++++++-------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/static/highlight/styles/neovim.min.css b/static/highlight/styles/neovim.min.css index 4528925..b1bb3df 100644 --- a/static/highlight/styles/neovim.min.css +++ b/static/highlight/styles/neovim.min.css @@ -3,19 +3,20 @@ * For use with "highlight.js" (used by the :help docs generated HTML). * See also: static/css/neovim-hi.css * License: Apache-2.0 - */ +*/ :root { + /* Light-mode palette - default */ --hljs-black: #2c2e33; --hljs-red: #5e0009; - --hljs-green: #015825; + --hljs-green: #0daa80; --hljs-yellow: #6e5600; --hljs-blue: #005078; --hljs-cyan: #007676; --hljs-white: #4f5258; --hljs-b-black: #4f5258; --hljs-b-red: #5e0009; - --hljs-b-green: #015825; + --hljs-b-green: #0daa80; --hljs-b-yellow: #6e5600; --hljs-b-blue: #005078; --hljs-b-cyan: #007676; @@ -24,6 +25,7 @@ @media (prefers-color-scheme: dark) { :root { + /* Dark-mode palette */ --hljs-black: #9b9ea4; --hljs-red: #ffbcb5; --hljs-green: #aaedb7; @@ -39,61 +41,50 @@ --hljs-b-cyan: #83efef; --hljs-b-white: #ebeef5 } +} - .hljs-meta, .hljs-comment { - color: #9b9ea4 - } +.hljs-meta, .hljs-comment { + color: #4f5258 +} - .hljs-tag, .hljs-doctag, .hljs-selector-id, .hljs-selector-class, .hljs-regexp, .hljs-template-tag, .hljs-selector-pseudo, .hljs-selector-attr, .hljs-variable.language_, .hljs-deletion { - color: var(--hljs-b-red) - } +.hljs-tag, .hljs-doctag, .hljs-selector-id, .hljs-selector-class, .hljs-regexp, .hljs-template-tag, .hljs-selector-pseudo, .hljs-selector-attr, .hljs-variable.language_, .hljs-deletion { + color: var(--hljs-b-red) +} - .hljs-variable, .hljs-template-variable, .hljs-number, .hljs-literal, .hljs-type, .hljs-params, .hljs-link { - color: #9fd8ff; - color: var(--hljs-b-blue) - } +.hljs-variable, .hljs-template-variable, .hljs-number, .hljs-literal, .hljs-type, .hljs-params, .hljs-link { + color: var(--hljs-b-cyan) +} - .hljs-built_in, .hljs-attribute { - color: #f4d88c; - color: var(--hljs-b-yellow); - color: #aaedb7; - color: var(--hljs-b-green) - } +.hljs-built_in, .hljs-attribute { + color: var(--hljs-b-green) +} - .hljs-selector-tag { - color: #83efef; - color: var(--hljs-b-cyan) - } +.hljs-selector-tag { + color: var(--hljs-b-cyan) +} - .hljs-keyword, .hljs-title.function_, .hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__, .hljs-subst, .hljs-property { - color: #9fd8ff; - color: var(--hljs-b-blue) - } +.hljs-keyword, .hljs-title.function_, .hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__, .hljs-subst, .hljs-property { + color: var(--hljs-b-blue) +} - .hljs-quote, .hljs-string, .hljs-symbol, .hljs-bullet, .hljs-addition { - color: #aaedb7; - color: var(--hljs-b-green) - } +.hljs-quote, .hljs-string, .hljs-symbol, .hljs-bullet, .hljs-addition { + color: var(--hljs-b-green) +} - .hljs-code, .hljs-function, .hljs-formula, .hljs-section { - color: #9fd8ff; - color: var(--hljs-b-blue) - } +.hljs-code, .hljs-function, .hljs-formula, .hljs-section { + color: var(--hljs-b-blue) +} - .hljs-name, .hljs-keyword, .hljs-operator, .hljs-char.escape_, .hljs-attr { - color: #83efef; - color: var(--hljs-b-cyan) - } +.hljs-name, .hljs-keyword, .hljs-operator, .hljs-char.escape_, .hljs-attr { + color: var(--hljs-b-cyan) +} - .hljs-punctuation { - color: #ebeef5; - color: var(--hljs-b-white) - } +.hljs-punctuation { + color: var(--hljs-black) +} - .hljs { - color: #ebeef5; - color: var(--hljs-b-white) - } +.hljs { + color: var(--hljs-black) } .hljs-emphasis {