[feat] initial draft of a blogpost, added syntax highglighting

This commit is contained in:
mangoiv 2023-11-16 01:35:46 +01:00
parent 8fa85ef2a4
commit 60e1a06899
Signed by: mangoiv
SSH key fingerprint: SHA256:JlsRe4zkmS13EG6gMFNjv13Lw5rtoMPu3Lq69ZQTKF8
14 changed files with 2184 additions and 141 deletions

2
.envrc
View file

@ -1 +1 @@
use flake
use flake . -Lv

View file

@ -32,3 +32,7 @@ You may know me from the internet as this little fella:
I've switched over to [sourcehut](https://sr.ht/) for everything unrelated to keyboards, and I highly recommend giving it a look.
Other alternatives to GitHub include [codeberg](https://codeberg.org/) or [gitlab](https://gitlab.com/).
### contact me
You can [send a mail to contact@mangoiv.com](mailto:contact@mangoiv.com) or [ping me on mastodon](https://elk.zone/functional.cafe/@mangoiv).

View file

@ -1,5 +0,0 @@
---
title: contact
---
You can [send a mail to contact@mangoiv.com](mailto:contact@mangoiv.com) or [ping me on mastodon](https://elk.zone/functional.cafe/@mangoiv).

View file

@ -1,17 +0,0 @@
---
$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
version: '0.2'
dictionaryDefinitions:
- name: ignored-words
path: './ignored-words'
addWords: true
dictionaries:
- ignored-words
ignorePaths:
- './css'
- './images'
- './**/*.nix'
- './\.*'
- '*.hs'
- '*.cabal'

View file

@ -1,5 +1,24 @@
{
"nodes": {
"devshell": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
},
"locked": {
"lastModified": 1698410321,
"narHash": "sha256-MphuSlgpmKwtJncGMohryHiK55J1n6WzVQ/OAfmfoMc=",
"owner": "numtide",
"repo": "devshell",
"rev": "1aed986e3c81a4f6698e85a7452cbfcc4b31a36e",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
@ -18,7 +37,7 @@
},
"flake-utils": {
"inputs": {
"systems": "systems"
"systems": "systems_2"
},
"locked": {
"lastModified": 1685518550,
@ -57,11 +76,11 @@
},
"haskell-flake": {
"locked": {
"lastModified": 1691763544,
"narHash": "sha256-QQsSI5VXm0bBijeGSXXNf4fyw76/XmN67NGbmTCx71s=",
"lastModified": 1699388095,
"narHash": "sha256-uutZJWtd6rKwoLYLFGsjrA2zu06uRdGC//FANb4azgU=",
"owner": "srid",
"repo": "haskell-flake",
"rev": "f16e7ac05b1f22b66ef05b7fcc8a96281bb2b749",
"rev": "7029034b00bd7c9225d74915a6a53e5b44b4a1d3",
"type": "github"
},
"original": {
@ -72,15 +91,15 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1692343221,
"narHash": "sha256-aCQE0eXmQ36ouEFfRf4gxGHELo/GFW2UzGj8DU7CtfU=",
"owner": "nixos",
"lastModified": 1677383253,
"narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "babf56d5b24a91526a208cad1dde3d6ddbe4878c",
"rev": "9952d6bc395f5841262b006fbace8dd7e143b634",
"type": "github"
},
"original": {
"owner": "nixos",
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
@ -89,11 +108,11 @@
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1690881714,
"narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=",
"lastModified": 1698611440,
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9e1960bc196baf6881340d53dccb203a951745a2",
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
"type": "github"
},
"original": {
@ -121,6 +140,22 @@
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1700014976,
"narHash": "sha256-dSGpS2YeJrXW5aH9y7Abd235gGufY3RuZFth6vuyVtU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "592047fc9e4f7b74a4dc85d1b9f5243dfe4899e3",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1689261696,
"narHash": "sha256-LzfUtFs9MQRvIoQ3MfgSuipBVMXslMPH/vZ+nM40LkA=",
@ -141,11 +176,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1690933134,
"narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
"lastModified": 1698882062,
"narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
"rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
"type": "github"
},
"original": {
@ -159,15 +194,15 @@
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"gitignore": "gitignore",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_3",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1692274144,
"narHash": "sha256-BxTQuRUANQ81u8DJznQyPmRsg63t4Yc+0kcyq6OLz8s=",
"lastModified": 1700064067,
"narHash": "sha256-1ZWNDzhu8UlVCK7+DUN9dVQfiHX1bv6OQP9VxstY/gs=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa",
"rev": "e558068cba67b23b4fbc5537173dbb43748a17e8",
"type": "github"
},
"original": {
@ -178,8 +213,9 @@
},
"root": {
"inputs": {
"devshell": "devshell",
"haskell-flake": "haskell-flake",
"nixpkgs": "nixpkgs",
"nixpkgs": "nixpkgs_2",
"parts": "parts",
"pre-commit-hooks": "pre-commit-hooks"
}
@ -198,6 +234,21 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View file

@ -4,6 +4,7 @@
parts.url = "github:hercules-ci/flake-parts";
pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
haskell-flake.url = "github:srid/haskell-flake";
devshell.url = "github:numtide/devshell";
};
outputs = inputs:
inputs.parts.lib.mkFlake {inherit inputs;} {
@ -11,33 +12,58 @@
imports = [
inputs.haskell-flake.flakeModule
inputs.pre-commit-hooks.flakeModule
inputs.devshell.flakeModule
];
perSystem = {
pkgs,
lib,
config,
...
}: {
haskellProjects.default = {
devShell.mkShellArgs.shellHook = config.pre-commit.installationScript;
packages = {
# hlint.source = "3.6.1";
# fourmolu.source = "0.13.0.0";
devshells.default = let
port = 8000;
in {
commands = [
{
name = "fmt";
help = "format all";
command = "pre-commit run --all";
}
{
name = "watch";
help = "watch website";
command = "cabal run website -- watch --port ${toString port}";
}
{
name = "open";
help = "open website";
command = "${lib.getExe' pkgs.xdg-utils "xdg-open"} http://localhost:${toString port}";
}
];
devshell = {
startup = {
pre-commit.text = config.pre-commit.installationScript;
};
packagesFrom = [config.devShells.ghc94];
};
};
haskellProjects.ghc94 = {
packages = {};
settings = {
website.haddock = true;
# fourmolu.check = false;
};
};
# haskell-flake doesn't set the default package, but you can do it here.
packages.generator = config.packages.website;
packages.generator = config.packages.ghc94-website;
packages.default = pkgs.stdenv.mkDerivation {
name = "website-built";
src = ./.;
LC_ALL = "C.UTF-8";
buildPhase = ''
${config.packages.website}/bin/site build
${lib.getExe' config.packages.ghc94-website "site"} build
'';
installPhase = ''
mkdir $out
@ -54,10 +80,6 @@
alejandra.enable = true;
statix.enable = true;
deadnix.enable = true;
cspell.enable = true;
rome.enable = true;
};
};
};

View file

@ -1,40 +0,0 @@
Avenir
bies
bigbigbig
blockquote
Cantarell
Chiffre
chota
clearfix
codeberg
Consolas
dosis
Dosis
evenodd
fieldset
Fira
flexbox
fourmolu
gapless
Hakyll
iframe
lightoff
lighton
Lucida
mangoiv's
marginless
Neue
nowrap
paddingless
parens
Roboto
samp
Segoe
sourcehut
stylesheet
Tahoma
tfoot
thead
truetype
Dracu
mangoiv

View file

@ -22,6 +22,8 @@ const setDark = () => {
setToColor("#6272a4", githubPath);
setToColor("#8be9fd", mastodonPath);
setToColor("#282a36", mastodonMPath);
removeStyleSheet();
addStyleSheet("/css/syntax-dark.css");
};
const setLight = () => {
@ -31,8 +33,28 @@ const setLight = () => {
setToColor("#4c4f69", githubPath);
setToColor("#1e66f5", mastodonPath);
setToColor("#eff1f5", mastodonMPath);
removeStyleSheet();
addStyleSheet("/css/syntax-light.css");
};
const addStyleSheet = (path) => {
var headID = document.getElementsByTagName("head")[0];
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = path;
cssNode.media = 'screen';
cssNode.class = 'syntax'
headID.appendChild(cssNode);
};
const removeStyleSheet = () => {
const elements = document.querySelectorAll('link.syntax');
elements.forEach((element) => {
element.remove();
});
}
if (mode === "dark") {
setDark();
} else if (mode === "light") {

112
posts/2023-11-15-webshop.md Normal file
View file

@ -0,0 +1,112 @@
---
title: webshop
---
### ⚠️ this is still a work in progress ⚠️
# How to build a Webshop in Haskell + Nix
## Chapter 1: Why would you do that?
Well first of all, I don't know why *you* would, but here is my ordeal:
- a family member (for the rest of the post, I will call him Udo) wants to sell motorcycle tours
- for obvious reasons (*"he does something with computers"*) they asked me how one could do that
- I told them to use wordpress + some store integration which I thought would be the obvious solution
- they tried to make something but struggled for ~ 3 months before asking me whether I could do it
So now there were two possibilities: either spent days in pain and agony trying to click something together
in shopify or wordpress and get an unsatisfying result which also costs a fortune in fees monthly, so I
asked them whether they can wait another month if I did it for them, *my way*.
And that's how it was decided.
## Chapter 2: Approaching the Beast.
Right at the beginning, I was fairly clueless on how to approach the problem but at least I had a fairly clear
set of requirements:
- one should be able to book a motorcycling tour from one of the `n` offerings
- each tour should have a nice blog-post attached to it, describing what this tour is going to offer,
including a lot of pictures that I got provided by Udo
- their should also be a possibility to fairly quickly insert longer texts, add new tours, edit customers,
the usual business
- there was already an example site which I should "copy as good as possible" but as their only option
was booking via a <a href="https://jotform.com" target="_blank">jotform</a>, that did not sound like
a hard task
Given these requirements, I went ahead and asked the Haskell magical girls on how to do this and promptly
got some helpful tips which I was going to follow closely.
Reassured that I could do it, I sat down and started to search for *the perfect stack*.
## Chapter 3: Choices.
To understand the way I went ahead with this, it's important to note, that I am not a
[Simple Haskell](https://www.simplehaskell.org/) advocate. I like playing with types, even though Haskell as a
language but also GHC as a compiler has their limitations. More about that later.
### A webserver
First of all I decided *against* [Yesod](https://flora.pm/packages/@hackage/yesod) (because I don't like Template
Haskell, sue me) and *for* [servant](https://flora.pm/packages/@hackage/servant) mainly because it's probably the most
mature and production ready alternative. If you want to get started with servant, be sure to check out
[docs](https://docs.servant.dev/en/stable/); if you don't understand some of the things that are going on in the Api types,
don't be afraid, you can treat these as a rather opaque eDSL, understanding will come with time.
### A database(-library)
To store customers, tours and bookings I also needed a database. I chose [postgres](https://www.postgresql.org/)
for familiarity reasons, then I started to search for libraries to use on the Haskell side of things. I knew there
was [beam](https://flora.pm/packages/@hackage/beam) which people recommended against, I cannot verify the objections
because I never tried it. Then many people recommended [postgresql-simple](https://flora.pm/packages/@hackage/postgresql-simple)
which I'm sure is a great choice, but for my taste, it was a tad *too* simple; I did not want to use a strongly typed
language and then have no guarantees that what was coming out of my query would actually be the right thing, or that
the query itself was even syntactically correct at the time of writing.
I also had a look at the less popular [rel8](https://flora.pm/packages/@hackage/rel8) which was absolutely was too my taste;
for representing types, it uses a [barbies](https://flora.pm/packages/@hackage/barbies) like approach which goes approximately
like this:
```hs
-- have a Customer type, parametrized
-- over some `f :: Type -> Type`
type Customer :: (Type -> Type) -> Type
data Customer f
= MkCustomer
{ name :: f Text
, age :: f Word8 -- only 8; sad, isn't it
}
-- a customer that has all its field present
-- this corresponds to how you would declare
-- Customer normally
type CustomerI = Customer Identity
customerI :: CustomerI
customerI
= MkCustomer
{ name = "joe" -- this is no mistake, `Identity` derives both
, age = 69 -- IsString and Num for string literal and number
} -- overloading respectively.
-- a customer with optional fields
-- (perhaps before parsing)
type CustomerM = Customer Maybe
customerM :: CustomerM
customerM
= MkCustomer
{ name = Just "joe"
, age = Nothing
}
-- a customer in some database
type CustomerDB = Customer Row
```
It's really that simple, but with some glue it's really quite elegant.
`rel8` also offers a really nice eDSL to write sql expressions, that will remind a Haskell user of writing code in
the `List` Monad.

112
site.hs
View file

@ -1,59 +1,89 @@
--------------------------------------------------------------------------------
{-# LANGUAGE BlockArguments #-}
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Monoid (mappend)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Data.ByteString.Lazy qualified as BS
import Hakyll
import Skylighting.Styles
import Text.Pandoc.Highlighting
--------------------------------------------------------------------------------
main :: IO ()
main = hakyll $ do
match "images/*" do
route idRoute
compile copyFileCompiler
main = do
hakyll do
match "images/*" do
route idRoute
compile copyFileCompiler
match "css/*" do
route idRoute
compile compressCssCompiler
match "css/*" do
route idRoute
compile compressCssCompiler
match "css/fonts/*" do
route idRoute
compile copyFileCompiler
match "css/fonts/*" do
route idRoute
compile copyFileCompiler
match "js/*" do
route idRoute
compile copyFileCompiler
match "js/*" do
route idRoute
compile copyFileCompiler
match (fromList ["about.md", "contact.md"]) do
route $ setExtension "html"
compile $
pandocCompiler
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
match "about.md" do
route $ setExtension "html"
compile $
pandocCompiler
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
match "posts/*" do
route $ setExtension "html"
compile $
pandocCompiler
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls
match "themes/dracula.json" do
route (constRoute "css/syntax-dark.css")
compile do
Right draculaTheme <- traverse parseTheme <$> getResourceLBS
pure $ styleToCss <$> draculaTheme
match "index.html" do
route idRoute
compile do
posts <- recentFirst =<< loadAll "posts/*"
let indexCtx =
listField "posts" postCtx (return posts)
<> defaultContext
match "themes/latte.json" do
route (constRoute "css/syntax-light.css")
compile do
Right latteTheme <- traverse parseTheme <$> getResourceLBS
pure $ styleToCss <$> latteTheme
getResourceBody
>>= applyAsTemplate indexCtx
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
create ["posts.html"] do
route idRoute
compile do
posts <- recentFirst =<< loadAll "posts/*"
let archiveCtx =
mconcat
[ listField "posts" postCtx (return posts)
, constField "title" "Archives"
, defaultContext
]
makeItem ""
>>= loadAndApplyTemplate "templates/archive.html" archiveCtx
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
>>= relativizeUrls
match "templates/*" $ compile templateBodyCompiler
match "posts/*" do
route $ setExtension "html"
compile $
pandocCompiler
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls
match "index.html" do
route idRoute
compile do
posts <- recentFirst =<< loadAll "posts/*"
let indexCtx =
listField "posts" postCtx (return posts)
<> defaultContext
getResourceBody
>>= applyAsTemplate indexCtx
>>= loadAndApplyTemplate "templates/default.html" indexCtx
>>= relativizeUrls
match "templates/*" $ compile templateBodyCompiler
--------------------------------------------------------------------------------
postCtx :: Context String

View file

@ -10,8 +10,9 @@
<meta property="og:image" content="https://mangoiv.com/images/mango-big.png">
<meta property="og:url" content="https://mangoiv.com/">
<title>mangoiv's webpage - $title$</title>
<link rel="stylesheet" type="text/css" href="css/chota.min.css" />
<link rel="stylesheet" type="text/css" href="css/default.css" />
<link rel="stylesheet" type="text/css" href="/css/chota.min.css" />
<link rel="stylesheet" type="text/css" href="/css/default.css" />
<link rel="stylesheet" type="text/css" href="/css/syntax-dark.css" />
<style>
body.dark {
--bg-color: #282a36;
@ -20,7 +21,7 @@
--color-lightGrey: #6272a4;
--color-grey: #8be9fd;
--color-darkGrey: #ff79c6;
--color-error: #ff5555;
--color-error: #f8f8f2;
--color-success: #50fa7b;
--font-color: #f8f8f2;
}
@ -31,7 +32,7 @@
--color-lightGrey: #bac2de;
--color-grey: #6c7086;
--color-darkGrey: #313244;
--color-error: #d20f39;
--color-error: #dc8a78;
--color-success: #40a02b;
--font-color: #4c4f69;
--grid-maxWidth: 120rem;
@ -54,7 +55,7 @@
<div class="tabs">
<a href="/">home</a>
<a href="/about.html">about</a>
<a href="/contact.html">contact</a>
<a href="/posts.html">posts</a>
</div>
</div>
<div class="nav-right">

705
themes/dracula.json Normal file
View file

@ -0,0 +1,705 @@
{
"custom-styles": {
"Alerts": {
"Region Marker": {
"selected-text-color": "#6db8c7",
"text-color": "#6db8c7"
}
},
"Apache Configuration": {
"Directives": {
"bold": false
}
},
"Bash": {
"Path": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Redirection": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Variable": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
}
},
"C": {
"Prep. Lib": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
}
},
"C++": {
"Qt Macros": {
"bold": false,
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
}
},
"CMake": {
"Builtin Variable": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
}
},
"CSS": {
"Color": {
"bold": false
},
"Property": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Selector Class": {
"italic": true
},
"Selector Id": {
"bold": false,
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Selector Pseudo": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Selector Tag": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Unit": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
}
},
"D": {
"Attribute": {
"bold": false
},
"Declarator": {
"bold": false
},
"Deprecated": {
"bold": false
},
"Expression": {
"bold": false
},
"Module": {
"bold": false
},
"Property": {
"bold": false
},
"Template": {
"bold": false
}
},
"Diff": {
"Added line": {
"selected-text-color": "#5fde38",
"text-color": "#50fa7b"
},
"Changed line (new)": {
"background-color": "#50fa7b",
"selected-text-color": "#5fde38",
"text-color": "#50fa7b"
},
"Changed line (old)": {
"selected-text-color": "#e66eb4",
"text-color": "#ff79c6"
},
"Removed line": {
"selected-text-color": "#e66eb4",
"text-color": "#ff79c6"
}
},
"Doxygen": {
"Custom Tags": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"Description": {
"selected-text-color": "#c58e53",
"text-color": "#c58e53"
},
"Entities": {
"bold": false
},
"HTML Tag": {
"bold": false,
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"Region": {
"selected-text-color": "#6db8c7",
"text-color": "#6db8c7"
},
"Tags": {
"bold": false,
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"Word": {
"bold": false,
"selected-text-color": "#c58e53",
"text-color": "#c58e53"
}
},
"GNU Assembler": {
"Label": {
"underline": true
}
},
"Go": {
"Builtin Function": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
}
},
"HTML": {
"Doctype": {
"bold": false,
"italic": false,
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
}
},
"ISO C++": {
"Prep. Lib": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Standard Suffix": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"UDL Numeric Suffix": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"UDL String Suffix": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
}
},
"Intel x86 (NASM)": {
"Label": {
"underline": true
},
"Registers": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
}
},
"JSON": {
"Style_Keyword": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Style_String_Key": {
"italic": false
}
},
"JavaScript": {
"Built-in Objects": {
"italic": true
},
"Function (Built-in)": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Object Member": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
}
},
"JavaScript React (JSX)": {
"Attribute": {
"italic": true
},
"Component Tag": {
"bold": false,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
}
},
"Makefile": {
"Operator": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Prereq": {
"italic": false,
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Target": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Variable": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
}
},
"Markdown": {
"Blockquote: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Email": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Emphasis Text": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Header H1": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Header H2": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Header H3": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Header H4": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Header H5": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Header H6": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Inline Image": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
},
"Inline Image: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"List: Emphasis Text": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"List: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"List: Strong Text": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
},
"Normal Text: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Reference Image": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
},
"Reference-Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Reference-Link Name": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6",
"underline": false
},
"Reference-Link Target": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Reference-Link Target: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Reference-Link: Link": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Strong Text": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
}
},
"Modelines": {
"Variable": {
"selected-text-color": "#c58e53",
"text-color": "#c58e53"
}
},
"PHP/PHP": {
"Backslash Code": {
"bold": false,
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Control Structures": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Library Constant": {
"bold": false,
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Special Variable": {
"bold": false,
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
},
"Variable": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
}
},
"Python": {
"Builtin Function": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Special Variable": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
}
},
"QMake": {
"Backslash Code": {
"bold": false
},
"Predefined Variable": {
"bold": false,
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
}
},
"Ruby": {
"Access Control": {
"bold": false,
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Default globals": {
"bold": false
},
"Definition": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Global Constant": {
"bold": false,
"italic": true,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Kernel methods": {
"bold": false,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Message": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Module mixin methods": {
"bold": false
},
"Pseudo variable": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
}
},
"Rust": {
"Attribute": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
},
"CConstant": {
"bold": false
},
"CType": {
"italic": true,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Constant": {
"bold": false
},
"Definition": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Lifetime": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Macro": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Scope": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
},
"Self": {
"italic": true,
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Trait": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
}
},
"SPDX-Comments": {
"SPDX Deprecated License": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"SPDX Deprecated License Exception": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"SPDX License": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"SPDX License Exception": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"SPDX Tag": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
},
"SPDX Value": {
"selected-text-color": "#d465a7",
"text-color": "#d465a7"
}
},
"TypeScript": {
"Built-in Objects": {
"italic": true
},
"Function (Built-in)": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Object Member": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
}
},
"TypeScript React (TSX)": {
"Attribute": {
"italic": true
},
"Component Tag": {
"bold": false,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
}
},
"YAML": {
"Attribute": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Key": {
"bold": false,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"List": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
}
}
},
"editor-colors": {
"BackgroundColor": "#282a36",
"BracketMatching": "#7c62a5",
"CodeFolding": "#44475a",
"CurrentLine": "#44475a",
"CurrentLineNumber": "#f8f8f2",
"IconBorder": "#282a36",
"IndentationLine": "#6272a4",
"LineNumbers": "#6272a4",
"MarkBookmark": "#8be9fd",
"MarkBreakpointActive": "#ff5555",
"MarkBreakpointDisabled": "#bd93f9",
"MarkBreakpointReached": "#f1fa8c",
"MarkError": "#ff5555",
"MarkExecution": "#44475a",
"MarkWarning": "#ffb86c",
"ModifiedLines": "#ff79c6",
"ReplaceHighlight": "#2c8843",
"SavedLines": "#50fa7b",
"SearchHighlight": "#566591",
"Separator": "#45474e",
"SpellChecking": "#ff5555",
"TabMarker": "#6272a4",
"TemplateBackground": "#282a36",
"TemplateFocusedPlaceholder": "#282a36",
"TemplatePlaceholder": "#282a36",
"TemplateReadOnlyPlaceholder": "#44475a",
"TextSelection": "#44475a",
"WordWrapMarker": "#282a36"
},
"metadata": {
"copyright": [
"SPDX-FileCopyrightText: 2016 Dracula Theme",
"SPDX-FileCopyrightText: 2020 Christoph Cullmann <cullmann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
"name": "Dracula",
"revision": 8
},
"text-styles": {
"Alert": {
"bold": true,
"selected-text-color": "#ff5555",
"text-color": "#ff5555"
},
"Annotation": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Attribute": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"BaseN": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"BuiltIn": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Char": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Comment": {
"selected-text-color": "#6272a4",
"text-color": "#6272a4"
},
"CommentVar": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Constant": {
"bold": true,
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"ControlFlow": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"DataType": {
"italic": true,
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"DecVal": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Documentation": {
"selected-text-color": "#ffb86c",
"text-color": "#ffb86c"
},
"Error": {
"selected-text-color": "#ff5555",
"text-color": "#ff5555",
"underline": true
},
"Extension": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"Float": {
"selected-text-color": "#bd93f9",
"text-color": "#bd93f9"
},
"Function": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Import": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Information": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Keyword": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"Normal": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
},
"Operator": {
"selected-text-color": "#f8f8f2",
"text-color": "#f8f8f2"
},
"Others": {
"selected-text-color": "#50fa7b",
"text-color": "#50fa7b"
},
"Preprocessor": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"RegionMarker": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"SpecialChar": {
"selected-text-color": "#ff79c6",
"text-color": "#ff79c6"
},
"SpecialString": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"String": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
},
"Variable": {
"selected-text-color": "#8be9fd",
"text-color": "#8be9fd"
},
"VerbatimString": {
"selected-text-color": "#d7e60a",
"text-color": "#d7e60a"
},
"Warning": {
"selected-text-color": "#ff5555",
"text-color": "#ff5555"
}
}
}

1155
themes/latte.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,10 @@ executable site
main-is: site.hs
build-depends:
, base
, bytestring
, hakyll
, pandoc
, skylighting
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: GHC2021