diff options
| -rw-r--r-- | .envrc | 1 | ||||
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | app/css/Main.hs | 4 | ||||
| -rw-r--r-- | app/logos/Main.hs | 4 | ||||
| -rw-r--r-- | flake.lock | 76 | ||||
| -rw-r--r-- | flake.nix | 31 | ||||
| -rw-r--r-- | nix/build.nix | 10 | ||||
| -rw-r--r-- | nix/overlay.nix | 21 | ||||
| -rw-r--r-- | package.yaml | 4 | ||||
| -rw-r--r-- | src/WWW/Colors.hs | 6 | ||||
| -rw-r--r-- | src/WWW/Colors/Hex.hs | 34 | ||||
| -rw-r--r-- | src/WWW/Colors/Instances.hs | 12 | ||||
| -rw-r--r-- | src/WWW/Colors/QQ.hs | 31 | ||||
| -rw-r--r-- | src/WWW/Css.hs | 108 | ||||
| -rw-r--r-- | www-assets.cabal | 71 |
15 files changed, 368 insertions, 48 deletions
@@ -0,0 +1 @@ +use flake . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5d02da --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +dist-newstyle/* +result +.direnv diff --git a/app/css/Main.hs b/app/css/Main.hs new file mode 100644 index 0000000..c2e4af9 --- /dev/null +++ b/app/css/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = undefined diff --git a/app/logos/Main.hs b/app/logos/Main.hs new file mode 100644 index 0000000..c2e4af9 --- /dev/null +++ b/app/logos/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = undefined diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a82f023 --- /dev/null +++ b/flake.lock @@ -0,0 +1,76 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nix-filter": { + "locked": { + "lastModified": 1730207686, + "narHash": "sha256-SCHiL+1f7q9TAnxpasriP6fMarWE5H43t25F5/9e28I=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "776e68c1d014c3adde193a18db9d738458cd2ba4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1731532898, + "narHash": "sha256-M3Vv3Ka6AUitXhs6bFHNlc2VvVQRwF+MPS6+z2ggvLw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "755573265fe75219dfe67161ed6b090a9c004360", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nix-filter": "nix-filter", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "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", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..fa86e71 --- /dev/null +++ b/flake.nix @@ -0,0 +1,31 @@ +{ + description = "Assets for my webpages"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs"; + flake-utils.url = "github:numtide/flake-utils"; + nix-filter.url = "github:numtide/nix-filter"; + }; + + outputs = { self, nixpkgs, flake-utils, nix-filter, ... }: { + overlays.default = import ./nix/overlay.nix { inherit nix-filter; }; + } // flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + }; + in { + packages = { + inherit (pkgs) www-assets; + default = pkgs.www-assets; + }; + + devShells.default = pkgs.haskellPackages.shellFor { + packages = p: [ p.www-assets ]; + withHoogle = true; + buildInputs = with pkgs.haskellPackages; [ + cabal-install + hpack + ]; + }; + }); +} diff --git a/nix/build.nix b/nix/build.nix new file mode 100644 index 0000000..0844618 --- /dev/null +++ b/nix/build.nix @@ -0,0 +1,10 @@ +{ runCommand, buildAssets, ... }: +runCommand "www-assets" { + nativeBuildInputs = [ + buildAssets + ]; +} '' + mkdir -p $out/{css,logos,favicon} + + +'' diff --git a/nix/overlay.nix b/nix/overlay.nix new file mode 100644 index 0000000..0ca77ce --- /dev/null +++ b/nix/overlay.nix @@ -0,0 +1,21 @@ +{ nix-filter, ... }: +final: prev: let + src = nix-filter { + root = ../.; + include = [ + ../app + ../src + ../package.yaml + ../www-assets.cabal + ]; + }; +in { + haskellPackages = prev.haskellPackages.extend (hfinal: hprev: { + www-assets = hfinal.callCabal2nix "www-assets" src {}; + }); + + www-assets = prev.callPackage ./build.nix { + buildAssets = final.haskell.lib.compose.justStaticExecutables final.haskellPackages.www-assets; + }; + +} diff --git a/package.yaml b/package.yaml index f5c65bf..9ffd5a1 100644 --- a/package.yaml +++ b/package.yaml @@ -15,7 +15,7 @@ ghc-options: - -Wcompat - -Widentities - -Wincomplete-record-updates - - -Wincomplete-uni-patters + - -Wincomplete-uni-patterns - -Wmissing-home-modules - -Wpartial-fields - -Wredundant-constraints @@ -25,6 +25,7 @@ library: default-extensions: - BangPatterns - DeriveGeneric + - DeriveLift - DerivingStrategies - DefaultSignatures - FunctionalDependencies @@ -39,6 +40,7 @@ library: - colour - diagrams - diagrams-lib + - template-haskell - text executables: diff --git a/src/WWW/Colors.hs b/src/WWW/Colors.hs index b52aea7..a266414 100644 --- a/src/WWW/Colors.hs +++ b/src/WWW/Colors.hs @@ -10,7 +10,7 @@ module WWW.Colors , gruvboxLightS ) where -import Data.Colour +-- import Data.Colour import Data.String import Diagrams.Attributes @@ -107,7 +107,7 @@ gruvboxDarkS = soft gruvboxDark gruvboxLight :: Gruvbox SomeColor gruvboxLight = - let gb = someToAlpha <$> gruvboxDark + let gb = someToColor' <$> gruvboxDark in SomeColor <$> gb { _bg = [hex|fbf1c7|] , _gray = [hex|7c6f64|] @@ -130,7 +130,7 @@ gruvboxLight = , _fg2 = [hex|504945|] , _fg1 = [hex|3c3836|] , _fg0 = [hex|282828|] - , orange' = [hex|af3a03|] + , _orange' = [hex|af3a03|] } gruvboxLightH :: Gruvbox SomeColor diff --git a/src/WWW/Colors/Hex.hs b/src/WWW/Colors/Hex.hs deleted file mode 100644 index 1773e66..0000000 --- a/src/WWW/Colors/Hex.hs +++ /dev/null @@ -1,34 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} -module WWW.Colors.Hex - ( HexColor - ) where - -import Data.Colour -import Digrams.Attributes -import Language.Haskell.TH.Quote - - -newtype HexColor = HexColor ByteString - deriving (Eq, Generic, Ord) - -instance Bounded HexColor where - maxBound = HexColor "\255\255\255" - minBound = HexColor "\NUL\NUL\NUL" - - -instance Color HexColor where - - - - -hex :: QuasiQuoter -hex = QuasiQuoter - { quoteExp = parseit - , quotePat = failure "quotePat" - , quoteType = failure "quoteType" - , quoteDec = failure "quoteDec" - } where - failure s = const $ fail $ "No " <> s <> " defined for the hexcolor quasiquoter." - parseit s = case undefined of - Nothing -> fail $ "Can't understand " <> s <> " as a valid hex color." - Just h -> h `seq` [|h|] diff --git a/src/WWW/Colors/Instances.hs b/src/WWW/Colors/Instances.hs index e071b6b..3fc7667 100644 --- a/src/WWW/Colors/Instances.hs +++ b/src/WWW/Colors/Instances.hs @@ -1,23 +1,23 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} module WWW.Colors.Instances where import Clay.Color qualified as Clay import Data.Colour import Data.Colour.SRGB (toSRGB24, sRGB24, RGB (..)) import Diagrams.Attributes -import GHC.Float (double2Float, float2Double) +-- | Not perfect, but good enough for building what I need instance Color Clay.Color where toAlphaColour :: Clay.Color -> AlphaColour Double toAlphaColour col = case Clay.toRgba col of Clay.Rgba r g b a -> let rgb = sRGB24 (fromInteger r) (fromInteger g) (fromInteger b) - in withOpacity rgb (float2Double a) + in alphaColourConvert $ withOpacity rgb a _ -> error "Should not happen" fromAlphaColour :: AlphaColour Double -> Clay.Color fromAlphaColour col = - let c = fromAlphaColour col :: Colour Double - a = alphaChannel col - rgb = toInteger <$> toSRGB24 c - in Clay.rgba (channelRed rgb) (channelGreen rgb) (channelBlue rgb) (double2Float a) + let a = alphaChannel $ alphaColourConvert col + RGB r g b = toInteger <$> toSRGB24 (fromAlphaColour @(Colour Double) col) + in Clay.rgba r g b a diff --git a/src/WWW/Colors/QQ.hs b/src/WWW/Colors/QQ.hs index 4a03dbb..281a93a 100644 --- a/src/WWW/Colors/QQ.hs +++ b/src/WWW/Colors/QQ.hs @@ -1,20 +1,43 @@ {-# LANGUAGE TemplateHaskell #-} module WWW.Colors.QQ ( hex + , Color' + , toColor' + , someToColor' ) where --- import Data.Colour --- import Data.Colour.SRGB +import Data.Colour +import Data.Colour.SRGB import Control.Monad ((>=>)) +import Diagrams.Attributes import Diagrams.Backend.CmdLine (readHexColor) +import Language.Haskell.TH.Syntax import Language.Haskell.TH.Quote +-- | data type defined so we can use template haskell to get compile-time hex colors +data Color' = Color' !Double !Double !Double !Double + deriving Lift --- | QuasiQuoter which reads in a hex color code and ouputs a 'AlphaColour Double'. +instance Color Color' where + toAlphaColour (Color' r g b a) = withOpacity (sRGB r g b) a + fromAlphaColour col = + let a = alphaChannel col + RGB r g b = toSRGB $ fromAlphaColour @(Colour Double) col + in Color' r g b a + + +toColor' :: AlphaColour Double -> Color' +toColor' = fromAlphaColour + +someToColor' :: SomeColor -> Color' +someToColor' = toColor' . someToAlpha + + +-- | QuasiQuoter which reads in a hex color code and outputs a 'AlphaColour Double'. hex :: QuasiQuoter hex = QuasiQuoter - { quoteExp = readHexColor >=> \x -> x `seq` pure [|x|] + { quoteExp = readHexColor >=> pure . toColor' >=> \x -> x `seq` [|x|] , quotePat = failure "quotePat" , quoteType = failure "quoteType" , quoteDec = failure "quoteDec" diff --git a/src/WWW/Css.hs b/src/WWW/Css.hs new file mode 100644 index 0000000..164b2af --- /dev/null +++ b/src/WWW/Css.hs @@ -0,0 +1,108 @@ +module WWW.Css where + +import Control.Monad +import Clay +import Clay.Flexbox qualified as F +import Data.Text (Text) +import Diagrams.Attributes (SomeColor) + +import WWW.Colors qualified as G + + + +colorVariables :: G.Gruvbox SomeColor -> Css +colorVariables gb = do + "--html-bg" -: "test" + +rootColors :: Css +rootColors = do + ":root[color-mode=light]" ? do + colorVariables G.gruvboxLightH + ":root[color-mode=dark]" ? do + colorVariables G.gruvboxDarkH + +general :: Css +general = do + html ? do + fontFamily [ "Fira Sans" ] [ sansSerif ] + backgroundColor $ cvar "html-bg" + color $ cvar "fg" + margin (em 1) auto auto auto + body ? do + backgroundColor $ cvar "bg" + join4 margin auto + maxWidth (cm 30) + border (px 1) solid $ cvar "fg" + join4 padding $ em 1 + a ? do + color $ cvar "href" + textDecoration underline + hover & do + color $ cvar "href-hover" + header ? do + padding nil nil nil nil + margin nil nil nil nil + fontSize $ em 1 + fontWeight bold + textDecoration none + footer ? do + clear both + paddingTop $ px 10 + paddingBottom $ px 15 + fontWeight bold + hr ? do + borderTop (px 3) double $ cvar "hr" + borderBottomWidth 0 + a ? do + textDecoration none + color $ cvar "footer-href" + a # hover ? do + textDecoration underline + color $ cvar "footer-href-hover" + code ? do + fontFamily [ "Fira Code" ] [ monospace ] + backgroundColor $ cvar "code-bg" + join4 padding $ px 2 + + +someClasses :: Css +someClasses = do + ".pull-left" ? do + float floatLeft + ".pull-right" ? do + float floatRight + +menu :: Css +menu = do + clear both + display block + "width" -: "100%" + margin 0 0 (em 1) 0 + color $ cvar "bg" + backgroundColor $ cvar "fg" + "overflow" -: "hidden" + a ? do + display block + float floatLeft + padding (px 5) (px 10) (px 5) (px 10) + color $ cvar "bg" + a # hover ? do + color $ cvar "href-hover" + + + + +-- helpers + +join3 :: Monad m => m (m (m a)) -> m a +join3 = join . join + +join4 :: Monad m => m (m (m (m a))) -> m a +join4 = join . join3 + +cvar :: Text -> Color +cvar n = Other $ value $ "var(--" <> n <> ")" +-- root :: Css +-- root = do +-- ":root" ? do +-- "-- diff --git a/www-assets.cabal b/www-assets.cabal new file mode 100644 index 0000000..140c2dc --- /dev/null +++ b/www-assets.cabal @@ -0,0 +1,71 @@ +cabal-version: 1.12 + +-- This file has been generated from package.yaml by hpack version 0.36.1. +-- +-- see: https://github.com/sol/hpack + +name: www-assets +version: 0.1.0.0 +author: Chris Wells +maintainer: chris@mathematicaster.org +copyright: 2024 Chris Wells +license: MIT +build-type: Simple + +library + exposed-modules: + WWW.Colors + WWW.Colors.Instances + WWW.Colors.QQ + WWW.Css + other-modules: + Paths_www_assets + hs-source-dirs: + src + default-extensions: + BangPatterns + DeriveGeneric + DeriveLift + DerivingStrategies + DefaultSignatures + FunctionalDependencies + GADTs + LambdaCase + MultiWayIf + OverloadedStrings + PatternSynonyms + TypeFamilies + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + base >=4.7 && <5 + , clay + , colour + , diagrams + , diagrams-lib + , template-haskell + , text + default-language: GHC2021 + +executable css + main-is: Main.hs + other-modules: + Paths_www_assets + hs-source-dirs: + app/css + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + base >=4.7 && <5 + , www-assets + default-language: GHC2021 + +executable logos + main-is: Main.hs + other-modules: + Paths_www_assets + hs-source-dirs: + app/logos + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + base >=4.7 && <5 + , www-assets + default-language: GHC2021 |
