From a7df9b3959a136c358edd5874076a3d4ffb87684 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 25 May 2020 22:28:06 +0200 Subject: [PATCH 01/27] move to shake --- Shakefile.hs | 38 ++++++++++++++++++++++++++++++++++++++ build.sh | 3 +++ engine/compresscss.sh | 7 +------ engine/dup-for-themes.sh | 4 +--- engine/mkrss.sh | 4 +--- engine/optim-classes.sh | 4 +--- engine/optim-html.sh | 4 +--- engine/shell.nix | 11 ----------- engine/update-file-size.sh | 4 +--- project.el | 2 +- shell.nix | 36 ++++++++++++++++++++++-------------- 11 files changed, 70 insertions(+), 47 deletions(-) create mode 100644 Shakefile.hs create mode 100755 build.sh delete mode 100644 engine/shell.nix diff --git a/Shakefile.hs b/Shakefile.hs new file mode 100644 index 0000000..34d03af --- /dev/null +++ b/Shakefile.hs @@ -0,0 +1,38 @@ +import Development.Shake +import Development.Shake.Command +import Development.Shake.FilePath +import Development.Shake.Util + +main :: IO () +main = do + let shOpts = shakeOptions { shakeVerbosity = Chatty, shakeLintInside = ["\\"] } + shakeArgsForward shOpts buildRules + +buildRules :: Action () +buildRules = do + allPosts <- buildPosts + buildIndex allPosts + buildFeed allPosts + copyStaticFiles + +-- | Find and build all posts +buildPosts :: Action [Post] +buildPosts = do + pPaths <- getDirectoryFiles "." ["site/posts//*.md"] + forP pPaths buildPost + +-- | Load a post, process metadata, write it to output, then return the post object +-- Detects changes to either post content or template +buildPost :: FilePath -> Action Post +buildPost srcPath = cacheAction ("build" :: T.Text, srcPath) $ do + liftIO . putStrLn $ "Rebuilding post: " <> srcPath + postContent <- readFile' srcPath + -- load post content and metadata as JSON blob + postData <- markdownToHTML . T.pack $ postContent + let postUrl = T.pack . dropDirectory1 $ srcPath -<.> "html" + withPostUrl = _Object . at "url" ?~ String postUrl + -- Add additional metadata we've been able to compute + let fullPostData = withSiteMeta . withPostUrl $ postData + template <- compileTemplate' "site/templates/post.html" + writeFile' (outputFolder T.unpack postUrl) . T.unpack $ substitute template fullPostData + convert fullPostData diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..71b68d1 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +mkdir -p _shake +ghc --make Shakefile.hs -rtsopts -threaded -with-rtsopts=-I0 -outputdir=_shake -o _shake/build && _shake/build "$@" diff --git a/engine/compresscss.sh b/engine/compresscss.sh index 763a779..00094c1 100755 --- a/engine/compresscss.sh +++ b/engine/compresscss.sh @@ -1,8 +1,3 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i bash -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" -#!nix-shell -p minify - -# nix-shell -p nodePackages.clean-css +#!/usr/bin/env bash minify "$1" > "$2" diff --git a/engine/dup-for-themes.sh b/engine/dup-for-themes.sh index ae10842..f9d8c65 100755 --- a/engine/dup-for-themes.sh +++ b/engine/dup-for-themes.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i zsh -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" +#!/usr/bin/env zsh cd "$(git rev-parse --show-toplevel)" || exit 1 diff --git a/engine/mkrss.sh b/engine/mkrss.sh index 77f804e..f964ee5 100755 --- a/engine/mkrss.sh +++ b/engine/mkrss.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i zsh -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" +#!/usr/bin/env zsh cd "$(git rev-parse --show-toplevel)" || exit 1 # Directory diff --git a/engine/optim-classes.sh b/engine/optim-classes.sh index 9f78d68..2b5d0e7 100755 --- a/engine/optim-classes.sh +++ b/engine/optim-classes.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i zsh -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" +#!/usr/bin/env zsh cd "$(git rev-parse --show-toplevel)" || exit 1 webdir="_optim" diff --git a/engine/optim-html.sh b/engine/optim-html.sh index baf1495..619f5f4 100755 --- a/engine/optim-html.sh +++ b/engine/optim-html.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i zsh -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" +#!/usr/bin/env zsh cd "$(git rev-parse --show-toplevel)" || exit 1 webdir="_optim" diff --git a/engine/shell.nix b/engine/shell.nix deleted file mode 100644 index 0eab84d..0000000 --- a/engine/shell.nix +++ /dev/null @@ -1,11 +0,0 @@ -# { pkgs ? import {} }: -{ pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {} }: - pkgs.mkShell { - buildInputs = [ pkgs.coreutils - pkgs.html-xml-utils - pkgs.zsh - pkgs.perl - pkgs.perlPackages.URI - pkgs.minify - ]; - } diff --git a/engine/update-file-size.sh b/engine/update-file-size.sh index 341ea88..9e70862 100755 --- a/engine/update-file-size.sh +++ b/engine/update-file-size.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i zsh -#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz" +#!/usr/bin/env zsh cd "$(git rev-parse --show-toplevel)" || exit 1 webdir="_optim" diff --git a/project.el b/project.el index 2db93e5..15ce804 100644 --- a/project.el +++ b/project.el @@ -284,7 +284,7 @@ " %s" ;; source " -sampling-factor 4:2:0" " -strip" - " -resize 200x200\\>" + " -resize 300x300\\>" " -interlace Plane" " -quality 85" " -define filter:blur=0.75" diff --git a/shell.nix b/shell.nix index fad7781..59add58 100644 --- a/shell.nix +++ b/shell.nix @@ -1,15 +1,23 @@ -# { pkgs ? import {} }: -{ pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {} }: - let my_aspell = pkgs.aspellWithDicts(p: with p; [en fr]); - in - pkgs.mkShell { - buildInputs = [ pkgs.coreutils - pkgs.html-xml-utils - pkgs.zsh - pkgs.perl - pkgs.perlPackages.URI - pkgs.minify - pkgs.haskellPackages.sws - pkgs.cacert - ]; +{ pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz) {} }: +let + haskellDeps = ps : with ps; [ + shake + ]; + pkgs1909 = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}; + ghc = pkgs.haskellPackages.ghcWithPackages haskellDeps; +in +pkgs.mkShell { + buildInputs = with pkgs; + [cacert + coreutils + html-xml-utils + zsh + perl + perlPackages.URI + minify + niv + ghc + pkgs1909.haskellPackages.sws + haskellPackages.shake + ]; } From 0f62b038dfceb841cbee7d7d0ffac726f0b3059f Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 25 May 2020 22:30:22 +0200 Subject: [PATCH 02/27] minor fixes --- Shakefile.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Shakefile.hs b/Shakefile.hs index 34d03af..727b838 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -1,7 +1,10 @@ +{-# LANGUAGE OverloadedStrings #-} + import Development.Shake import Development.Shake.Command import Development.Shake.FilePath import Development.Shake.Util +import Data.Text as T main :: IO () main = do From 536f0ed5e60b7e28f72d4f91bf91e5fac60512d2 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Sun, 14 Jun 2020 13:19:13 +0200 Subject: [PATCH 03/27] wip --- .gitignore | 2 ++ Shakefile.hs | 68 ++++++++++++++++++++++++-------------- _optim/.gitignore | 2 -- _site/.gitignore | 2 -- _site/index.html | 84 +++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 6 +++- 6 files changed, 135 insertions(+), 29 deletions(-) delete mode 100644 _optim/.gitignore delete mode 100644 _site/.gitignore create mode 100644 _site/index.html diff --git a/.gitignore b/.gitignore index d9947d9..e3771aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ _cache/ src/archive.org .direnv/ +_shake/ +.shake/ \ No newline at end of file diff --git a/Shakefile.hs b/Shakefile.hs index 727b838..2a1b921 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -4,38 +4,58 @@ import Development.Shake import Development.Shake.Command import Development.Shake.FilePath import Development.Shake.Util -import Data.Text as T + +import Data.Default (Default(def)) +import qualified Data.Set as Set +import qualified Data.Text as T +import Text.Pandoc.Class (PandocPure) +import qualified Text.Pandoc.Class as Pandoc +import Text.Pandoc.Extensions (getDefaultExtensions) +import Text.Pandoc.Options (ReaderOptions(..),TrackChanges(RejectChanges)) +import qualified Text.Pandoc.Readers as Readers +import qualified Text.Pandoc.Writers as Writers main :: IO () main = do let shOpts = shakeOptions { shakeVerbosity = Chatty, shakeLintInside = ["\\"] } - shakeArgsForward shOpts buildRules + shakeArgs shOpts buildRules -buildRules :: Action () +buildRules :: Rules () buildRules = do - allPosts <- buildPosts - buildIndex allPosts - buildFeed allPosts - copyStaticFiles + phony "clean" $ do + putInfo "Cleaning files in _site and _optim" + removeFilesAfter "_site" ["//*"] + removeFilesAfter "_optim" ["//*"] --- | Find and build all posts -buildPosts :: Action [Post] -buildPosts = do - pPaths <- getDirectoryFiles "." ["site/posts//*.md"] - forP pPaths buildPost + "_site//*.html" %> buildPost +-- buildPosts +-- allPosts <- buildPosts +-- buildIndex allPosts +-- buildFeed allPosts +-- copyStaticFiles + +data Post = Post { postTitle :: T.Text + , postAuthor :: T.Text + , postDate :: T.Text + } + +defaultReaderOpts t = + def { readerExtensions = getDefaultExtensions t + , readerStandalone = True } + +orgToHTML :: T.Text -> PandocPure T.Text +orgToHTML txt = Readers.readOrg (defaultReaderOpts "org") txt + >>= Writers.writeHtml5String def -- | Load a post, process metadata, write it to output, then return the post object -- Detects changes to either post content or template -buildPost :: FilePath -> Action Post -buildPost srcPath = cacheAction ("build" :: T.Text, srcPath) $ do - liftIO . putStrLn $ "Rebuilding post: " <> srcPath - postContent <- readFile' srcPath +buildPost :: FilePath -> Action () +buildPost out = do + let org = "src/" <> (dropDirectory1 $ out -<.> "org") + liftIO . putStrLn $ "Rebuilding post: " <> out + postContent <- readFile' org -- load post content and metadata as JSON blob - postData <- markdownToHTML . T.pack $ postContent - let postUrl = T.pack . dropDirectory1 $ srcPath -<.> "html" - withPostUrl = _Object . at "url" ?~ String postUrl - -- Add additional metadata we've been able to compute - let fullPostData = withSiteMeta . withPostUrl $ postData - template <- compileTemplate' "site/templates/post.html" - writeFile' (outputFolder T.unpack postUrl) . T.unpack $ substitute template fullPostData - convert fullPostData + let pandocReturn = Pandoc.runPure $ orgToHTML . T.pack $ postContent + case pandocReturn of + Left _ -> putError "BAD" + Right outData -> writeFile' out (T.unpack outData) diff --git a/_optim/.gitignore b/_optim/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/_optim/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/_site/.gitignore b/_site/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/_site/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/_site/index.html b/_site/index.html new file mode 100644 index 0000000..a508e26 --- /dev/null +++ b/_site/index.html @@ -0,0 +1,84 @@ +

+

I'm a functional programmer, working remotely for Cisco.
I work in Clojure and use Haskell/Purescript during the weekends.

+ + + + + + + + + + + + +
email Yann Esposito <yann@esposito.host>
gpgCB420F8005F1A662
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
self-hostedweb
programsgitea.esy.fungithub/yogsototh
bookmarksespial.esy.funpinboard/u:yogsototh
microblogespial.esy.funtwitter/@yogsototh
keybase. . . . . . . .yogsototh
lobste.rs. . . . . . . ./u/yogsototh
reddit. . . . . . . ./u/yogsototh
stack overflow. . . . . . . .yogsototh
+

That website was created with the following constraints in mind by order of priority:

+
    +
  1. Respect Privacy; no tracker of any sort (no ads, no google analytics, no referrer for all external links, etc…)

  2. +
  3. Almost javascript free; no js at all except for a single exception, pages containing Math formulæ are displayed using mathjax.

  4. +
  5. Accessibility; should be easy to read on a text browser so people with disabilities could easily consume it.

  6. +
  7. RSS; you should be able to get informed when I add a new blog post.

  8. +
  9. Frugal; try to minimize the resources needed to visit my website; no javascript, no web-font, not too much CSS magic, not much images or really compressed one.
  10. +
+

If you are interested about technical details behind this website, take a look here.

\ No newline at end of file diff --git a/shell.nix b/shell.nix index 59add58..919089c 100644 --- a/shell.nix +++ b/shell.nix @@ -2,13 +2,15 @@ let haskellDeps = ps : with ps; [ shake + pandoc + data-default ]; pkgs1909 = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}; ghc = pkgs.haskellPackages.ghcWithPackages haskellDeps; in pkgs.mkShell { buildInputs = with pkgs; - [cacert + [ cacert coreutils html-xml-utils zsh @@ -17,6 +19,8 @@ pkgs.mkShell { minify niv ghc + git + direnv pkgs1909.haskellPackages.sws haskellPackages.shake ]; From 1e0d4c8fad0cb3cbe617bbedc26bfdcab1021bbb Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Sun, 21 Jun 2020 15:52:33 +0200 Subject: [PATCH 04/27] forgot some gitignore --- _optim/.gitignore | 2 ++ _site/.gitignore | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 _optim/.gitignore create mode 100644 _site/.gitignore diff --git a/_optim/.gitignore b/_optim/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/_optim/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/_site/.gitignore b/_site/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/_site/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 1eb4a6de5abf9ee61b610be66b874141e330c388 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 09:39:44 +0200 Subject: [PATCH 05/27] save --- Shakefile.hs | 111 +++++++++++++++++++++++++++++++++++++-------------- shell.nix | 5 ++- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 2a1b921..e31026e 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -1,4 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE NoImplicitPrelude #-} + +import Protolude hiding ((*>)) import Development.Shake import Development.Shake.Command @@ -8,8 +11,9 @@ import Development.Shake.Util import Data.Default (Default(def)) import qualified Data.Set as Set import qualified Data.Text as T -import Text.Pandoc.Class (PandocPure) +import Text.Pandoc.Class (PandocPure,PandocMonad) import qualified Text.Pandoc.Class as Pandoc +import Text.Pandoc.Definition (Pandoc(..),Block(..),Inline,nullMeta,docTitle,docDate,docAuthors) import Text.Pandoc.Extensions (getDefaultExtensions) import Text.Pandoc.Options (ReaderOptions(..),TrackChanges(RejectChanges)) import qualified Text.Pandoc.Readers as Readers @@ -20,42 +24,91 @@ main = do let shOpts = shakeOptions { shakeVerbosity = Chatty, shakeLintInside = ["\\"] } shakeArgs shOpts buildRules +data BlogPost = + BlogPost { postTitle :: T.Text + , postDate :: T.Text + , postAuthors :: [T.Text] + , postUrl :: FilePath + , postP :: Pandoc + } + +inlineToText :: PandocMonad m => [Inline] -> m T.Text +inlineToText inline = + Writers.writeAsciiDoc def (Pandoc nullMeta [Plain inline]) + buildRules :: Rules () buildRules = do + let + siteDir = "_site" + optimDir = "_optim" + build = () siteDir phony "clean" $ do putInfo "Cleaning files in _site and _optim" - removeFilesAfter "_site" ["//*"] - removeFilesAfter "_optim" ["//*"] + removeFilesAfter siteDir ["//*"] + removeFilesAfter optimDir ["//*"] + getPost <- newCache $ \path -> do + fileContent <- readFile' path + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (T.pack fileContent) + case eitherResult of + Left _ -> liftIO $ putText "Problem" + Right pandoc@(Pandoc meta _) -> liftIO $ Pandoc.runIO $ do + title <- inlineToText $ docTitle meta + date <- inlineToText $ docDate meta + authors <- map inlineToText $ docAuthors meta + let url = dropExtension path + return $ BlogPost title date authors url pandoc + getPosts <- newCache $ \() -> + mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] + let hsDeps = return ["AsciiArt.hs", "Index.hs", "Rot13.hs"] + cssDeps = map (siteDir ) <$> getDirectoryFiles "" ["src/css/*.css"] + build "index.html" *> \out -> do + hs <- hsDeps + css <- cssDeps + posts <- getPosts () + need $ hs + <> css + <> map ( combine "build" + . flip combine "index.html" + . postUrl ) posts + <> [build "atom.xml"] + writeFile' out + . renderHtml . index "" + . sortBy (\a b -> + compare (Down (postDate a)) (Down (postDate b))) + $ posts + build "src/css/*.css" *> \out -> + copyFile' (dropDirectory1 out) out - "_site//*.html" %> buildPost + +-- "_site//*.html" %> buildPost -- buildPosts -- allPosts <- buildPosts -- buildIndex allPosts -- buildFeed allPosts -- copyStaticFiles -data Post = Post { postTitle :: T.Text - , postAuthor :: T.Text - , postDate :: T.Text - } - -defaultReaderOpts t = - def { readerExtensions = getDefaultExtensions t - , readerStandalone = True } - -orgToHTML :: T.Text -> PandocPure T.Text -orgToHTML txt = Readers.readOrg (defaultReaderOpts "org") txt - >>= Writers.writeHtml5String def - --- | Load a post, process metadata, write it to output, then return the post object --- Detects changes to either post content or template -buildPost :: FilePath -> Action () -buildPost out = do - let org = "src/" <> (dropDirectory1 $ out -<.> "org") - liftIO . putStrLn $ "Rebuilding post: " <> out - postContent <- readFile' org - -- load post content and metadata as JSON blob - let pandocReturn = Pandoc.runPure $ orgToHTML . T.pack $ postContent - case pandocReturn of - Left _ -> putError "BAD" - Right outData -> writeFile' out (T.unpack outData) +-- data Post = Post { postTitle :: T.Text +-- , postAuthor :: T.Text +-- , postDate :: T.Text +-- } +-- +-- defaultReaderOpts t = +-- def { readerExtensions = getDefaultExtensions t +-- , readerStandalone = True } +-- +-- orgToHTML :: T.Text -> PandocPure T.Text +-- orgToHTML txt = Readers.readOrg (defaultReaderOpts "org") txt +-- >>= Writers.writeHtml5String def +-- +-- -- | Load a post, process metadata, write it to output, then return the post object +-- -- Detects changes to either post content or template +-- buildPost :: FilePath -> Action () +-- buildPost out = do +-- let org = "src/" <> (dropDirectory1 $ out -<.> "org") +-- liftIO . putStrLn $ "Rebuilding post: " <> out +-- postContent <- readFile' org +-- -- load post content and metadata as JSON blob +-- let pandocReturn = Pandoc.runPure $ orgToHTML . T.pack $ postContent +-- case pandocReturn of +-- Left _ -> putError "BAD" +-- Right outData -> writeFile' out (T.unpack outData) diff --git a/shell.nix b/shell.nix index 919089c..dc3a357 100644 --- a/shell.nix +++ b/shell.nix @@ -1,11 +1,13 @@ { pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz) {} }: let + pkgs1909 = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}; haskellDeps = ps : with ps; [ shake pandoc data-default + protolude + pkgs1909.haskellPackages.sws ]; - pkgs1909 = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}; ghc = pkgs.haskellPackages.ghcWithPackages haskellDeps; in pkgs.mkShell { @@ -21,7 +23,6 @@ pkgs.mkShell { ghc git direnv - pkgs1909.haskellPackages.sws haskellPackages.shake ]; } From e3a33d9ecfd0cf61889a196c0e46b33e006b14d6 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 11:44:11 +0200 Subject: [PATCH 06/27] starting to work --- Shakefile.hs | 142 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 59 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index e31026e..b1fb34e 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -1,83 +1,107 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} -import Protolude hiding ((*>)) +import Protolude -import Development.Shake -import Development.Shake.Command -import Development.Shake.FilePath -import Development.Shake.Util +import Development.Shake +import Development.Shake.Command +import Development.Shake.FilePath +import Development.Shake.Util -import Data.Default (Default(def)) -import qualified Data.Set as Set -import qualified Data.Text as T -import Text.Pandoc.Class (PandocPure,PandocMonad) -import qualified Text.Pandoc.Class as Pandoc -import Text.Pandoc.Definition (Pandoc(..),Block(..),Inline,nullMeta,docTitle,docDate,docAuthors) -import Text.Pandoc.Extensions (getDefaultExtensions) -import Text.Pandoc.Options (ReaderOptions(..),TrackChanges(RejectChanges)) -import qualified Text.Pandoc.Readers as Readers -import qualified Text.Pandoc.Writers as Writers +import Control.Monad.Fail +import Data.Default ( Default(def) ) +import qualified Data.Set as Set +import qualified Data.Text as T +import Text.Pandoc.Class ( PandocPure + , PandocMonad + ) +import qualified Text.Pandoc.Class as Pandoc +import Text.Pandoc.Definition ( Pandoc(..) + , Block(..) + , Inline + , nullMeta + , docTitle + , docDate + , docAuthors + ) +import Text.Pandoc.Extensions ( getDefaultExtensions ) +import Text.Pandoc.Options ( ReaderOptions(..) + , TrackChanges(RejectChanges) + ) +import qualified Text.Pandoc.Readers as Readers +import qualified Text.Pandoc.Writers as Writers main :: IO () main = do - let shOpts = shakeOptions { shakeVerbosity = Chatty, shakeLintInside = ["\\"] } - shakeArgs shOpts buildRules + let + shOpts = shakeOptions { shakeVerbosity = Chatty + , shakeLintInside = ["\\"] + } + shakeArgs shOpts buildRules data BlogPost = BlogPost { postTitle :: T.Text , postDate :: T.Text , postAuthors :: [T.Text] , postUrl :: FilePath - , postP :: Pandoc + , postBody :: Pandoc } inlineToText :: PandocMonad m => [Inline] -> m T.Text inlineToText inline = - Writers.writeAsciiDoc def (Pandoc nullMeta [Plain inline]) + Writers.writeAsciiDoc def (Pandoc nullMeta [Plain inline]) + +getBlogpostFromMetas + :: (MonadIO m, MonadFail m) => [Char] -> Pandoc -> m BlogPost +getBlogpostFromMetas path pandoc@(Pandoc meta _) = do + eitherBlogpost <- liftIO $ Pandoc.runIO $ do + title <- inlineToText $ docTitle meta + date <- inlineToText $ docDate meta + authors <- mapM inlineToText $ docAuthors meta + -- let url = dropExtension path + return $ BlogPost title date authors path pandoc + case eitherBlogpost of + Left _ -> fail "BAD" + Right bp -> return bp + +sortByPostDate :: [BlogPost] -> [BlogPost] +sortByPostDate = + sortBy (\a b -> compare (Down (postDate a)) (Down (postDate b))) buildRules :: Rules () buildRules = do - let - siteDir = "_site" - optimDir = "_optim" - build = () siteDir - phony "clean" $ do - putInfo "Cleaning files in _site and _optim" - removeFilesAfter siteDir ["//*"] - removeFilesAfter optimDir ["//*"] - getPost <- newCache $ \path -> do - fileContent <- readFile' path - eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (T.pack fileContent) - case eitherResult of - Left _ -> liftIO $ putText "Problem" - Right pandoc@(Pandoc meta _) -> liftIO $ Pandoc.runIO $ do - title <- inlineToText $ docTitle meta - date <- inlineToText $ docDate meta - authors <- map inlineToText $ docAuthors meta - let url = dropExtension path - return $ BlogPost title date authors url pandoc - getPosts <- newCache $ \() -> - mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] - let hsDeps = return ["AsciiArt.hs", "Index.hs", "Rot13.hs"] - cssDeps = map (siteDir ) <$> getDirectoryFiles "" ["src/css/*.css"] - build "index.html" *> \out -> do - hs <- hsDeps - css <- cssDeps - posts <- getPosts () - need $ hs - <> css - <> map ( combine "build" - . flip combine "index.html" - . postUrl ) posts - <> [build "atom.xml"] - writeFile' out - . renderHtml . index "" - . sortBy (\a b -> - compare (Down (postDate a)) (Down (postDate b))) - $ posts - build "src/css/*.css" *> \out -> - copyFile' (dropDirectory1 out) out + let siteDir = "_site" + optimDir = "_optim" + build = () siteDir + phony "clean" $ do + putInfo "Cleaning files in _site and _optim" + removeFilesAfter siteDir ["//*"] + removeFilesAfter optimDir ["//*"] + getPost <- newCache $ \path -> do + fileContent <- readFile' path + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg + def + (T.pack fileContent) + case eitherResult of + Left _ -> fail "BAD" + Right pandoc -> getBlogpostFromMetas path pandoc + getPosts <- + newCache + $ \() -> mapM getPost =<< getDirectoryFiles + "" + ["src/posts//*.org"] + let -- hsDeps = return ["AsciiArt.hs", "Index.hs", "Rot13.hs"] + cssDeps = map (siteDir ) + <$> getDirectoryFiles "" ["src/css/*.css"] + build "index.html" %> \out -> do + -- hs <- hsDeps + css <- cssDeps + posts <- getPosts () + need $ css <> map postUrl posts + -- <> [build "atom.xml"] + let titles = map postTitle posts + writeFile' out (mconcat (map T.unpack titles)) + build "src/css/*.css" %> \out -> copyFile' (dropDirectory1 out) out -- "_site//*.html" %> buildPost From b81339a51e396b58ed8c2ae412b5d58dbba38c9f Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 12:08:07 +0200 Subject: [PATCH 07/27] progress --- Shakefile.hs | 110 +++---- _optim/.gitignore | 2 - _site/.gitignore | 2 - _site/index.html | 97 +------ _site/src/css/colors.css | 139 +++++++++ _site/src/css/latex.css | 379 +++++++++++++++++++++++++ _site/src/css/mk.css | 139 +++++++++ _site/src/css/slides.css | 20 ++ _site/src/css/y.css | 600 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 1334 insertions(+), 154 deletions(-) delete mode 100644 _optim/.gitignore delete mode 100644 _site/.gitignore create mode 100644 _site/src/css/colors.css create mode 100644 _site/src/css/latex.css create mode 100644 _site/src/css/mk.css create mode 100644 _site/src/css/slides.css create mode 100644 _site/src/css/y.css diff --git a/Shakefile.hs b/Shakefile.hs index b1fb34e..9e15316 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -32,12 +32,24 @@ import qualified Text.Pandoc.Readers as Readers import qualified Text.Pandoc.Writers as Writers main :: IO () -main = do - let - shOpts = shakeOptions { shakeVerbosity = Chatty - , shakeLintInside = ["\\"] - } - shakeArgs shOpts buildRules +main = shakeArgs shOpts buildRules + where + shOpts = + shakeOptions + { shakeVerbosity = Chatty + , shakeLintInside = ["\\"] + } + +-- Configuration +-- Should probably go in a Reader Monad + +siteDir :: FilePath +siteDir = "_site" + +optimDir :: FilePath +optimDir = "_optim" + +-- BlogPost data structure (a bit of duplication because the metas are in Pandoc) data BlogPost = BlogPost { postTitle :: T.Text @@ -66,73 +78,39 @@ getBlogpostFromMetas path pandoc@(Pandoc meta _) = do sortByPostDate :: [BlogPost] -> [BlogPost] sortByPostDate = - sortBy (\a b -> compare (Down (postDate a)) (Down (postDate b))) + sortBy (\b a -> compare (Down (postDate a)) (Down (postDate b))) buildRules :: Rules () buildRules = do - let siteDir = "_site" - optimDir = "_optim" - build = () siteDir - phony "clean" $ do - putInfo "Cleaning files in _site and _optim" - removeFilesAfter siteDir ["//*"] - removeFilesAfter optimDir ["//*"] - getPost <- newCache $ \path -> do - fileContent <- readFile' path - eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg - def - (T.pack fileContent) - case eitherResult of - Left _ -> fail "BAD" - Right pandoc -> getBlogpostFromMetas path pandoc - getPosts <- - newCache - $ \() -> mapM getPost =<< getDirectoryFiles - "" - ["src/posts//*.org"] - let -- hsDeps = return ["AsciiArt.hs", "Index.hs", "Rot13.hs"] - cssDeps = map (siteDir ) - <$> getDirectoryFiles "" ["src/css/*.css"] + let build = () siteDir + cleanRule + getPost <- mkGetPost + getPosts <- mkGetPosts getPost + let cssDeps = map (siteDir ) <$> getDirectoryFiles "" ["src/css/*.css"] build "index.html" %> \out -> do - -- hs <- hsDeps css <- cssDeps posts <- getPosts () - need $ css <> map postUrl posts - -- <> [build "atom.xml"] - let titles = map postTitle posts - writeFile' out (mconcat (map T.unpack titles)) + need $ css <> map postUrl (sortByPostDate posts) + let titles = T.unpack $ T.intercalate "\n" $ map postTitle posts + writeFile' out titles + -- build "//*.html" %> \out -> do + -- css <- cssDeps + -- let orgfile = dropDirectory1 out + -- post <- getPost orgfile build "src/css/*.css" %> \out -> copyFile' (dropDirectory1 out) out +cleanRule :: Rules () +cleanRule = + phony "clean" $ do + putInfo "Cleaning files in _site and _optim" + forM_ [siteDir,optimDir] $ flip removeFilesAfter ["//*"] --- "_site//*.html" %> buildPost --- buildPosts --- allPosts <- buildPosts --- buildIndex allPosts --- buildFeed allPosts --- copyStaticFiles +mkGetPost = newCache $ \path -> do + fileContent <- readFile' path + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (T.pack fileContent) + case eitherResult of + Left _ -> fail "BAD" + Right pandoc -> getBlogpostFromMetas path pandoc --- data Post = Post { postTitle :: T.Text --- , postAuthor :: T.Text --- , postDate :: T.Text --- } --- --- defaultReaderOpts t = --- def { readerExtensions = getDefaultExtensions t --- , readerStandalone = True } --- --- orgToHTML :: T.Text -> PandocPure T.Text --- orgToHTML txt = Readers.readOrg (defaultReaderOpts "org") txt --- >>= Writers.writeHtml5String def --- --- -- | Load a post, process metadata, write it to output, then return the post object --- -- Detects changes to either post content or template --- buildPost :: FilePath -> Action () --- buildPost out = do --- let org = "src/" <> (dropDirectory1 $ out -<.> "org") --- liftIO . putStrLn $ "Rebuilding post: " <> out --- postContent <- readFile' org --- -- load post content and metadata as JSON blob --- let pandocReturn = Pandoc.runPure $ orgToHTML . T.pack $ postContent --- case pandocReturn of --- Left _ -> putError "BAD" --- Right outData -> writeFile' out (T.unpack outData) +mkGetPosts getPost = + newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] diff --git a/_optim/.gitignore b/_optim/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/_optim/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/_site/.gitignore b/_site/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/_site/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/_site/index.html b/_site/index.html index a508e26..255da53 100644 --- a/_site/index.html +++ b/_site/index.html @@ -1,84 +1,13 @@ -

-

I'm a functional programmer, working remotely for Cisco.
I work in Clojure and use Haskell/Purescript during the weekends.

- - - - - - - - - - - - -
email Yann Esposito <yann@esposito.host>
gpgCB420F8005F1A662
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
self-hostedweb
programsgitea.esy.fungithub/yogsototh
bookmarksespial.esy.funpinboard/u:yogsototh
microblogespial.esy.funtwitter/@yogsototh
keybase. . . . . . . .yogsototh
lobste.rs. . . . . . . ./u/yogsototh
reddit. . . . . . . ./u/yogsototh
stack overflow. . . . . . . .yogsototh
-

That website was created with the following constraints in mind by order of priority:

-
    -
  1. Respect Privacy; no tracker of any sort (no ads, no google analytics, no referrer for all external links, etc…)

  2. -
  3. Almost javascript free; no js at all except for a single exception, pages containing Math formulæ are displayed using mathjax.

  4. -
  5. Accessibility; should be easy to read on a text browser so people with disabilities could easily consume it.

  6. -
  7. RSS; you should be able to get informed when I add a new blog post.

  8. -
  9. Frugal; try to minimize the resources needed to visit my website; no javascript, no web-font, not too much CSS magic, not much images or really compressed one.
  10. -
-

If you are interested about technical details behind this website, take a look here.

\ No newline at end of file +New Blog +Troll 2 +Autoload Script by project +How I Internet +RSS Generation +Modern IRC +Catalina iTerm Theme switch +Further Blog Engine change +Optimize the size of no js websites +Learn Haskell Now! +Add links to code block during orgmode export +Solaryzed: A Generalisation of Solarized +How to choose your tools \ No newline at end of file diff --git a/_site/src/css/colors.css b/_site/src/css/colors.css new file mode 100644 index 0000000..2d3edf5 --- /dev/null +++ b/_site/src/css/colors.css @@ -0,0 +1,139 @@ +/* COLORS */ + +/* colortheme switch */ +body>input { display: none; } +#labels > .content { margin: 0 auto; text-align: center; } +label { font-weight: 700; } +label:hover { cursor: pointer; } +#logo { text-align: center; } +body { margin:0; padding: 0; border: 0; max-width: none;} +#content,.content,#preamble,#postamble { + max-width: 80ch; + overflow: hidden; + margin: 0 auto; +} +figure img { width: 100%; } +.footdef > sup { vertical-align: top; font-size: medium; } +.footdef > sup > a { padding: 0.5em; } +.footpara { display: inline; } +footer { margin: 3em 0; padding: 1em 0; border-top: solid 1px; border-bottom: solid 1px; line-height: 1em; } +#postamble td { border-bottom: none; } +nav { text-align: center; padding: 2em 0; } + + +:root { + --b03: #2E3440; + --b02: #3B4252; + /* not used because light mode is has more contrast + --b01: #656b74; + */ + --b00: #727781; + --b0: #989ea8; + --b1: #b0bac7; + --b2: #ECEFF4; + --b3: #fff; + --y: #c18600; + --o: #d84100; + --r: #e62729; + --m: #ec0085; + --v: #6c71c4; + --b: #0095ff; + --c: #00b0a3; + --g: #879a00; + + /* default light */ + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--o); +} + +/* light checked */ +input#l:checked ~ div { + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--o); +} +input#l:checked ~ div img { + filter: none; +} + +/* dark checked */ +input#d:checked ~ div { + --bg: hsl(210,20%,2%); + --rbg: var(--b03); + --fg: var(--b1); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--y); +} +input#d:checked ~ div img { + filter: brightness(0.5) saturate(0.5); +} + +/* dark preferred */ +@media (prefers-color-scheme: dark) +{ + :root { + --bg: black; + --rbg: var(--b03); + --fg: var(--b1); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--y); + } + img { filter: brightness(0.5) saturate(0.5); } +} +body, body > div { + background: var(--bg); + color: var(--fg); +} +a,a:visited { color: var(--hl); } + +/* ---- SYNTAX HIGHLIGHTING ---- */ +.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, +.org-css-selector, .org-nix-attribute, .org-builtin, +.IN_REVIEW { + color:var(--c); +} + +.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, +.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed { + color:var(--b); +} + +.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { + color:var(--v); +} + +.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, +.CANCELED { + color:var(--m); +} +.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { + color:var(--r); +} +.org-rainbow-delimiters-depth-6, .org-haskell-constructor { + color:var(--o); +} +.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, +.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { + color:var(--y); +} +.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, +.org-doc, .org-keyword, .DONE { + color:var(--g); +} + +.org-highlight-numbers-number, .org-highlight-number-number, +.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, +.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, +.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, +.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { + color:var(--fg0); +} diff --git a/_site/src/css/latex.css b/_site/src/css/latex.css new file mode 100644 index 0000000..5a1bc41 --- /dev/null +++ b/_site/src/css/latex.css @@ -0,0 +1,379 @@ +/*! + * LaTeX.css (https://latex.now.sh/) + * + * Source: https://github.com/vincentdoerig/latex-css + * Licensed under MIT (https://github.com/vincentdoerig/latex-css/blob/master/LICENSE) +*/ + +@font-face { + font-family: 'Latin Modern'; + font-style: normal; + font-weight: normal; + font-display: swap; + src: url('./fonts/LM-regular.woff2') format('woff2'), + url('./fonts/LM-regular.woff') format('woff'), + url('./fonts/LM-regular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Latin Modern'; + font-style: italic; + font-weight: normal; + font-display: swap; + src: url('./fonts/LM-italic.woff2') format('woff2'), + url('./fonts/LM-italic.woff') format('woff'), + url('./fonts/LM-italic.ttf') format('truetype'); +} + +@font-face { + font-family: 'Latin Modern'; + font-style: normal; + font-weight: bold; + font-display: swap; + src: url('./fonts/LM-bold.woff2') format('woff2'), + url('./fonts/LM-bold.woff') format('woff'), + url('./fonts/LM-bold.ttf') format('truetype'); +} + +@font-face { + font-family: 'Latin Modern'; + font-style: italic; + font-weight: bold; + font-display: swap; + src: url('./fonts/LM-bold-italic.woff2') format('woff2'), + url('./fonts/LM-bold-italic.woff') format('woff'), + url('./fonts/LM-bold-italic.ttf') format('truetype'); +} + +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Remove default margin */ +body, +h1, +h2, +h3, +h4, +p, +ul[class], +ol[class], +li, +figure, +figcaption, +dl, +dd { + margin: 0; +} + +/* Make default font-size 1rem and add smooth scrolling to anchors */ +html { + font-size: 1rem; + scroll-behavior: smooth; +} + +body { + font-family: 'Latin Modern', Georgia, Cambria, 'Times New Roman', Times, serif; + line-height: 1.8; + + max-width: 80ch; + min-height: 100vh; + overflow-x: hidden; + margin: 0 auto; + padding: 2rem 1.25rem; + + counter-reset: theorem; + counter-reset: definition; + + color: hsl(0, 5%, 10%); + background-color: hsl(210, 20%, 98%); + + text-rendering: optimizeLegibility; +} + +/* Justify and hyphenate all paragraphs */ +p { + text-align: justify; + hyphens: auto; + -webkit-hyphens: auto; + -moz-hyphens: auto; + margin-top: 1rem; +} + +/* A elements that don't have a class get default styles */ +a:not([class]) { + text-decoration-skip-ink: auto; +} + +/* Make links red */ +a, +a:visited { + color: #a00; +} + +/* Make images easier to work with */ +img { + max-width: 100%; + display: block; +} + +/* Inherit fonts for inputs and buttons */ +input, +button, +textarea, +select { + font: inherit; +} + +/* Prevent textarea from overflowing */ +textarea { + width: 100%; +} + +/* Natural flow and rhythm in articles by default */ +article > * + * { + margin-top: 1em; +} + +/* Styles for inline code or code snippets */ +code, +pre, +kbd { + font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', + monospace; + font-size: 85%; +} +pre { + padding: 1rem 1.4rem; + max-width: 100%; + overflow: auto; + border: 1px solid hsl(210, 15%, 49%); + border-radius: 4px; + background: hsl(210, 40%, 96%); +} +pre code { + font-size: 95%; + position: relative; +} +kbd { + background: hsl(210, 5%, 100%); + border: 1px solid hsl(210, 5%, 70%); + border-radius: 2px; + padding: 2px 4px; + font-size: 75%; +} + +/* Make table 100% width, add borders between rows */ +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + max-width: 100%; +} +th, +td { + text-align: left; + padding: 0.5rem; +} +td { + border-bottom: 1px solid hsl(0, 0%, 85%); +} +thead th { + border-bottom: 2px solid hsl(0, 0%, 70%); +} +tfoot th { + border-top: 2px solid hsl(0, 0%, 70%); +} + +/* Center align the title */ +h1:first-child { + text-align: center; +} + +/* Nested ordered list for ToC */ +nav ol { + counter-reset: item; + padding-left: 2rem; +} +nav li { + display: block; +} +nav li:before { + content: counters(item, '.') ' '; + counter-increment: item; + padding-right: 0.85rem; +} + +/* Center definitions (most useful for display equations) */ +dl dd { + text-align: center; +} + +/* Theorem */ +.theorem { + counter-increment: theorem; + display: block; + margin: 12px 0; + font-style: italic; +} +.theorem::before { + content: 'Theorem ' counter(theorem) '. '; + font-weight: bold; + font-style: normal; +} + +/* Lemma */ +.lemma { + counter-increment: theorem; + display: block; + margin: 12px 0; + font-style: italic; +} +.lemma::before { + content: 'Lemma ' counter(theorem) '. '; + font-weight: bold; + font-style: normal; +} + +/* Proof */ +.proof { + display: block; + margin: 12px 0; + font-style: normal; + position: relative; +} +.proof::before { + content: 'Proof. ' attr(title); + font-style: italic; +} +.proof:after { + content: '◾️'; + position: absolute; + right: -12px; + bottom: -2px; +} + +/* Definition */ +.definition { + counter-increment: definition; + display: block; + margin: 12px 0; + font-style: normal; +} +.definition::before { + content: 'Definition ' counter(definition) '. '; + font-weight: bold; + font-style: normal; +} + +/* Center align author name, use small caps and add vertical spacing */ +.author { + margin: 0.85rem 0; + font-variant-caps: small-caps; + text-align: center; +} + +/* Make footnote text smaller and left align it (looks bad with long URLs) */ +.footnotes p { + text-align: left; + line-height: 1.5; + font-size: 85%; + margin-bottom: 0.4rem; +} +.footnotes { + border-top: 1px solid hsl(0, 0%, 39%); +} + +/* Center title and paragraph */ +.abstract, +.abstract p { + text-align: center; +} +.abstract { + margin: 2.25rem 0; +} + +/* Format the LaTeX symbol correctly (a higher up, e lower) */ +.latex span:nth-child(1) { + text-transform: uppercase; + font-size: 0.75em; + vertical-align: 0.25em; + margin-left: -0.36em; + margin-right: -0.15em; + line-height: 1ex; +} + +.latex span:nth-child(2) { + text-transform: uppercase; + vertical-align: -0.5ex; + margin-left: -0.1667em; + margin-right: -0.125em; + line-height: 1ex; +} + +/* Heading typography */ +h1 { + font-size: 2.5rem; + line-height: 3.25rem; + margin-bottom: 1.625rem; +} + +h2 { + font-size: 1.7rem; + line-height: 2rem; + margin-top: 3rem; +} + +h3 { + font-size: 1.4rem; + margin-top: 2.5rem; +} + +h4 { + font-size: 1.2rem; + margin-top: 2rem; +} + +h5 { + font-size: 1rem; + margin-top: 1.8rem; +} + +h6 { + font-size: 1rem; + font-style: italic; + font-weight: normal; + margin-top: 2.5rem; +} + +h3, +h4, +h5, +h6 { + line-height: 1.625rem; +} + +h1 + h2 { + margin-top: 1.625rem; +} + +h2 + h3, +h3 + h4, +h4 + h5 { + margin-top: 0.8rem; +} + +h5 + h6 { + margin-top: -0.8rem; +} + +h2, +h3, +h4, +h5, +h6 { + margin-bottom: 0.8rem; +} diff --git a/_site/src/css/mk.css b/_site/src/css/mk.css new file mode 100644 index 0000000..cec9502 --- /dev/null +++ b/_site/src/css/mk.css @@ -0,0 +1,139 @@ +/* COLORS */ + +/* colortheme switch */ +body>input { display: none; } +#labels > .content { margin: 0 auto; text-align: center; } +label { font-weight: 700; } +label:hover { cursor: pointer; } +#logo { text-align: center; } +body { margin:0; padding: 0; border: 0; max-width: none;} +#content,.content,#preamble,#postamble { + max-width: 80ch; + overflow-x: hidden; + margin: 0 auto; +} +figure img { width: 100%; } +.footdef > sup { vertical-align: top; font-size: medium; } +.footdef > sup > a { padding: 0.5em; } +.footpara { display: inline; } +footer { margin: 3em 0; padding: 1em 0; border-top: solid 1px; border-bottom: solid 1px; line-height: 1em; } +#postamble td { border-bottom: none; } +nav { text-align: center; padding: 2em 0; } + + +:root { + --b03: #2E3440; + --b02: #3B4252; + /* not used because light mode is has more contrast + --b01: #656b74; + */ + --b00: #727781; + --b0: #989ea8; + --b1: #b0bac7; + --b2: #ECEFF4; + --b3: #fff; + --y: #c18600; + --o: #d84100; + --r: #e62729; + --m: #ec0085; + --v: #6c71c4; + --b: #0095ff; + --c: #00b0a3; + --g: #879a00; + + /* default light */ + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--o); +} + +/* light checked */ +input#l:checked ~ div { + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--o); +} +input#l:checked ~ div img { + filter: none; +} + +/* dark checked */ +input#d:checked ~ div { + --bg: hsl(210,20%,2%); + --rbg: var(--b03); + --fg: var(--b1); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--y); +} +input#d:checked ~ div img { + filter: brightness(0.5) saturate(0.5); +} + +/* dark preferred */ +@media (prefers-color-scheme: dark) +{ + :root { + --bg: black; + --rbg: var(--b03); + --fg: var(--b1); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--y); + } + img { filter: brightness(0.5) saturate(0.5); } +} +body, body > div { + background: var(--bg); + color: var(--fg); +} +a,a:visited { color: var(--hl); } + +/* ---- SYNTAX HIGHLIGHTING ---- */ +.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, +.org-css-selector, .org-nix-attribute, .org-builtin, +.IN_REVIEW { + color:var(--c); +} + +.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, +.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed { + color:var(--b); +} + +.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { + color:var(--v); +} + +.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, +.CANCELED { + color:var(--m); +} +.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { + color:var(--r); +} +.org-rainbow-delimiters-depth-6, .org-haskell-constructor { + color:var(--o); +} +.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, +.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { + color:var(--y); +} +.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, +.org-doc, .org-keyword, .DONE { + color:var(--g); +} + +.org-highlight-numbers-number, .org-highlight-number-number, +.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, +.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, +.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, +.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { + color:var(--fg0); +} diff --git a/_site/src/css/slides.css b/_site/src/css/slides.css new file mode 100644 index 0000000..a272261 --- /dev/null +++ b/_site/src/css/slides.css @@ -0,0 +1,20 @@ +.outline-4 { + margin: 1em 0; + padding: 1em; + border: solid; + min-height: 21em; + display: block; +} +.outline-3 > h3, +.outline-2 > h2 { + border: solid; + padding: 10em 1em; + margin: 1em 0; + text-align: center; +} +#content,.content { + max-width: 53em !important; +} +#preamble { + margin-bottom: 2em; +} diff --git a/_site/src/css/y.css b/_site/src/css/y.css new file mode 100644 index 0000000..edcd680 --- /dev/null +++ b/_site/src/css/y.css @@ -0,0 +1,600 @@ +/* Fonts if you need them +@font-face { + font-family: 'CMU Serif'; + font-style: normal; + font-weight: normal; + font-display: swap; + src: url('./fonts/cmunrm.woff2') format('woff2'), + url('./fonts/cmunrm.woff') format('woff'), + url('./fonts/cmunrm.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Serif'; + font-style: italic; + font-weight: normal; + font-display: swap; + src: url('./fonts/cmunti.woff2') format('woff2'), + url('./fonts/cmunti.woff') format('woff'), + url('./fonts/cmunti.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Serif'; + font-style: normal; + font-weight: bold; + font-display: swap; + src: url('./fonts/cmunbx.woff2') format('woff2'), + url('./fonts/cmunbx.woff') format('woff'), + url('./fonts/cmunbx.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Serif'; + font-style: italic; + font-weight: bold; + font-display: swap; + src: url('./fonts/cmunbi.woff2') format('woff2'), + url('./fonts/cmunbi.woff') format('woff'), + url('./fonts/cmunbi.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Typewriter'; + font-style: normal; + font-weight: normal; + font-display: swap; + src: url('./fonts/cmuntt.woff2') format('woff2'), + url('./fonts/cmuntt.woff') format('woff'), + url('./fonts/cmuntt.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Typewriter'; + font-style: italic; + font-weight: normal; + font-display: swap; + src: url('./fonts/cmunit.woff2') format('woff2'), + url('./fonts/cmunit.woff') format('woff'); + url('./fonts/cmunit.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Typewriter'; + font-style: normal; + font-weight: bold; + font-display: swap; + src: url('./fonts/cmuntb.woff2') format('woff2'), + url('./fonts/cmuntb.woff') format('woff'), + url('./fonts/cmuntb.ttf') format('truetype'); +} + +@font-face { + font-family: 'CMU Typewriter'; + font-style: italic; + font-weight: bold; + font-display: swap; + src: url('./fonts/cmuntx.woff2') format('woff2'), + url('./fonts/cmuntx.woff') format('woff'), + url('./fonts/cmuntx.ttf') format('truetype'); +} + +*/ + +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Remove default margin */ +body, +h1, +h2, +h3, +h4, +p, +ul[class], +ol[class], +li, +figcaption, +dl, +dd { + margin: 0; +} +figure { margin: 1em 0; } + +/* Make default font-size 1rem and add smooth scrolling to anchors */ +html { + font-size: 1rem; + scroll-behavior: smooth; +} + +body { + font-family: "American Typewriter", Georgia, serif; + line-height: 1.5; + + max-width: 60ch; + min-height: 100vh; + overflow-x: hidden; + margin: 0 auto; + padding: 2rem 1.25rem; + + counter-reset: theorem; + counter-reset: definition; + + color: hsl(0, 5%, 10%); + background-color: hsl(218, 20%, 98%); + + text-rendering: optimizeLegibility; +} + +/* Justify and hyphenate all paragraphs */ +p { + text-align: justify; + hyphens: auto; + -webkit-hyphens: auto; + -moz-hyphens: auto; + margin-top: 1rem; +} + +/* A elements that don't have a class get default styles */ +a:not([class]) { + text-decoration-skip-ink: auto; +} + +/* Make images easier to work with */ +img { + max-width: 100%; + display: block; +} + +/* Inherit fonts for inputs and buttons */ +input, +button, +textarea, +select { + font: inherit; +} + +/* Prevent textarea from overflowing */ +textarea { + width: 100%; +} + +/* Natural flow and rhythm in articles by default */ +article > * + * { + margin-top: 1em; +} + +/* Styles for inline code or code snippets */ +code, +pre, +kbd { + font-family: Courier, monospace; +} +pre { + padding: 1rem; + max-width: 100%; + overflow: auto; + border: 1px solid hsl(218, 15%, 49%); + border-radius: 4px; + background: hsl(218, 40%, 96%); + font-size: 85%; +} +pre code { + font-size: 95%; + position: relative; +} +kbd { + background: hsl(218, 5%, 100%); + border: 1px solid hsl(218, 5%, 70%); + border-radius: 2px; + padding: 2px 4px; + font-size: 75%; +} + +/* Make table 100% width, add borders between rows */ +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + max-width: 100%; +} +th, +td { + text-align: left; + padding: 0.5rem; +} +td { + border-bottom: 1px solid hsl(0, 0%, 85%); +} +thead th { + border-bottom: 2px solid hsl(0, 0%, 70%); +} +tfoot th { + border-top: 2px solid hsl(0, 0%, 70%); +} + +/* Center align the title */ +h1:first-child { + text-align: center; +} + +/* Nested ordered list for ToC */ +nav ol { + counter-reset: item; + padding-left: 2rem; +} +nav li { + display: block; +} + +/* Center definitions (most useful for display equations) */ +dl dt { font-weight: 700; } +dl dd { + padding-left: 3rem; +} + +/* Theorem */ +.theorem { + counter-increment: theorem; + display: block; + margin: 12px 0; + font-style: italic; +} +.theorem::before { + content: 'Theorem ' counter(theorem) '. '; + font-weight: bold; + font-style: normal; +} + +/* Lemma */ +.lemma { + counter-increment: theorem; + display: block; + margin: 12px 0; + font-style: italic; +} +.lemma::before { + content: 'Lemma ' counter(theorem) '. '; + font-weight: bold; + font-style: normal; +} + +/* Proof */ +.proof { + display: block; + margin: 12px 0; + font-style: normal; + position: relative; +} +.proof::before { + content: 'Proof. ' attr(title); + font-style: italic; +} +.proof:after { + content: '◾️'; + position: absolute; + right: -12px; + bottom: -2px; +} + +/* Definition */ +.definition { + counter-increment: definition; + display: block; + margin: 12px 0; + font-style: normal; +} +.definition::before { + content: 'Definition ' counter(definition) '. '; + font-weight: bold; + font-style: normal; +} + +/* Center align author name, use small caps and add vertical spacing */ +.author { + margin: 0.85rem 0; + font-variant-caps: small-caps; + text-align: center; +} + +/* Make footnote text smaller and left align it (looks bad with long URLs) */ +.footref { display: inline-block; padding: 0 3px; } +.footnotes p { + text-align: left; + line-height: 1.5; + font-size: 85%; + margin-bottom: 0.4rem; +} +.footnotes { + border-top: 1px solid hsl(0, 0%, 39%); +} + +/* Center title and paragraph */ +.abstract, +.abstract p { + text-align: center; +} +.abstract { + margin: 2.25rem 0; +} + +/* Format the LaTeX symbol correctly (a higher up, e lower) */ +.latex span:nth-child(1) { + text-transform: uppercase; + font-size: 0.75em; + vertical-align: 0.25em; + margin-left: -0.36em; + margin-right: -0.15em; + line-height: 1ex; +} + +.latex span:nth-child(2) { + text-transform: uppercase; + vertical-align: -0.5ex; + margin-left: -0.1667em; + margin-right: -0.125em; + line-height: 1ex; +} + +/* Heading typography */ +h1 { + font-size: 2.5rem; + line-height: 3.25rem; + margin-bottom: 1.625rem; +} + +h2 { + font-size: 1.7rem; + line-height: 2rem; + margin-top: 3rem; +} + +h3 { + font-size: 1.4rem; + margin-top: 2.5rem; +} + +h4 { + font-size: 1.2rem; + margin-top: 2rem; +} + +h5 { + font-size: 1rem; + margin-top: 1.8rem; +} + +h6 { + font-size: 1rem; + font-style: italic; + font-weight: normal; + margin-top: 2.5rem; +} + +h3, +h4, +h5, +h6 { + line-height: 1.625rem; +} + +h1 + h2 { + margin-top: 1.625rem; +} + +h2 + h3, +h3 + h4, +h4 + h5 { + margin-top: 0.8rem; +} + +h5 + h6 { + margin-top: -0.8rem; +} + +h2, +h3, +h4, +h5, +h6 { + margin-bottom: 0.8rem; +} +/* COLORS */ + +/* colortheme switch */ +body>input { display: none; } +#labels > .content { margin: 0 auto; text-align: center; } +label { font-weight: 700; } +label:hover { cursor: pointer; } +label ~ pre { margin-top: 0; } +.org-src-container { margin: 1rem 0; } +#logo { text-align: center; } +body { margin:0; padding: 0; border: 0; max-width: none;} +#preamble, #postamble { text-align: center; } +#content,.content,#preamble,#postamble { + max-width: 60ch; + overflow: hidden; + margin: 0 auto; +} +figure img { width: 100%; } +.footdef > sup { vertical-align: top; font-size: medium; } +.footdef > sup > a { padding: 0.5em; } +.footpara { display: inline; } +footer { margin: 3em 0; + padding: 1em 0; + border-top: solid 1px; + border-bottom: solid 1px; + line-height: 1em; + font-size: 0.85em; + } +td { border-bottom: none; padding: .2rem; } +table { margin-top: 1rem; } +nav { text-align: center; padding: 2em 0; } +pre { line-height: 1em; } + +:root { + --b03: #2E3440; + --b02: #3B4252; + /* not used because light mode is has more contrast + --b01: #656b74; + */ + --b00: #727781; + --b0: #989ea8; + --b1: #b0bac7; + --b2: #ECEFF4; + --b3: #fff; + --y: #c18600; + --o: #d84100; + --r: #e62729; + --m: #ec0085; + --v: #6c71c4; + --b: #0095ff; + --c: #00b0a3; + --g: #879a00; + + /* default light */ + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--r); +} + +/* dark preferred */ +@media (prefers-color-scheme: dark) +{ + :root { + --bg: hsl(218,20%,16%); + --rbg: var(--b03); + --fg: var(--b0); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--g); + --y: #ae8c51; + --o: #a9654a; + --r: #af6255; + --m: #ae5e7d; + --v: #6774b2; + --b: #3f8cc3; + --c: #15a198; + --g: #939452; + } + img { filter: brightness(0.7) saturate(0.5); } + pre { + background: hsl(218,20%,18%); + border-color: hsl(218,15%,23%); + } +} + +/* light checked */ +input#l:checked ~ div { + --bg: var(--b3); + --rbg: var(--b2); + --fg0: var(--b0); + --fg: var(--b02); + --rfg: #000; + --hl: var(--o); + --y: #c18600; + --o: #d84100; + --r: #e62729; + --m: #ec0085; + --v: #6c71c4; + --b: #0095ff; + --c: #00b0a3; + --g: #879a00; +} +input#l:checked ~ div img { + filter: none; +} +input#l:checked ~ div pre { + border: 1px solid hsl(218, 15%, 49%); + background: hsl(218, 40%, 96%); +} + +/* dark checked */ +input#d:checked ~ div { + --bg: hsl(218,20%,16%); + --rbg: var(--b03); + --fg: var(--b0); + --fg0: var(--b00); + --rfg: var(--b2); + --hl: var(--g); + --y: #ae8c51; + --o: #a9654a; + --r: #af6255; + --m: #ae5e7d; + --v: #6774b2; + --b: #3f8cc3; + --c: #15a198; + --g: #939452; +} +input#d:checked ~ div img { + filter: brightness(0.7) saturate(0.5); +} +input#d:checked ~ div pre { + background: hsl(218,20%,18%); + border-color: hsl(218,15%,23%); +} + +/* ---- */ +::selection { + background: var(--m); + color: hsl(218,40%,96%); + text-decoration: hsl(218,40%,96%); +} + +body, body > div { + background: var(--bg); + color: var(--fg); +} +a,a:visited { color: var(--hl); } + +/* ---- SYNTAX HIGHLIGHTING ---- */ +#table-of-contents { text-align: left; } +.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, +.org-css-selector, .org-builtin, +.IN_REVIEW { + color:var(--c); +} + +.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, +.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed, +.org-nix-attribute, .org-nxml-element-local-name { + color:var(--b); +} + +.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { + color:var(--v); +} + +.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, +.CANCELED { + color:var(--m); +} +.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { + color:var(--r); +} +.org-rainbow-delimiters-depth-6, .org-haskell-constructor { + color:var(--o); +} +.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, +.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { + color:var(--y); +} +.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, +.org-doc, .org-keyword, .DONE { + color:var(--g); +} + +.org-highlight-numbers-number, .org-highlight-number-number, +.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, +.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, +.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, +.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { + color:var(--fg0); +} From 5359765bf54640e2f89c5b99ecddeead15dc5cec Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 12:27:45 +0200 Subject: [PATCH 08/27] updated --- .gitignore | 2 ++ Shakefile.hs | 22 ++++++++++++++++++++-- _site/index.html | 13 ------------- 3 files changed, 22 insertions(+), 15 deletions(-) delete mode 100644 _site/index.html diff --git a/.gitignore b/.gitignore index e3771aa..bb5e6a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ _cache/ +_site/ +_optim/ src/archive.org .direnv/ _shake/ diff --git a/Shakefile.hs b/Shakefile.hs index 9e15316..837aad1 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -80,25 +80,43 @@ sortByPostDate :: [BlogPost] -> [BlogPost] sortByPostDate = sortBy (\b a -> compare (Down (postDate a)) (Down (postDate b))) + +build = () siteDir + buildRules :: Rules () buildRules = do - let build = () siteDir cleanRule + allRule getPost <- mkGetPost getPosts <- mkGetPosts getPost let cssDeps = map (siteDir ) <$> getDirectoryFiles "" ["src/css/*.css"] - build "index.html" %> \out -> do + build "articles.html" %> \out -> do css <- cssDeps posts <- getPosts () need $ css <> map postUrl (sortByPostDate posts) let titles = T.unpack $ T.intercalate "\n" $ map postTitle posts writeFile' out titles + build "index.html" %> \out -> do + css <- cssDeps + need $ css <> ["src/index.org"] + bp <- getPost "src/index.org" + eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) + case eitherHtml of + Left _ -> fail "BAD" + Right htmlFile -> writeFile' out (T.unpack htmlFile) -- build "//*.html" %> \out -> do -- css <- cssDeps -- let orgfile = dropDirectory1 out -- post <- getPost orgfile build "src/css/*.css" %> \out -> copyFile' (dropDirectory1 out) out + +allRule :: Rules () +allRule = + phony "all" $ + need (map build [ "index.html" + , "articles.html"]) + cleanRule :: Rules () cleanRule = phony "clean" $ do diff --git a/_site/index.html b/_site/index.html deleted file mode 100644 index 255da53..0000000 --- a/_site/index.html +++ /dev/null @@ -1,13 +0,0 @@ -New Blog -Troll 2 -Autoload Script by project -How I Internet -RSS Generation -Modern IRC -Catalina iTerm Theme switch -Further Blog Engine change -Optimize the size of no js websites -Learn Haskell Now! -Add links to code block during orgmode export -Solaryzed: A Generalisation of Solarized -How to choose your tools \ No newline at end of file From a706933d96b4bf0a4eaaa817d010f41f66b38583 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 14:32:03 +0200 Subject: [PATCH 09/27] remove ignored files --- _site/src/css/colors.css | 139 --------- _site/src/css/latex.css | 379 ------------------------- _site/src/css/mk.css | 139 --------- _site/src/css/slides.css | 20 -- _site/src/css/y.css | 600 --------------------------------------- 5 files changed, 1277 deletions(-) delete mode 100644 _site/src/css/colors.css delete mode 100644 _site/src/css/latex.css delete mode 100644 _site/src/css/mk.css delete mode 100644 _site/src/css/slides.css delete mode 100644 _site/src/css/y.css diff --git a/_site/src/css/colors.css b/_site/src/css/colors.css deleted file mode 100644 index 2d3edf5..0000000 --- a/_site/src/css/colors.css +++ /dev/null @@ -1,139 +0,0 @@ -/* COLORS */ - -/* colortheme switch */ -body>input { display: none; } -#labels > .content { margin: 0 auto; text-align: center; } -label { font-weight: 700; } -label:hover { cursor: pointer; } -#logo { text-align: center; } -body { margin:0; padding: 0; border: 0; max-width: none;} -#content,.content,#preamble,#postamble { - max-width: 80ch; - overflow: hidden; - margin: 0 auto; -} -figure img { width: 100%; } -.footdef > sup { vertical-align: top; font-size: medium; } -.footdef > sup > a { padding: 0.5em; } -.footpara { display: inline; } -footer { margin: 3em 0; padding: 1em 0; border-top: solid 1px; border-bottom: solid 1px; line-height: 1em; } -#postamble td { border-bottom: none; } -nav { text-align: center; padding: 2em 0; } - - -:root { - --b03: #2E3440; - --b02: #3B4252; - /* not used because light mode is has more contrast - --b01: #656b74; - */ - --b00: #727781; - --b0: #989ea8; - --b1: #b0bac7; - --b2: #ECEFF4; - --b3: #fff; - --y: #c18600; - --o: #d84100; - --r: #e62729; - --m: #ec0085; - --v: #6c71c4; - --b: #0095ff; - --c: #00b0a3; - --g: #879a00; - - /* default light */ - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--o); -} - -/* light checked */ -input#l:checked ~ div { - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--o); -} -input#l:checked ~ div img { - filter: none; -} - -/* dark checked */ -input#d:checked ~ div { - --bg: hsl(210,20%,2%); - --rbg: var(--b03); - --fg: var(--b1); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--y); -} -input#d:checked ~ div img { - filter: brightness(0.5) saturate(0.5); -} - -/* dark preferred */ -@media (prefers-color-scheme: dark) -{ - :root { - --bg: black; - --rbg: var(--b03); - --fg: var(--b1); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--y); - } - img { filter: brightness(0.5) saturate(0.5); } -} -body, body > div { - background: var(--bg); - color: var(--fg); -} -a,a:visited { color: var(--hl); } - -/* ---- SYNTAX HIGHLIGHTING ---- */ -.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, -.org-css-selector, .org-nix-attribute, .org-builtin, -.IN_REVIEW { - color:var(--c); -} - -.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, -.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed { - color:var(--b); -} - -.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { - color:var(--v); -} - -.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, -.CANCELED { - color:var(--m); -} -.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { - color:var(--r); -} -.org-rainbow-delimiters-depth-6, .org-haskell-constructor { - color:var(--o); -} -.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, -.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { - color:var(--y); -} -.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, -.org-doc, .org-keyword, .DONE { - color:var(--g); -} - -.org-highlight-numbers-number, .org-highlight-number-number, -.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, -.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, -.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, -.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { - color:var(--fg0); -} diff --git a/_site/src/css/latex.css b/_site/src/css/latex.css deleted file mode 100644 index 5a1bc41..0000000 --- a/_site/src/css/latex.css +++ /dev/null @@ -1,379 +0,0 @@ -/*! - * LaTeX.css (https://latex.now.sh/) - * - * Source: https://github.com/vincentdoerig/latex-css - * Licensed under MIT (https://github.com/vincentdoerig/latex-css/blob/master/LICENSE) -*/ - -@font-face { - font-family: 'Latin Modern'; - font-style: normal; - font-weight: normal; - font-display: swap; - src: url('./fonts/LM-regular.woff2') format('woff2'), - url('./fonts/LM-regular.woff') format('woff'), - url('./fonts/LM-regular.ttf') format('truetype'); -} - -@font-face { - font-family: 'Latin Modern'; - font-style: italic; - font-weight: normal; - font-display: swap; - src: url('./fonts/LM-italic.woff2') format('woff2'), - url('./fonts/LM-italic.woff') format('woff'), - url('./fonts/LM-italic.ttf') format('truetype'); -} - -@font-face { - font-family: 'Latin Modern'; - font-style: normal; - font-weight: bold; - font-display: swap; - src: url('./fonts/LM-bold.woff2') format('woff2'), - url('./fonts/LM-bold.woff') format('woff'), - url('./fonts/LM-bold.ttf') format('truetype'); -} - -@font-face { - font-family: 'Latin Modern'; - font-style: italic; - font-weight: bold; - font-display: swap; - src: url('./fonts/LM-bold-italic.woff2') format('woff2'), - url('./fonts/LM-bold-italic.woff') format('woff'), - url('./fonts/LM-bold-italic.ttf') format('truetype'); -} - -/* Box sizing rules */ -*, -*::before, -*::after { - box-sizing: border-box; -} - -/* Remove default margin */ -body, -h1, -h2, -h3, -h4, -p, -ul[class], -ol[class], -li, -figure, -figcaption, -dl, -dd { - margin: 0; -} - -/* Make default font-size 1rem and add smooth scrolling to anchors */ -html { - font-size: 1rem; - scroll-behavior: smooth; -} - -body { - font-family: 'Latin Modern', Georgia, Cambria, 'Times New Roman', Times, serif; - line-height: 1.8; - - max-width: 80ch; - min-height: 100vh; - overflow-x: hidden; - margin: 0 auto; - padding: 2rem 1.25rem; - - counter-reset: theorem; - counter-reset: definition; - - color: hsl(0, 5%, 10%); - background-color: hsl(210, 20%, 98%); - - text-rendering: optimizeLegibility; -} - -/* Justify and hyphenate all paragraphs */ -p { - text-align: justify; - hyphens: auto; - -webkit-hyphens: auto; - -moz-hyphens: auto; - margin-top: 1rem; -} - -/* A elements that don't have a class get default styles */ -a:not([class]) { - text-decoration-skip-ink: auto; -} - -/* Make links red */ -a, -a:visited { - color: #a00; -} - -/* Make images easier to work with */ -img { - max-width: 100%; - display: block; -} - -/* Inherit fonts for inputs and buttons */ -input, -button, -textarea, -select { - font: inherit; -} - -/* Prevent textarea from overflowing */ -textarea { - width: 100%; -} - -/* Natural flow and rhythm in articles by default */ -article > * + * { - margin-top: 1em; -} - -/* Styles for inline code or code snippets */ -code, -pre, -kbd { - font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', - monospace; - font-size: 85%; -} -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; - border: 1px solid hsl(210, 15%, 49%); - border-radius: 4px; - background: hsl(210, 40%, 96%); -} -pre code { - font-size: 95%; - position: relative; -} -kbd { - background: hsl(210, 5%, 100%); - border: 1px solid hsl(210, 5%, 70%); - border-radius: 2px; - padding: 2px 4px; - font-size: 75%; -} - -/* Make table 100% width, add borders between rows */ -table { - border-collapse: collapse; - border-spacing: 0; - width: 100%; - max-width: 100%; -} -th, -td { - text-align: left; - padding: 0.5rem; -} -td { - border-bottom: 1px solid hsl(0, 0%, 85%); -} -thead th { - border-bottom: 2px solid hsl(0, 0%, 70%); -} -tfoot th { - border-top: 2px solid hsl(0, 0%, 70%); -} - -/* Center align the title */ -h1:first-child { - text-align: center; -} - -/* Nested ordered list for ToC */ -nav ol { - counter-reset: item; - padding-left: 2rem; -} -nav li { - display: block; -} -nav li:before { - content: counters(item, '.') ' '; - counter-increment: item; - padding-right: 0.85rem; -} - -/* Center definitions (most useful for display equations) */ -dl dd { - text-align: center; -} - -/* Theorem */ -.theorem { - counter-increment: theorem; - display: block; - margin: 12px 0; - font-style: italic; -} -.theorem::before { - content: 'Theorem ' counter(theorem) '. '; - font-weight: bold; - font-style: normal; -} - -/* Lemma */ -.lemma { - counter-increment: theorem; - display: block; - margin: 12px 0; - font-style: italic; -} -.lemma::before { - content: 'Lemma ' counter(theorem) '. '; - font-weight: bold; - font-style: normal; -} - -/* Proof */ -.proof { - display: block; - margin: 12px 0; - font-style: normal; - position: relative; -} -.proof::before { - content: 'Proof. ' attr(title); - font-style: italic; -} -.proof:after { - content: '◾️'; - position: absolute; - right: -12px; - bottom: -2px; -} - -/* Definition */ -.definition { - counter-increment: definition; - display: block; - margin: 12px 0; - font-style: normal; -} -.definition::before { - content: 'Definition ' counter(definition) '. '; - font-weight: bold; - font-style: normal; -} - -/* Center align author name, use small caps and add vertical spacing */ -.author { - margin: 0.85rem 0; - font-variant-caps: small-caps; - text-align: center; -} - -/* Make footnote text smaller and left align it (looks bad with long URLs) */ -.footnotes p { - text-align: left; - line-height: 1.5; - font-size: 85%; - margin-bottom: 0.4rem; -} -.footnotes { - border-top: 1px solid hsl(0, 0%, 39%); -} - -/* Center title and paragraph */ -.abstract, -.abstract p { - text-align: center; -} -.abstract { - margin: 2.25rem 0; -} - -/* Format the LaTeX symbol correctly (a higher up, e lower) */ -.latex span:nth-child(1) { - text-transform: uppercase; - font-size: 0.75em; - vertical-align: 0.25em; - margin-left: -0.36em; - margin-right: -0.15em; - line-height: 1ex; -} - -.latex span:nth-child(2) { - text-transform: uppercase; - vertical-align: -0.5ex; - margin-left: -0.1667em; - margin-right: -0.125em; - line-height: 1ex; -} - -/* Heading typography */ -h1 { - font-size: 2.5rem; - line-height: 3.25rem; - margin-bottom: 1.625rem; -} - -h2 { - font-size: 1.7rem; - line-height: 2rem; - margin-top: 3rem; -} - -h3 { - font-size: 1.4rem; - margin-top: 2.5rem; -} - -h4 { - font-size: 1.2rem; - margin-top: 2rem; -} - -h5 { - font-size: 1rem; - margin-top: 1.8rem; -} - -h6 { - font-size: 1rem; - font-style: italic; - font-weight: normal; - margin-top: 2.5rem; -} - -h3, -h4, -h5, -h6 { - line-height: 1.625rem; -} - -h1 + h2 { - margin-top: 1.625rem; -} - -h2 + h3, -h3 + h4, -h4 + h5 { - margin-top: 0.8rem; -} - -h5 + h6 { - margin-top: -0.8rem; -} - -h2, -h3, -h4, -h5, -h6 { - margin-bottom: 0.8rem; -} diff --git a/_site/src/css/mk.css b/_site/src/css/mk.css deleted file mode 100644 index cec9502..0000000 --- a/_site/src/css/mk.css +++ /dev/null @@ -1,139 +0,0 @@ -/* COLORS */ - -/* colortheme switch */ -body>input { display: none; } -#labels > .content { margin: 0 auto; text-align: center; } -label { font-weight: 700; } -label:hover { cursor: pointer; } -#logo { text-align: center; } -body { margin:0; padding: 0; border: 0; max-width: none;} -#content,.content,#preamble,#postamble { - max-width: 80ch; - overflow-x: hidden; - margin: 0 auto; -} -figure img { width: 100%; } -.footdef > sup { vertical-align: top; font-size: medium; } -.footdef > sup > a { padding: 0.5em; } -.footpara { display: inline; } -footer { margin: 3em 0; padding: 1em 0; border-top: solid 1px; border-bottom: solid 1px; line-height: 1em; } -#postamble td { border-bottom: none; } -nav { text-align: center; padding: 2em 0; } - - -:root { - --b03: #2E3440; - --b02: #3B4252; - /* not used because light mode is has more contrast - --b01: #656b74; - */ - --b00: #727781; - --b0: #989ea8; - --b1: #b0bac7; - --b2: #ECEFF4; - --b3: #fff; - --y: #c18600; - --o: #d84100; - --r: #e62729; - --m: #ec0085; - --v: #6c71c4; - --b: #0095ff; - --c: #00b0a3; - --g: #879a00; - - /* default light */ - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--o); -} - -/* light checked */ -input#l:checked ~ div { - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--o); -} -input#l:checked ~ div img { - filter: none; -} - -/* dark checked */ -input#d:checked ~ div { - --bg: hsl(210,20%,2%); - --rbg: var(--b03); - --fg: var(--b1); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--y); -} -input#d:checked ~ div img { - filter: brightness(0.5) saturate(0.5); -} - -/* dark preferred */ -@media (prefers-color-scheme: dark) -{ - :root { - --bg: black; - --rbg: var(--b03); - --fg: var(--b1); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--y); - } - img { filter: brightness(0.5) saturate(0.5); } -} -body, body > div { - background: var(--bg); - color: var(--fg); -} -a,a:visited { color: var(--hl); } - -/* ---- SYNTAX HIGHLIGHTING ---- */ -.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, -.org-css-selector, .org-nix-attribute, .org-builtin, -.IN_REVIEW { - color:var(--c); -} - -.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, -.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed { - color:var(--b); -} - -.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { - color:var(--v); -} - -.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, -.CANCELED { - color:var(--m); -} -.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { - color:var(--r); -} -.org-rainbow-delimiters-depth-6, .org-haskell-constructor { - color:var(--o); -} -.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, -.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { - color:var(--y); -} -.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, -.org-doc, .org-keyword, .DONE { - color:var(--g); -} - -.org-highlight-numbers-number, .org-highlight-number-number, -.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, -.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, -.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, -.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { - color:var(--fg0); -} diff --git a/_site/src/css/slides.css b/_site/src/css/slides.css deleted file mode 100644 index a272261..0000000 --- a/_site/src/css/slides.css +++ /dev/null @@ -1,20 +0,0 @@ -.outline-4 { - margin: 1em 0; - padding: 1em; - border: solid; - min-height: 21em; - display: block; -} -.outline-3 > h3, -.outline-2 > h2 { - border: solid; - padding: 10em 1em; - margin: 1em 0; - text-align: center; -} -#content,.content { - max-width: 53em !important; -} -#preamble { - margin-bottom: 2em; -} diff --git a/_site/src/css/y.css b/_site/src/css/y.css deleted file mode 100644 index edcd680..0000000 --- a/_site/src/css/y.css +++ /dev/null @@ -1,600 +0,0 @@ -/* Fonts if you need them -@font-face { - font-family: 'CMU Serif'; - font-style: normal; - font-weight: normal; - font-display: swap; - src: url('./fonts/cmunrm.woff2') format('woff2'), - url('./fonts/cmunrm.woff') format('woff'), - url('./fonts/cmunrm.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Serif'; - font-style: italic; - font-weight: normal; - font-display: swap; - src: url('./fonts/cmunti.woff2') format('woff2'), - url('./fonts/cmunti.woff') format('woff'), - url('./fonts/cmunti.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Serif'; - font-style: normal; - font-weight: bold; - font-display: swap; - src: url('./fonts/cmunbx.woff2') format('woff2'), - url('./fonts/cmunbx.woff') format('woff'), - url('./fonts/cmunbx.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Serif'; - font-style: italic; - font-weight: bold; - font-display: swap; - src: url('./fonts/cmunbi.woff2') format('woff2'), - url('./fonts/cmunbi.woff') format('woff'), - url('./fonts/cmunbi.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Typewriter'; - font-style: normal; - font-weight: normal; - font-display: swap; - src: url('./fonts/cmuntt.woff2') format('woff2'), - url('./fonts/cmuntt.woff') format('woff'), - url('./fonts/cmuntt.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Typewriter'; - font-style: italic; - font-weight: normal; - font-display: swap; - src: url('./fonts/cmunit.woff2') format('woff2'), - url('./fonts/cmunit.woff') format('woff'); - url('./fonts/cmunit.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Typewriter'; - font-style: normal; - font-weight: bold; - font-display: swap; - src: url('./fonts/cmuntb.woff2') format('woff2'), - url('./fonts/cmuntb.woff') format('woff'), - url('./fonts/cmuntb.ttf') format('truetype'); -} - -@font-face { - font-family: 'CMU Typewriter'; - font-style: italic; - font-weight: bold; - font-display: swap; - src: url('./fonts/cmuntx.woff2') format('woff2'), - url('./fonts/cmuntx.woff') format('woff'), - url('./fonts/cmuntx.ttf') format('truetype'); -} - -*/ - -/* Box sizing rules */ -*, -*::before, -*::after { - box-sizing: border-box; -} - -/* Remove default margin */ -body, -h1, -h2, -h3, -h4, -p, -ul[class], -ol[class], -li, -figcaption, -dl, -dd { - margin: 0; -} -figure { margin: 1em 0; } - -/* Make default font-size 1rem and add smooth scrolling to anchors */ -html { - font-size: 1rem; - scroll-behavior: smooth; -} - -body { - font-family: "American Typewriter", Georgia, serif; - line-height: 1.5; - - max-width: 60ch; - min-height: 100vh; - overflow-x: hidden; - margin: 0 auto; - padding: 2rem 1.25rem; - - counter-reset: theorem; - counter-reset: definition; - - color: hsl(0, 5%, 10%); - background-color: hsl(218, 20%, 98%); - - text-rendering: optimizeLegibility; -} - -/* Justify and hyphenate all paragraphs */ -p { - text-align: justify; - hyphens: auto; - -webkit-hyphens: auto; - -moz-hyphens: auto; - margin-top: 1rem; -} - -/* A elements that don't have a class get default styles */ -a:not([class]) { - text-decoration-skip-ink: auto; -} - -/* Make images easier to work with */ -img { - max-width: 100%; - display: block; -} - -/* Inherit fonts for inputs and buttons */ -input, -button, -textarea, -select { - font: inherit; -} - -/* Prevent textarea from overflowing */ -textarea { - width: 100%; -} - -/* Natural flow and rhythm in articles by default */ -article > * + * { - margin-top: 1em; -} - -/* Styles for inline code or code snippets */ -code, -pre, -kbd { - font-family: Courier, monospace; -} -pre { - padding: 1rem; - max-width: 100%; - overflow: auto; - border: 1px solid hsl(218, 15%, 49%); - border-radius: 4px; - background: hsl(218, 40%, 96%); - font-size: 85%; -} -pre code { - font-size: 95%; - position: relative; -} -kbd { - background: hsl(218, 5%, 100%); - border: 1px solid hsl(218, 5%, 70%); - border-radius: 2px; - padding: 2px 4px; - font-size: 75%; -} - -/* Make table 100% width, add borders between rows */ -table { - border-collapse: collapse; - border-spacing: 0; - width: 100%; - max-width: 100%; -} -th, -td { - text-align: left; - padding: 0.5rem; -} -td { - border-bottom: 1px solid hsl(0, 0%, 85%); -} -thead th { - border-bottom: 2px solid hsl(0, 0%, 70%); -} -tfoot th { - border-top: 2px solid hsl(0, 0%, 70%); -} - -/* Center align the title */ -h1:first-child { - text-align: center; -} - -/* Nested ordered list for ToC */ -nav ol { - counter-reset: item; - padding-left: 2rem; -} -nav li { - display: block; -} - -/* Center definitions (most useful for display equations) */ -dl dt { font-weight: 700; } -dl dd { - padding-left: 3rem; -} - -/* Theorem */ -.theorem { - counter-increment: theorem; - display: block; - margin: 12px 0; - font-style: italic; -} -.theorem::before { - content: 'Theorem ' counter(theorem) '. '; - font-weight: bold; - font-style: normal; -} - -/* Lemma */ -.lemma { - counter-increment: theorem; - display: block; - margin: 12px 0; - font-style: italic; -} -.lemma::before { - content: 'Lemma ' counter(theorem) '. '; - font-weight: bold; - font-style: normal; -} - -/* Proof */ -.proof { - display: block; - margin: 12px 0; - font-style: normal; - position: relative; -} -.proof::before { - content: 'Proof. ' attr(title); - font-style: italic; -} -.proof:after { - content: '◾️'; - position: absolute; - right: -12px; - bottom: -2px; -} - -/* Definition */ -.definition { - counter-increment: definition; - display: block; - margin: 12px 0; - font-style: normal; -} -.definition::before { - content: 'Definition ' counter(definition) '. '; - font-weight: bold; - font-style: normal; -} - -/* Center align author name, use small caps and add vertical spacing */ -.author { - margin: 0.85rem 0; - font-variant-caps: small-caps; - text-align: center; -} - -/* Make footnote text smaller and left align it (looks bad with long URLs) */ -.footref { display: inline-block; padding: 0 3px; } -.footnotes p { - text-align: left; - line-height: 1.5; - font-size: 85%; - margin-bottom: 0.4rem; -} -.footnotes { - border-top: 1px solid hsl(0, 0%, 39%); -} - -/* Center title and paragraph */ -.abstract, -.abstract p { - text-align: center; -} -.abstract { - margin: 2.25rem 0; -} - -/* Format the LaTeX symbol correctly (a higher up, e lower) */ -.latex span:nth-child(1) { - text-transform: uppercase; - font-size: 0.75em; - vertical-align: 0.25em; - margin-left: -0.36em; - margin-right: -0.15em; - line-height: 1ex; -} - -.latex span:nth-child(2) { - text-transform: uppercase; - vertical-align: -0.5ex; - margin-left: -0.1667em; - margin-right: -0.125em; - line-height: 1ex; -} - -/* Heading typography */ -h1 { - font-size: 2.5rem; - line-height: 3.25rem; - margin-bottom: 1.625rem; -} - -h2 { - font-size: 1.7rem; - line-height: 2rem; - margin-top: 3rem; -} - -h3 { - font-size: 1.4rem; - margin-top: 2.5rem; -} - -h4 { - font-size: 1.2rem; - margin-top: 2rem; -} - -h5 { - font-size: 1rem; - margin-top: 1.8rem; -} - -h6 { - font-size: 1rem; - font-style: italic; - font-weight: normal; - margin-top: 2.5rem; -} - -h3, -h4, -h5, -h6 { - line-height: 1.625rem; -} - -h1 + h2 { - margin-top: 1.625rem; -} - -h2 + h3, -h3 + h4, -h4 + h5 { - margin-top: 0.8rem; -} - -h5 + h6 { - margin-top: -0.8rem; -} - -h2, -h3, -h4, -h5, -h6 { - margin-bottom: 0.8rem; -} -/* COLORS */ - -/* colortheme switch */ -body>input { display: none; } -#labels > .content { margin: 0 auto; text-align: center; } -label { font-weight: 700; } -label:hover { cursor: pointer; } -label ~ pre { margin-top: 0; } -.org-src-container { margin: 1rem 0; } -#logo { text-align: center; } -body { margin:0; padding: 0; border: 0; max-width: none;} -#preamble, #postamble { text-align: center; } -#content,.content,#preamble,#postamble { - max-width: 60ch; - overflow: hidden; - margin: 0 auto; -} -figure img { width: 100%; } -.footdef > sup { vertical-align: top; font-size: medium; } -.footdef > sup > a { padding: 0.5em; } -.footpara { display: inline; } -footer { margin: 3em 0; - padding: 1em 0; - border-top: solid 1px; - border-bottom: solid 1px; - line-height: 1em; - font-size: 0.85em; - } -td { border-bottom: none; padding: .2rem; } -table { margin-top: 1rem; } -nav { text-align: center; padding: 2em 0; } -pre { line-height: 1em; } - -:root { - --b03: #2E3440; - --b02: #3B4252; - /* not used because light mode is has more contrast - --b01: #656b74; - */ - --b00: #727781; - --b0: #989ea8; - --b1: #b0bac7; - --b2: #ECEFF4; - --b3: #fff; - --y: #c18600; - --o: #d84100; - --r: #e62729; - --m: #ec0085; - --v: #6c71c4; - --b: #0095ff; - --c: #00b0a3; - --g: #879a00; - - /* default light */ - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--r); -} - -/* dark preferred */ -@media (prefers-color-scheme: dark) -{ - :root { - --bg: hsl(218,20%,16%); - --rbg: var(--b03); - --fg: var(--b0); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--g); - --y: #ae8c51; - --o: #a9654a; - --r: #af6255; - --m: #ae5e7d; - --v: #6774b2; - --b: #3f8cc3; - --c: #15a198; - --g: #939452; - } - img { filter: brightness(0.7) saturate(0.5); } - pre { - background: hsl(218,20%,18%); - border-color: hsl(218,15%,23%); - } -} - -/* light checked */ -input#l:checked ~ div { - --bg: var(--b3); - --rbg: var(--b2); - --fg0: var(--b0); - --fg: var(--b02); - --rfg: #000; - --hl: var(--o); - --y: #c18600; - --o: #d84100; - --r: #e62729; - --m: #ec0085; - --v: #6c71c4; - --b: #0095ff; - --c: #00b0a3; - --g: #879a00; -} -input#l:checked ~ div img { - filter: none; -} -input#l:checked ~ div pre { - border: 1px solid hsl(218, 15%, 49%); - background: hsl(218, 40%, 96%); -} - -/* dark checked */ -input#d:checked ~ div { - --bg: hsl(218,20%,16%); - --rbg: var(--b03); - --fg: var(--b0); - --fg0: var(--b00); - --rfg: var(--b2); - --hl: var(--g); - --y: #ae8c51; - --o: #a9654a; - --r: #af6255; - --m: #ae5e7d; - --v: #6774b2; - --b: #3f8cc3; - --c: #15a198; - --g: #939452; -} -input#d:checked ~ div img { - filter: brightness(0.7) saturate(0.5); -} -input#d:checked ~ div pre { - background: hsl(218,20%,18%); - border-color: hsl(218,15%,23%); -} - -/* ---- */ -::selection { - background: var(--m); - color: hsl(218,40%,96%); - text-decoration: hsl(218,40%,96%); -} - -body, body > div { - background: var(--bg); - color: var(--fg); -} -a,a:visited { color: var(--hl); } - -/* ---- SYNTAX HIGHLIGHTING ---- */ -#table-of-contents { text-align: left; } -.org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, -.org-css-selector, .org-builtin, -.IN_REVIEW { - color:var(--c); -} - -.org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, -.org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed, -.org-nix-attribute, .org-nxml-element-local-name { - color:var(--b); -} - -.org-rainbow-delimiters-depth-3, .HOLD, .WAITING { - color:var(--v); -} - -.org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, -.CANCELED { - color:var(--m); -} -.org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { - color:var(--r); -} -.org-rainbow-delimiters-depth-6, .org-haskell-constructor { - color:var(--o); -} -.org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, -.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { - color:var(--y); -} -.org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, -.org-doc, .org-keyword, .DONE { - color:var(--g); -} - -.org-highlight-numbers-number, .org-highlight-number-number, -.org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, -.org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, -.org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, -.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { - color:var(--fg0); -} From f3be77298635cb92396fca70b6c2026a4cd65fd5 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 22:13:12 +0200 Subject: [PATCH 10/27] mostly works --- Shakefile.hs | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 837aad1..954f437 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -81,6 +81,7 @@ sortByPostDate = sortBy (\b a -> compare (Down (postDate a)) (Down (postDate b))) +build :: FilePath -> FilePath build = () siteDir buildRules :: Rules () @@ -89,33 +90,43 @@ buildRules = do allRule getPost <- mkGetPost getPosts <- mkGetPosts getPost - let cssDeps = map (siteDir ) <$> getDirectoryFiles "" ["src/css/*.css"] + let cssDeps = map (siteDir ) <$> getDirectoryFiles "src" ["css/*.css"] + -- build "index.html" %> \out -> do + -- css <- cssDeps + -- need $ css <> ["src/index.org"] + -- bp <- getPost "src/index.org" + -- eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) + -- case eitherHtml of + -- Left _ -> fail "BAD" + -- Right htmlFile -> writeFile' out (T.unpack htmlFile) + build "//*.html" %> \out -> do + css <- cssDeps + let srcFile = "src" (dropDirectory1 (replaceExtension out "org")) + liftIO $ putText $ "need: " <> (T.pack srcFile) <> " <- " <> (T.pack out) + need $ css <> [srcFile] + bp <- getPost srcFile + eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) + case eitherHtml of + Left _ -> fail "BAD" + Right htmlFile -> writeFile' out (T.unpack htmlFile) build "articles.html" %> \out -> do css <- cssDeps posts <- getPosts () need $ css <> map postUrl (sortByPostDate posts) let titles = T.unpack $ T.intercalate "\n" $ map postTitle posts writeFile' out titles - build "index.html" %> \out -> do - css <- cssDeps - need $ css <> ["src/index.org"] - bp <- getPost "src/index.org" - eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) - case eitherHtml of - Left _ -> fail "BAD" - Right htmlFile -> writeFile' out (T.unpack htmlFile) - -- build "//*.html" %> \out -> do - -- css <- cssDeps - -- let orgfile = dropDirectory1 out - -- post <- getPost orgfile - build "src/css/*.css" %> \out -> copyFile' (dropDirectory1 out) out - + build "css/*.css" %> \out -> do + let src = "src" (dropDirectory1 out) + dst = out + liftIO $ putText $ T.pack $ "src:" <> src <> " => dst: " <> dst + copyFile' src dst allRule :: Rules () allRule = - phony "all" $ - need (map build [ "index.html" - , "articles.html"]) + phony "all" $ do + allOrgFiles <- getDirectoryFiles "src" ["//*.org"] + let allHtmlFiles = map (flip replaceExtension "html") allOrgFiles + need (map build (allHtmlFiles <> ["index.html", "articles.html"])) cleanRule :: Rules () cleanRule = @@ -123,6 +134,7 @@ cleanRule = putInfo "Cleaning files in _site and _optim" forM_ [siteDir,optimDir] $ flip removeFilesAfter ["//*"] +mkGetPost :: Rules (FilePath -> Action BlogPost) mkGetPost = newCache $ \path -> do fileContent <- readFile' path eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (T.pack fileContent) @@ -130,5 +142,6 @@ mkGetPost = newCache $ \path -> do Left _ -> fail "BAD" Right pandoc -> getBlogpostFromMetas path pandoc +mkGetPosts :: (FilePath -> Action b) -> Rules (() -> Action [b]) mkGetPosts getPost = newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] From e5d9673fc4110dbbb36abe3889f8efcc805bf97a Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Mon, 22 Jun 2020 23:01:47 +0200 Subject: [PATCH 11/27] right track --- Shakefile.hs | 76 ++++++++++++++++++++++++----------------- shell.nix | 1 + templates/main.mustache | 9 +++++ 3 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 templates/main.mustache diff --git a/Shakefile.hs b/Shakefile.hs index 954f437..6deb93d 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -9,27 +9,29 @@ import Development.Shake.FilePath import Development.Shake.Util import Control.Monad.Fail -import Data.Default ( Default(def) ) -import qualified Data.Set as Set -import qualified Data.Text as T -import Text.Pandoc.Class ( PandocPure - , PandocMonad - ) -import qualified Text.Pandoc.Class as Pandoc -import Text.Pandoc.Definition ( Pandoc(..) - , Block(..) - , Inline - , nullMeta - , docTitle - , docDate - , docAuthors - ) -import Text.Pandoc.Extensions ( getDefaultExtensions ) -import Text.Pandoc.Options ( ReaderOptions(..) +import Data.Aeson +import Text.Megaparsec +import Data.Default ( Default(def) ) +import qualified Data.Set as Set +import qualified Data.Text as T +import Text.Mustache +import Text.Pandoc.Class ( PandocPure, PandocMonad) +import qualified Text.Pandoc.Class as Pandoc +import Text.Pandoc.Definition ( Pandoc(..) + , Block(..) + , Inline + , nullMeta + , docTitle + , docDate + , docAuthors + ) +import Text.Pandoc.Extensions ( getDefaultExtensions ) +import Text.Pandoc.Options ( ReaderOptions(..) , TrackChanges(RejectChanges) ) -import qualified Text.Pandoc.Readers as Readers -import qualified Text.Pandoc.Writers as Writers +import qualified Text.Pandoc.Readers as Readers +import qualified Text.Pandoc.Templates as PandocTemplates +import qualified Text.Pandoc.Writers as Writers main :: IO () main = shakeArgs shOpts buildRules @@ -90,35 +92,37 @@ buildRules = do allRule getPost <- mkGetPost getPosts <- mkGetPosts getPost + getTemplate <- mkGetTemplate let cssDeps = map (siteDir ) <$> getDirectoryFiles "src" ["css/*.css"] - -- build "index.html" %> \out -> do - -- css <- cssDeps - -- need $ css <> ["src/index.org"] - -- bp <- getPost "src/index.org" - -- eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) - -- case eitherHtml of - -- Left _ -> fail "BAD" - -- Right htmlFile -> writeFile' out (T.unpack htmlFile) + -- templateDeps = getDirectoryFiles "templates" ["*.mustache"] build "//*.html" %> \out -> do css <- cssDeps + -- templates <- templateDeps + template <- getTemplate ("templates" "main.mustache") let srcFile = "src" (dropDirectory1 (replaceExtension out "org")) - liftIO $ putText $ "need: " <> (T.pack srcFile) <> " <- " <> (T.pack out) + liftIO $ putText $ "need: " <> (toS srcFile) <> " <- " <> (toS out) need $ css <> [srcFile] bp <- getPost srcFile eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) case eitherHtml of Left _ -> fail "BAD" - Right htmlFile -> writeFile' out (T.unpack htmlFile) + Right innerHtml -> + let htmlContent = renderMustache template $ object [ "title" .= postTitle bp + , "authors" .= postAuthors bp + , "date" .= postDate bp + , "body" .= innerHtml + ] + in writeFile' out (toS htmlContent) build "articles.html" %> \out -> do css <- cssDeps posts <- getPosts () need $ css <> map postUrl (sortByPostDate posts) - let titles = T.unpack $ T.intercalate "\n" $ map postTitle posts + let titles = toS $ T.intercalate "\n" $ map postTitle posts writeFile' out titles build "css/*.css" %> \out -> do let src = "src" (dropDirectory1 out) dst = out - liftIO $ putText $ T.pack $ "src:" <> src <> " => dst: " <> dst + liftIO $ putText $ toS $ "src:" <> src <> " => dst: " <> dst copyFile' src dst allRule :: Rules () @@ -134,10 +138,18 @@ cleanRule = putInfo "Cleaning files in _site and _optim" forM_ [siteDir,optimDir] $ flip removeFilesAfter ["//*"] +mkGetTemplate :: Rules (FilePath -> Action Template) +mkGetTemplate = newCache $ \path -> do + fileContent <- readFile' path + let res = compileMustacheText "page" (toS fileContent) + case res of + Left _ -> fail "BAD" + Right template -> return template + mkGetPost :: Rules (FilePath -> Action BlogPost) mkGetPost = newCache $ \path -> do fileContent <- readFile' path - eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (T.pack fileContent) + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (toS fileContent) case eitherResult of Left _ -> fail "BAD" Right pandoc -> getBlogpostFromMetas path pandoc diff --git a/shell.nix b/shell.nix index dc3a357..7fa6367 100644 --- a/shell.nix +++ b/shell.nix @@ -7,6 +7,7 @@ let data-default protolude pkgs1909.haskellPackages.sws + stache ]; ghc = pkgs.haskellPackages.ghcWithPackages haskellDeps; in diff --git a/templates/main.mustache b/templates/main.mustache new file mode 100644 index 0000000..44bafe4 --- /dev/null +++ b/templates/main.mustache @@ -0,0 +1,9 @@ + + + {{title}} + + +

{{title}}

+ {{{ body }}} + + From c1a00e1c094221c170131de647e3068e8099f7a6 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 00:20:38 +0200 Subject: [PATCH 12/27] closer --- templates/main.mustache | 70 +++++++++++++++++++++++++++++++++----- templates/post.html | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 templates/post.html diff --git a/templates/main.mustache b/templates/main.mustache index 44bafe4..5b38e62 100644 --- a/templates/main.mustache +++ b/templates/main.mustache @@ -1,9 +1,63 @@ - - - {{title}} - - -

{{title}}

- {{{ body }}} - + + + + + +{{title}} + + + + + + + + + +
+
+ | +
+
+
+
+ +

{{title}}

+
+
+

+

+

+ +{{{ body }}} + +
+
+
+
+
+ diff --git a/templates/post.html b/templates/post.html new file mode 100644 index 0000000..7f91fc7 --- /dev/null +++ b/templates/post.html @@ -0,0 +1,74 @@ + + + + + +{{title}} + + + + + + + + +
+
+ +| + +
+
+
+
+ +
+

{{title}}

+
{{authors}}
+
on + Yann Esposito's blog - + source - +
+
{{description}}
+
+
+ {{{body}}} +
+
+
+
+ +
+
+ + + + From d201cf8b1bfe5b03a6eb3f12e4514c398869845c Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 08:44:02 +0200 Subject: [PATCH 13/27] wip --- Shakefile.hs | 11 ++++++++++- templates/main.mustache | 14 +------------- templates/post.html | 4 +--- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 6deb93d..948fb3f 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -22,6 +22,7 @@ import Text.Pandoc.Definition ( Pandoc(..) , Inline , nullMeta , docTitle + , lookupMeta , docDate , docAuthors ) @@ -59,6 +60,7 @@ data BlogPost = , postAuthors :: [T.Text] , postUrl :: FilePath , postBody :: Pandoc + -- , postToc :: Boolean } inlineToText :: PandocMonad m => [Inline] -> m T.Text @@ -72,7 +74,6 @@ getBlogpostFromMetas path pandoc@(Pandoc meta _) = do title <- inlineToText $ docTitle meta date <- inlineToText $ docDate meta authors <- mapM inlineToText $ docAuthors meta - -- let url = dropExtension path return $ BlogPost title date authors path pandoc case eitherBlogpost of Left _ -> fail "BAD" @@ -146,9 +147,17 @@ mkGetTemplate = newCache $ \path -> do Left _ -> fail "BAD" Right template -> return template +parseOptions :: Text -> [Text] -> Maybe Text +parseOptions fc = + fc & T.lines + & map T.toLower + & filter (T.isPrefixOf (T.pack "#options: ")) + & head + mkGetPost :: Rules (FilePath -> Action BlogPost) mkGetPost = newCache $ \path -> do fileContent <- readFile' path + let options = parseOptions (toS fileContent) eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (toS fileContent) case eitherResult of Left _ -> fail "BAD" diff --git a/templates/main.mustache b/templates/main.mustache index 5b38e62..a94c624 100644 --- a/templates/main.mustache +++ b/templates/main.mustache @@ -33,22 +33,10 @@

{{title}}

-

-

-

{{{ body }}} +
Any comment? Click on my email below and I'll add it. diff --git a/templates/post.html b/templates/post.html index 7f91fc7..ecc7995 100644 --- a/templates/post.html +++ b/templates/post.html @@ -15,9 +15,7 @@
- -| - + |
From 2bdc881cc948b020385e4b72899c8a1928ff31c8 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 09:15:03 +0200 Subject: [PATCH 14/27] closer --- Shakefile.hs | 33 ++++++++------- src/css/y.css | 10 ++--- src/posts/0010-Haskell-Now/index.org | 62 ++++++++++++++-------------- 3 files changed, 54 insertions(+), 51 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 948fb3f..aaef6cf 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -28,8 +28,9 @@ import Text.Pandoc.Definition ( Pandoc(..) ) import Text.Pandoc.Extensions ( getDefaultExtensions ) import Text.Pandoc.Options ( ReaderOptions(..) - , TrackChanges(RejectChanges) - ) + , WriterOptions(..) + , TrackChanges(RejectChanges) + ) import qualified Text.Pandoc.Readers as Readers import qualified Text.Pandoc.Templates as PandocTemplates import qualified Text.Pandoc.Writers as Writers @@ -59,8 +60,8 @@ data BlogPost = , postDate :: T.Text , postAuthors :: [T.Text] , postUrl :: FilePath + , postToc :: Bool , postBody :: Pandoc - -- , postToc :: Boolean } inlineToText :: PandocMonad m => [Inline] -> m T.Text @@ -68,13 +69,13 @@ inlineToText inline = Writers.writeAsciiDoc def (Pandoc nullMeta [Plain inline]) getBlogpostFromMetas - :: (MonadIO m, MonadFail m) => [Char] -> Pandoc -> m BlogPost -getBlogpostFromMetas path pandoc@(Pandoc meta _) = do + :: (MonadIO m, MonadFail m) => [Char] -> Bool -> Pandoc -> m BlogPost +getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do eitherBlogpost <- liftIO $ Pandoc.runIO $ do title <- inlineToText $ docTitle meta date <- inlineToText $ docDate meta authors <- mapM inlineToText $ docAuthors meta - return $ BlogPost title date authors path pandoc + return $ BlogPost title date authors path toc pandoc case eitherBlogpost of Left _ -> fail "BAD" Right bp -> return bp @@ -104,7 +105,7 @@ buildRules = do liftIO $ putText $ "need: " <> (toS srcFile) <> " <- " <> (toS out) need $ css <> [srcFile] bp <- getPost srcFile - eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String def (postBody bp) + eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String (def { writerTableOfContents = (postToc bp) }) (postBody bp) case eitherHtml of Left _ -> fail "BAD" Right innerHtml -> @@ -147,21 +148,23 @@ mkGetTemplate = newCache $ \path -> do Left _ -> fail "BAD" Right template -> return template -parseOptions :: Text -> [Text] -> Maybe Text -parseOptions fc = - fc & T.lines - & map T.toLower - & filter (T.isPrefixOf (T.pack "#options: ")) - & head +tocRequested :: Text -> Bool +tocRequested fc = + let toc = fc & T.lines + & map T.toLower + & filter (T.isPrefixOf (T.pack "#+options: ")) + & head + & fmap (filter (T.isPrefixOf (T.pack "toc:")) . T.words) + in toc == Just ["toc:t"] mkGetPost :: Rules (FilePath -> Action BlogPost) mkGetPost = newCache $ \path -> do fileContent <- readFile' path - let options = parseOptions (toS fileContent) + let toc = tocRequested (toS fileContent) eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (toS fileContent) case eitherResult of Left _ -> fail "BAD" - Right pandoc -> getBlogpostFromMetas path pandoc + Right pandoc -> getBlogpostFromMetas path toc pandoc mkGetPosts :: (FilePath -> Action b) -> Rules (() -> Action [b]) mkGetPosts getPost = diff --git a/src/css/y.css b/src/css/y.css index edcd680..4336774 100644 --- a/src/css/y.css +++ b/src/css/y.css @@ -564,7 +564,7 @@ a,a:visited { color: var(--hl); } .org-rainbow-delimiters-depth-2, .org-nix-builtin, .org-variable-name, .org-haskell-definition, .org-haskell-operator, .org-function-name, .org-diff-changed, -.org-nix-attribute, .org-nxml-element-local-name { +.org-nix-attribute, .org-nxml-element-local-name, .op, .fu, .ot { color:var(--b); } @@ -579,15 +579,15 @@ a,a:visited { color: var(--hl); } .org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { color:var(--r); } -.org-rainbow-delimiters-depth-6, .org-haskell-constructor { +.org-rainbow-delimiters-depth-6, .org-haskell-constructor, .dt { color:var(--o); } .org-rainbow-delimiters-depth-7, .org-type, .org-constant, .org-diff-header, -.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS { +.org-haskell-keyword, .org-haskell-type, .IN_PROGRESS, .kw { color:var(--y); } .org-rainbow-delimiters-depth-8, .org-sh-heredoc, .org-diff-added, .org-string, -.org-doc, .org-keyword, .DONE { +.org-doc, .org-keyword, .DONE, .st { color:var(--g); } @@ -595,6 +595,6 @@ a,a:visited { color: var(--hl); } .org-diff-none, .org-preprocessor, .org-comment-delimiter, .org-comment, .org-outshine-level-1, .org-outshine-level-2, .org-outshine-level-3, .org-outshine-level-4, .org-outshine-level-5, .org-outshine-level-6, -.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9 { +.org-outshine-level-7, .org-outshine-level-8, .org-outshine-level-9, .co { color:var(--fg0); } diff --git a/src/posts/0010-Haskell-Now/index.org b/src/posts/0010-Haskell-Now/index.org index 910d35a..753128f 100644 --- a/src/posts/0010-Haskell-Now/index.org +++ b/src/posts/0010-Haskell-Now/index.org @@ -178,32 +178,32 @@ Otherwise, you can follow my advice to use nix: 4. Put the following =shell.nix= file inside it #+begin_src nix :tangle shell.nix -{ nixpkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {} }: -let - inherit (nixpkgs) pkgs; - inherit (pkgs) haskellPackages; - - haskellDeps = ps: with ps; [ - base - protolude - containers - ]; - - ghc = haskellPackages.ghcWithPackages haskellDeps; - - nixPackages = [ - ghc - pkgs.gdb - haskellPackages.cabal-install - ]; -in -pkgs.stdenv.mkDerivation { - name = "env"; - buildInputs = nixPackages; - shellHook = '' - export PS1="\n\[[hs:\033[1;32m\]\W\[\033[0m\]]> " - ''; -} + { nixpkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {} }: + let + inherit (nixpkgs) pkgs; + inherit (pkgs) haskellPackages; + + haskellDeps = ps: with ps; [ + base + protolude + containers + ]; + + ghc = haskellPackages.ghcWithPackages haskellDeps; + + nixPackages = [ + ghc + pkgs.gdb + haskellPackages.cabal-install + ]; + in + pkgs.stdenv.mkDerivation { + name = "env"; + buildInputs = nixPackages; + shellHook = '' + export PS1="\n\[[hs:\033[1;32m\]\W\[\033[0m\]]> " + ''; + } #+end_src 5. In the =hsenv= directory, in a terminal, run =nix-shell --pure=. @@ -219,11 +219,11 @@ pkgs.stdenv.mkDerivation { something like this: #+begin_src -~/hsenv> nix-shell -[nix-shell:~/hsenv]$ ghci -GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help -Prelude> import Protolude -Prelude Protolude> + ~/hsenv> nix-shell + [nix-shell:~/hsenv]$ ghci + GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help + Prelude> import Protolude + Prelude Protolude> #+end_src Congratulations you should be ready to start now. From d47ad320741943d98b51a32d4d28e66ca74d720d Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 16:14:53 +0200 Subject: [PATCH 15/27] updated hlint --- .hlint.yaml | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .hlint.yaml diff --git a/.hlint.yaml b/.hlint.yaml new file mode 100644 index 0000000..d6a5a09 --- /dev/null +++ b/.hlint.yaml @@ -0,0 +1,63 @@ +# HLint configuration file +# https://github.com/ndmitchell/hlint +########################## + +# This file contains a template configuration file, which is typically +# placed as .hlint.yaml in the root of your project + + +# Specify additional command line arguments +# +# - arguments: [--color, --cpp-simple, -XQuasiQuotes] + + +# Control which extensions/flags/modules/functions can be used +# +# - extensions: +# - default: false # all extension are banned by default +# - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used +# - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module +# +# - flags: +# - {name: -w, within: []} # -w is allowed nowhere +# +# - modules: +# - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set' +# - {name: Control.Arrow, within: []} # Certain modules are banned entirely +# +# - functions: +# - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules + + +# Add custom hints for this project +# +# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar" +# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x} + + +# Turn on hints that are off by default +# +# Ban "module X(module X) where", to require a real export list +# - warn: {name: Use explicit module export list} +# +# Replace a $ b $ c with a . b $ c +# - group: {name: dollar, enabled: true} +# +# Generalise map to fmap, ++ to <> +# - group: {name: generalise, enabled: true} + + +# Ignore some builtin hints +# - ignore: {name: Use let} +# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules + + +# Define some custom infix operators +# - fixity: infixr 3 ~^#^~ + + +# To generate a suitable file for HLint do: +# $ hlint --default > .hlint.yaml + +# Protolude does not use String and prefer Text so String is undefined and we should use [Char] +- ignore: {name: Use String} From 3a134357109e0522edd89d882cce4105f863fcee Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 16:55:38 +0200 Subject: [PATCH 16/27] updated with niv --- nix/sources.json | 38 ++++++++++++++ nix/sources.nix | 134 +++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 3 +- 3 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 nix/sources.json create mode 100644 nix/sources.nix diff --git a/nix/sources.json b/nix/sources.json new file mode 100644 index 0000000..58f2808 --- /dev/null +++ b/nix/sources.json @@ -0,0 +1,38 @@ +{ + "niv": { + "branch": "master", + "description": "Easy dependency management for Nix projects", + "homepage": "https://github.com/nmattia/niv", + "owner": "nmattia", + "repo": "niv", + "rev": "f73bf8d584148677b01859677a63191c31911eae", + "sha256": "0jlmrx633jvqrqlyhlzpvdrnim128gc81q5psz2lpp2af8p8q9qs", + "type": "tarball", + "url": "https://github.com/nmattia/niv/archive/f73bf8d584148677b01859677a63191c31911eae.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "nixpkgs": { + "branch": "nixpkgs-unstable", + "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", + "homepage": "https://github.com/NixOS/nixpkgs", + "owner": "NixOS", + "repo": "nixpkgs-channels", + "rev": "a84cbb60f0296210be03c08d243670dd18a3f6eb", + "sha256": "04j07c98iy66hpzha7brz867dcl9lkflck43xvz09dfmlvqyzmiz", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs-channels/archive/a84cbb60f0296210be03c08d243670dd18a3f6eb.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "shake": { + "branch": "master", + "description": "Shake build system", + "homepage": "http://shakebuild.com", + "owner": "ndmitchell", + "repo": "shake", + "rev": "4536d9ce5cef0e56395fd61ccef9816c9b420fd1", + "sha256": "1s7hjhcc09l026jaca3ndbb103s9d7qlx4vqzx2s6j4rr751nd70", + "type": "tarball", + "url": "https://github.com/ndmitchell/shake/archive/4536d9ce5cef0e56395fd61ccef9816c9b420fd1.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/nix/sources.nix b/nix/sources.nix new file mode 100644 index 0000000..8a725cb --- /dev/null +++ b/nix/sources.nix @@ -0,0 +1,134 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_ fetches specs of type . + # + + fetch_file = pkgs: spec: + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; } + else + pkgs.fetchurl { inherit (spec) url sha256; }; + + fetch_tarball = pkgs: spec: + if spec.builtin or true then + builtins_fetchTarball { inherit (spec) url sha256; } + else + pkgs.fetchzip { inherit (spec) url sha256; }; + + fetch_git = spec: + builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; + + fetch_builtin-tarball = spec: + builtins.trace + '' + WARNING: + The niv type "builtin-tarball" will soon be deprecated. You should + instead use `builtin = true`. + + $ niv modify -a type=tarball -a builtin=true + '' + builtins_fetchTarball { inherit (spec) url sha256; }; + + fetch_builtin-url = spec: + builtins.trace + '' + WARNING: + The niv type "builtin-url" will soon be deprecated. You should + instead use `builtin = true`. + + $ niv modify -a type=file -a builtin=true + '' + (builtins_fetchurl { inherit (spec) url sha256; }); + + # + # Various helpers + # + + # The set of packages used when specs are fetched using non-builtins. + mkPkgs = sources: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import {} + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + if ! builtins.hasAttr "type" spec then + abort "ERROR: niv spec ${name} does not have a 'type' attribute" + else if spec.type == "file" then fetch_file pkgs spec + else if spec.type == "tarball" then fetch_tarball pkgs spec + else if spec.type == "git" then fetch_git spec + else if spec.type == "builtin-tarball" then fetch_builtin-tarball spec + else if spec.type == "builtin-url" then fetch_builtin-url spec + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # Ports of functions for older nix versions + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball { inherit url; } + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl { inherit url; } + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs ( + name: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = fetch config.pkgs name spec; } + ) config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? ./sources.json + , sources ? builtins.fromJSON (builtins.readFile sourcesFile) + , pkgs ? mkPkgs sources + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/shell.nix b/shell.nix index 7fa6367..d7827e6 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,6 @@ -{ pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz) {} }: let + sources = import ./nix/sources.nix; + pkgs = import sources.nixpkgs {}; pkgs1909 = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}; haskellDeps = ps : with ps; [ shake From aef6f8127446b77c41c24c9ce63c877351c4c39c Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 19:28:41 +0200 Subject: [PATCH 17/27] Fixes --- Shakefile.hs | 154 ++++++++++++++++++--------- src/css/y.css | 5 +- src/posts/0002-troll-2/index.org | 6 +- src/posts/0010-Haskell-Now/index.org | 52 ++++----- 4 files changed, 137 insertions(+), 80 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index aaef6cf..35e7efe 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -6,33 +6,28 @@ import Protolude import Development.Shake import Development.Shake.Command import Development.Shake.FilePath -import Development.Shake.Util import Control.Monad.Fail import Data.Aeson -import Text.Megaparsec +-- import qualified Text.Megaparsec as Megaparsec import Data.Default ( Default(def) ) -import qualified Data.Set as Set import qualified Data.Text as T import Text.Mustache -import Text.Pandoc.Class ( PandocPure, PandocMonad) +import Text.Pandoc.Class (PandocMonad) import qualified Text.Pandoc.Class as Pandoc import Text.Pandoc.Definition ( Pandoc(..) , Block(..) , Inline , nullMeta , docTitle - , lookupMeta , docDate , docAuthors ) -import Text.Pandoc.Extensions ( getDefaultExtensions ) import Text.Pandoc.Options ( ReaderOptions(..) , WriterOptions(..) - , TrackChanges(RejectChanges) + , ObfuscationMethod(..) ) import qualified Text.Pandoc.Readers as Readers -import qualified Text.Pandoc.Templates as PandocTemplates import qualified Text.Pandoc.Writers as Writers main :: IO () @@ -47,6 +42,9 @@ main = shakeArgs shOpts buildRules -- Configuration -- Should probably go in a Reader Monad +srcDir :: FilePath +srcDir = "src" + siteDir :: FilePath siteDir = "_site" @@ -82,57 +80,115 @@ getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do sortByPostDate :: [BlogPost] -> [BlogPost] sortByPostDate = - sortBy (\b a -> compare (Down (postDate a)) (Down (postDate b))) + sortBy (\a b-> compare (Down (postDate a)) (Down (postDate b))) build :: FilePath -> FilePath build = () siteDir +genAllDeps :: [FilePattern] -> Action [FilePath] +genAllDeps patterns = do + allMatchedFiles <- getDirectoryFiles srcDir patterns + allMatchedFiles & + filter ((/= "html") . takeExtension) & + filter (null . takeExtension) & + map (siteDir ) & + return + buildRules :: Rules () buildRules = do - cleanRule - allRule - getPost <- mkGetPost - getPosts <- mkGetPosts getPost - getTemplate <- mkGetTemplate - let cssDeps = map (siteDir ) <$> getDirectoryFiles "src" ["css/*.css"] - -- templateDeps = getDirectoryFiles "templates" ["*.mustache"] - build "//*.html" %> \out -> do - css <- cssDeps - -- templates <- templateDeps - template <- getTemplate ("templates" "main.mustache") - let srcFile = "src" (dropDirectory1 (replaceExtension out "org")) - liftIO $ putText $ "need: " <> (toS srcFile) <> " <- " <> (toS out) - need $ css <> [srcFile] - bp <- getPost srcFile - eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String (def { writerTableOfContents = (postToc bp) }) (postBody bp) - case eitherHtml of - Left _ -> fail "BAD" - Right innerHtml -> - let htmlContent = renderMustache template $ object [ "title" .= postTitle bp - , "authors" .= postAuthors bp - , "date" .= postDate bp - , "body" .= innerHtml - ] - in writeFile' out (toS htmlContent) - build "articles.html" %> \out -> do - css <- cssDeps - posts <- getPosts () - need $ css <> map postUrl (sortByPostDate posts) - let titles = toS $ T.intercalate "\n" $ map postTitle posts - writeFile' out titles - build "css/*.css" %> \out -> do - let src = "src" (dropDirectory1 out) - dst = out - liftIO $ putText $ toS $ "src:" <> src <> " => dst: " <> dst - copyFile' src dst + cleanRule + -- build "//*" %> copy + allRule + getPost <- mkGetPost + getPosts <- mkGetPosts getPost + getTemplate <- mkGetTemplate + alternatives $ do + -- build "articles.html" %> \out -> do + -- css <- genAllDeps ["//*.css"] + -- posts <- getPosts () + -- need $ css <> map postUrl (sortByPostDate posts) + -- let titles = toS $ T.intercalate "\n" $ map postTitle posts + -- writeFile' out titles + build "//*.html" %> genHtmlAction getPost getTemplate + -- build "//*.org" %> copy + -- build "//*.jpg" %> copy + +copy :: FilePath -> Action () +copy out = do + let src = srcDir (dropDirectory1 out) + copyFileChanged src out + +genHtml :: (MonadIO m, MonadFail m) => BlogPost -> m Text +genHtml bp = do + eitherHtml <- liftIO $ + Pandoc.runIO $ + Writers.writeHtml5String + (def { writerTableOfContents = (postToc bp) + , writerEmailObfuscation = ReferenceObfuscation + }) + (postBody bp) + case eitherHtml of + Left _ -> fail "BAD" + Right innerHtml -> return innerHtml + +genHtmlAction + :: (FilePath -> Action BlogPost) + -> (FilePath -> Action Template) -> [Char] -> Action () +genHtmlAction getPost getTemplate out = do + template <- getTemplate ("templates" "main.mustache") + let srcFile = srcDir (dropDirectory1 (out -<.> "org")) + liftIO $ putText $ "need: " <> (toS srcFile) <> " -> " <> (toS out) + need [srcFile] + bp <- getPost srcFile + innerHtml <- genHtml bp + let htmlContent = + renderMustache template $ object [ "title" .= postTitle bp + , "authors" .= postAuthors bp + , "date" .= postDate bp + , "body" .= innerHtml + ] + writeFile' out (toS htmlContent) + +allHtmlAction :: Action () +allHtmlAction = do + allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] + let allHtmlFiles = map (-<.> "html") allOrgFiles + need (map build (allHtmlFiles + -- <> ["articles.html"] + )) + +compressImage :: CmdResult b => FilePath -> Action b +compressImage img = do + let src = srcDir img + dst = siteDir img + need [src] + let dir = takeDirectory dst + dirExists <- doesDirectoryExist dir + when (not dirExists) $ + command [] "mkdir" ["-p", dir] + command [] "convert" [src + , "-strip" + , "-resize","320x320>" + , "-interlace","Plane" + , "-quality","85" + , "-define","filter:blur=0.75" + , "-filter","Gaussian" + , "-ordered-dither","o4x4,4" + , dst ] allRule :: Rules () allRule = phony "all" $ do - allOrgFiles <- getDirectoryFiles "src" ["//*.org"] - let allHtmlFiles = map (flip replaceExtension "html") allOrgFiles - need (map build (allHtmlFiles <> ["index.html", "articles.html"])) + allAssets <- filter (/= ".DS_Store") <$> getDirectoryFiles srcDir ["//*.*"] + forM_ allAssets $ \asset -> + case (takeExtension asset) of + ".jpg" -> compressImage asset + ".jpeg" -> compressImage asset + ".gif" -> compressImage asset + ".png" -> compressImage asset + _ -> copyFileChanged (srcDir asset) (siteDir asset) + allHtmlAction cleanRule :: Rules () cleanRule = @@ -161,7 +217,7 @@ mkGetPost :: Rules (FilePath -> Action BlogPost) mkGetPost = newCache $ \path -> do fileContent <- readFile' path let toc = tocRequested (toS fileContent) - eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg def (toS fileContent) + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg (def { readerStandalone = True }) (toS fileContent) case eitherResult of Left _ -> fail "BAD" Right pandoc -> getBlogpostFromMetas path toc pandoc diff --git a/src/css/y.css b/src/css/y.css index 4336774..f349c5a 100644 --- a/src/css/y.css +++ b/src/css/y.css @@ -556,9 +556,10 @@ a,a:visited { color: var(--hl); } /* ---- SYNTAX HIGHLIGHTING ---- */ #table-of-contents { text-align: left; } + .org-rainbow-delimiters-depth-1, .org-rainbow-delimiters-depth-9, .org-css-selector, .org-builtin, -.IN_REVIEW { +.IN_REVIEW, .ex { color:var(--c); } @@ -573,7 +574,7 @@ a,a:visited { color: var(--hl); } } .org-rainbow-delimiters-depth-4, .org-diff-hunk-header, .org-sh-quoted-exec, -.CANCELED { +.CANCELED, .bu { color:var(--m); } .org-rainbow-delimiters-depth-5, .org-diff-removed, .TODO { diff --git a/src/posts/0002-troll-2/index.org b/src/posts/0002-troll-2/index.org index 2671b78..ed07fe5 100644 --- a/src/posts/0002-troll-2/index.org +++ b/src/posts/0002-troll-2/index.org @@ -44,9 +44,9 @@ goblins. Those costume looks very bad and cheap. So much you can only find them not terrorizing but funny and ridiculous. +#+ATTR_HTML: A goblin #+CAPTION: One goblin during the introduction scene of Troll 2 #+NAME: fig:troll-2-intro -#+ATTR_HTML: A goblin [[./Troll-2-intro.jpg]] Soon after that, you realize the acting of all actors is extremely bad. @@ -55,9 +55,9 @@ To give you an idea, the only equal bad acting I ever witnessed was while looking at amateurs first Youtube movies trying to follow a scenario. Apparently most actors were amateurs, it was their first and last movie. +#+ATTR_HTML: A bad acting demonstration #+CAPTION: One particularly terrible acting scene #+NAME: fig:bad-acting -#+ATTR_HTML: A bad acting demonstration [[file:bad-acting.png]] The dialog are, really something... @@ -83,9 +83,9 @@ They win against the monsters with, what I believe was a failed attempt at humor. It misses the point so bad, that the irony still make it funny. +#+ATTR_HTML: Eliott prevents his family to eat the food by urinating on the table #+CAPTION: Our hero save the day by urinating on the table. His family is frozen for 30s said grandpa, they were for 70s. #+NAME: fig:prevent-eating -#+ATTR_HTML: Eliott prevents his family to eat the food by urinating on the table [[./prevent-eating-scene.jpg]] Of course, the very last scene is a classical so terrible cliché. diff --git a/src/posts/0010-Haskell-Now/index.org b/src/posts/0010-Haskell-Now/index.org index 753128f..86da14f 100644 --- a/src/posts/0010-Haskell-Now/index.org +++ b/src/posts/0010-Haskell-Now/index.org @@ -1492,7 +1492,7 @@ The only way to work around this problem is to use some meta-programming trick, for example using the pre-processor. In C++ there is a better way, C++ templates: -#+BEGIN_SRC c++ +#+BEGIN_SRC cpp #include #include using namespace std; @@ -3880,9 +3880,7 @@ I will not argue much, but mainly, semantic versionning and Haskell versionning are just a "right to break things to your users". I don't want to talk a lot more about this, but, it would be nice if more -people would watch this talk[fn:9] related to versionning. - -[fn:9]: [[https://www.youtube.com/watch?v=oyLBGkS5ICk][Spec-ulation Keynote - Rich Hickey]] +people would watch this talk[fn:8] related to versionning. If you want to know more about Haskell versionning convention: https://pvp.haskell.org @@ -4082,30 +4080,32 @@ Thank you man. As of today, the definition of =IO= is no more visible into =base=. We have the following explanation in [[http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.IO.html][=GHC.IO.hs=]]: #+begin_quote -#+begin_src -The IO Monad is just an instance of the ST monad, where the state is -the real world. We use the exception mechanism (in GHC.Exception) to -implement IO exceptions. - -NOTE: The IO representation is deeply wired in to various parts of the -system. The following list may or may not be exhaustive: - -Compiler - types of various primitives in PrimOp.hs - -RTS - forceIO (StgStartup.cmm) - - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast - (Exception.cmm) - - raiseAsync (RaiseAsync.c) - -Prelude - GHC.IO.hs, and several other places including - GHC.Exception.hs. - -Libraries - parts of hslibs/lang. - ---SDM -#+end_src + #+begin_src + The IO Monad is just an instance of the ST monad, where the state is + the real world. We use the exception mechanism (in GHC.Exception) to + implement IO exceptions. + + NOTE: The IO representation is deeply wired in to various parts of the + system. The following list may or may not be exhaustive: + + Compiler - types of various primitives in PrimOp.hs + + RTS - forceIO (StgStartup.cmm) + - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast + (Exception.cmm) + - raiseAsync (RaiseAsync.c) + + Prelude - GHC.IO.hs, and several other places including + GHC.Exception.hs. + + Libraries - parts of hslibs/lang. + + --SDM + #+end_src #+end_quote [fn:7] Well, you'll certainly need to practice a bit to get used to them and to understand when you can use them and create your own. But you already made a big step in this direction. + +[fn:8] [[https://www.youtube.com/watch?v=oyLBGkS5ICk][Spec-ulation Keynote - Rich Hickey]] From 0e44c7d427f167c0307bcfd126c72da797806f8f Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Tue, 23 Jun 2020 23:58:09 +0200 Subject: [PATCH 18/27] right track --- Shakefile.hs | 76 ++++++++++++++++++++------ templates/{post.html => post.mustache} | 0 2 files changed, 58 insertions(+), 18 deletions(-) rename templates/{post.html => post.mustache} (100%) diff --git a/Shakefile.hs b/Shakefile.hs index 35e7efe..ffb02b9 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -103,14 +103,26 @@ buildRules = do getPost <- mkGetPost getPosts <- mkGetPosts getPost getTemplate <- mkGetTemplate - alternatives $ do -- build "articles.html" %> \out -> do -- css <- genAllDeps ["//*.css"] -- posts <- getPosts () -- need $ css <> map postUrl (sortByPostDate posts) -- let titles = toS $ T.intercalate "\n" $ map postTitle posts -- writeFile' out titles - build "//*.html" %> genHtmlAction getPost getTemplate + build "//*" %> \out -> do + let asset = dropDirectory1 out + case (takeExtension asset) of + ".html" -> genHtmlAction getPost getTemplate out + ".txt" -> do + txtExists <- doesFileExist (srcDir asset) + if txtExists + then copyFileChanged (srcDir asset) out + else genAsciiAction getPost out + ".jpg" -> compressImage asset + ".jpeg" -> compressImage asset + ".gif" -> compressImage asset + ".png" -> compressImage asset + _ -> copyFileChanged (srcDir asset) out -- build "//*.org" %> copy -- build "//*.jpg" %> copy @@ -136,27 +148,53 @@ genHtmlAction :: (FilePath -> Action BlogPost) -> (FilePath -> Action Template) -> [Char] -> Action () genHtmlAction getPost getTemplate out = do - template <- getTemplate ("templates" "main.mustache") + let isPost = takeDirectory1 (dropDirectory1 out) == "post" + template <- getTemplate ("templates" if isPost then "post.mustache" else "main.mustache") let srcFile = srcDir (dropDirectory1 (out -<.> "org")) liftIO $ putText $ "need: " <> (toS srcFile) <> " -> " <> (toS out) need [srcFile] bp <- getPost srcFile innerHtml <- genHtml bp let htmlContent = - renderMustache template $ object [ "title" .= postTitle bp - , "authors" .= postAuthors bp - , "date" .= postDate bp - , "body" .= innerHtml - ] + renderMustache template + $ object [ "title" .= postTitle bp + , "authors" .= postAuthors bp + , "date" .= postDate bp + , "body" .= innerHtml + ] writeFile' out (toS htmlContent) +genAscii :: (MonadIO m, MonadFail m) => BlogPost -> m Text +genAscii bp = do + eitherAscii <- liftIO $ Pandoc.runIO $ Writers.writePlain def (postBody bp) + case eitherAscii of + Left _ -> fail "BAD" + Right innerAscii -> return innerAscii + + +genAsciiAction + :: (FilePath -> Action BlogPost) + -> [Char] -> Action () +genAsciiAction getPost out = do + let srcFile = srcDir (dropDirectory1 (out -<.> "org")) + need [srcFile] + bp <- getPost srcFile + innerAscii <- genAscii bp + let preamble = postTitle bp <> "\n" + <> postDate bp <> "\n\n" + writeFile' out (toS (preamble <> toS innerAscii)) + allHtmlAction :: Action () allHtmlAction = do allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] let allHtmlFiles = map (-<.> "html") allOrgFiles - need (map build (allHtmlFiles - -- <> ["articles.html"] - )) + need (map build allHtmlFiles) + +allAsciiAction :: Action () +allAsciiAction = do + allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] + let allAsciiFiles = map (-<.> "txt") allOrgFiles + need (map build allAsciiFiles) compressImage :: CmdResult b => FilePath -> Action b compressImage img = do @@ -181,14 +219,16 @@ allRule :: Rules () allRule = phony "all" $ do allAssets <- filter (/= ".DS_Store") <$> getDirectoryFiles srcDir ["//*.*"] - forM_ allAssets $ \asset -> - case (takeExtension asset) of - ".jpg" -> compressImage asset - ".jpeg" -> compressImage asset - ".gif" -> compressImage asset - ".png" -> compressImage asset - _ -> copyFileChanged (srcDir asset) (siteDir asset) + need (map build allAssets) + -- forM_ allAssets $ \asset -> + -- case (takeExtension asset) of + -- ".jpg" -> compressImage asset + -- ".jpeg" -> compressImage asset + -- ".gif" -> compressImage asset + -- ".png" -> compressImage asset + -- _ -> copyFileChanged (srcDir asset) (siteDir asset) allHtmlAction + allAsciiAction cleanRule :: Rules () cleanRule = diff --git a/templates/post.html b/templates/post.mustache similarity index 100% rename from templates/post.html rename to templates/post.mustache From 0a1aef7425ad4c5f75eaf3d03df102d2b029ecbb Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Wed, 24 Jun 2020 18:36:56 +0200 Subject: [PATCH 19/27] archive working, site working --- Shakefile.hs | 110 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index ffb02b9..ac446a9 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -17,7 +17,7 @@ import Text.Pandoc.Class (PandocMonad) import qualified Text.Pandoc.Class as Pandoc import Text.Pandoc.Definition ( Pandoc(..) , Block(..) - , Inline + , Inline(..) , nullMeta , docTitle , docDate @@ -28,6 +28,7 @@ import Text.Pandoc.Options ( ReaderOptions(..) , ObfuscationMethod(..) ) import qualified Text.Pandoc.Readers as Readers +import Text.Pandoc.Walk (Walkable(..)) import qualified Text.Pandoc.Writers as Writers main :: IO () @@ -70,17 +71,25 @@ getBlogpostFromMetas :: (MonadIO m, MonadFail m) => [Char] -> Bool -> Pandoc -> m BlogPost getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do eitherBlogpost <- liftIO $ Pandoc.runIO $ do - title <- inlineToText $ docTitle meta - date <- inlineToText $ docDate meta + title <- fmap (T.dropEnd 1) $ inlineToText $ docTitle meta + date <- fmap (T.dropAround dateEnvelope) $ inlineToText $ docDate meta authors <- mapM inlineToText $ docAuthors meta return $ BlogPost title date authors path toc pandoc case eitherBlogpost of Left _ -> fail "BAD" Right bp -> return bp + where + dateEnvelope ' ' = True + dateEnvelope '\n' = True + dateEnvelope '\t' = True + dateEnvelope '[' = True + dateEnvelope ']' = True + dateEnvelope _ = False + sortByPostDate :: [BlogPost] -> [BlogPost] sortByPostDate = - sortBy (\a b-> compare (Down (postDate a)) (Down (postDate b))) + sortBy (\a b-> compare (postDate b) (postDate a)) build :: FilePath -> FilePath @@ -103,16 +112,13 @@ buildRules = do getPost <- mkGetPost getPosts <- mkGetPosts getPost getTemplate <- mkGetTemplate - -- build "articles.html" %> \out -> do - -- css <- genAllDeps ["//*.css"] - -- posts <- getPosts () - -- need $ css <> map postUrl (sortByPostDate posts) - -- let titles = toS $ T.intercalate "\n" $ map postTitle posts - -- writeFile' out titles build "//*" %> \out -> do let asset = dropDirectory1 out case (takeExtension asset) of - ".html" -> genHtmlAction getPost getTemplate out + ".html" -> do + if out == siteDir "archive.html" + then buildArchive getPosts getTemplate out + else genHtmlAction getPost getTemplate out ".txt" -> do txtExists <- doesFileExist (srcDir asset) if txtExists @@ -123,23 +129,62 @@ buildRules = do ".gif" -> compressImage asset ".png" -> compressImage asset _ -> copyFileChanged (srcDir asset) out - -- build "//*.org" %> copy - -- build "//*.jpg" %> copy -copy :: FilePath -> Action () -copy out = do - let src = srcDir (dropDirectory1 out) - copyFileChanged src out +buildArchive + :: (() -> Action [BlogPost]) + -> (FilePath -> Action Template) -> [Char] -> Action () +buildArchive getPosts getTemplate out = do + css <- genAllDeps ["//*.css"] + posts <- fmap sortByPostDate $ getPosts () + need $ css <> map postUrl posts + let + title :: Text + title = "#+title: Posts" + articleList = toS $ T.intercalate "\n" $ map postInfo posts + fileContent = title <> "\n\n" <> articleList + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg (def { readerStandalone = True }) (toS fileContent) + bp <- case eitherResult of + Left _ -> fail "BAD" + Right pandoc -> getBlogpostFromMetas out False pandoc + innerHtml <- genHtml bp + template <- getTemplate ("templates" "main.mustache") + let htmlContent = + renderMustache template + $ object [ "title" .= postTitle bp + , "authors" .= postAuthors bp + , "date" .= postDate bp + , "body" .= innerHtml + ] + writeFile' out (toS htmlContent) + +postInfo :: BlogPost -> Text +postInfo bp = + "- " <> date <> ": " <> orglink + where + date = T.takeWhile (/= ' ') (postDate bp) + url = toS (dropDirectory1 (postUrl bp)) + orglink = "[[file:" <> url <> "][" <> (postTitle bp) <> "]]" + +replaceLinks :: Pandoc -> Pandoc +replaceLinks = walk replaceOrgLink + where + replaceOrgLink :: Inline -> Inline + replaceOrgLink lnk@(Link attr inl (url,txt)) = + if takeExtension (toS url) == ".org" + then Link attr inl ((toS (toS url -<.> ".html")),txt) + else lnk + replaceOrgLink x = x genHtml :: (MonadIO m, MonadFail m) => BlogPost -> m Text genHtml bp = do + let htmlBody = replaceLinks (postBody bp) eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String (def { writerTableOfContents = (postToc bp) , writerEmailObfuscation = ReferenceObfuscation }) - (postBody bp) + htmlBody case eitherHtml of Left _ -> fail "BAD" Right innerHtml -> return innerHtml @@ -196,7 +241,7 @@ allAsciiAction = do let allAsciiFiles = map (-<.> "txt") allOrgFiles need (map build allAsciiFiles) -compressImage :: CmdResult b => FilePath -> Action b +compressImage :: FilePath -> Action () compressImage img = do let src = srcDir img dst = siteDir img @@ -205,28 +250,21 @@ compressImage img = do dirExists <- doesDirectoryExist dir when (not dirExists) $ command [] "mkdir" ["-p", dir] - command [] "convert" [src - , "-strip" - , "-resize","320x320>" - , "-interlace","Plane" - , "-quality","85" - , "-define","filter:blur=0.75" - , "-filter","Gaussian" - , "-ordered-dither","o4x4,4" - , dst ] + command_ [] "convert" [ src + , "-strip" + , "-resize","320x320>" + , "-interlace","Plane" + , "-quality","85" + , "-define","filter:blur=0.75" + , "-filter","Gaussian" + , "-ordered-dither","o4x4,4" + , dst ] allRule :: Rules () allRule = phony "all" $ do allAssets <- filter (/= ".DS_Store") <$> getDirectoryFiles srcDir ["//*.*"] - need (map build allAssets) - -- forM_ allAssets $ \asset -> - -- case (takeExtension asset) of - -- ".jpg" -> compressImage asset - -- ".jpeg" -> compressImage asset - -- ".gif" -> compressImage asset - -- ".png" -> compressImage asset - -- _ -> copyFileChanged (srcDir asset) (siteDir asset) + need (map build $ allAssets <> ["archive.html"]) allHtmlAction allAsciiAction From c34fa835041b77cee64df3ec83e87ac2c9f30c91 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 07:06:16 +0200 Subject: [PATCH 20/27] Neil Mitchell help https://github.com/ndmitchell/shake/issues/767 --- Shakefile.hs | 13 ++++++------- shell.nix | 2 ++ src/demo.org | 2 +- src/posts/0013-how-to-choose-your-tools/index.org | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index ac446a9..a6600e7 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -107,12 +107,11 @@ genAllDeps patterns = do buildRules :: Rules () buildRules = do cleanRule - -- build "//*" %> copy allRule getPost <- mkGetPost getPosts <- mkGetPosts getPost getTemplate <- mkGetTemplate - build "//*" %> \out -> do + build "**" %> \out -> do let asset = dropDirectory1 out case (takeExtension asset) of ".html" -> do @@ -231,13 +230,13 @@ genAsciiAction getPost out = do allHtmlAction :: Action () allHtmlAction = do - allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] + allOrgFiles <- getDirectoryFiles srcDir ["**.org"] let allHtmlFiles = map (-<.> "html") allOrgFiles need (map build allHtmlFiles) allAsciiAction :: Action () allAsciiAction = do - allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] + allOrgFiles <- getDirectoryFiles srcDir ["**.org"] let allAsciiFiles = map (-<.> "txt") allOrgFiles need (map build allAsciiFiles) @@ -263,7 +262,7 @@ compressImage img = do allRule :: Rules () allRule = phony "all" $ do - allAssets <- filter (/= ".DS_Store") <$> getDirectoryFiles srcDir ["//*.*"] + allAssets <- filter (/= ".DS_Store") <$> getDirectoryFiles srcDir ["**"] need (map build $ allAssets <> ["archive.html"]) allHtmlAction allAsciiAction @@ -272,7 +271,7 @@ cleanRule :: Rules () cleanRule = phony "clean" $ do putInfo "Cleaning files in _site and _optim" - forM_ [siteDir,optimDir] $ flip removeFilesAfter ["//*"] + forM_ [siteDir,optimDir] $ flip removeFilesAfter ["**"] mkGetTemplate :: Rules (FilePath -> Action Template) mkGetTemplate = newCache $ \path -> do @@ -302,4 +301,4 @@ mkGetPost = newCache $ \path -> do mkGetPosts :: (FilePath -> Action b) -> Rules (() -> Action [b]) mkGetPosts getPost = - newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] + newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts/**.org"] diff --git a/shell.nix b/shell.nix index d7827e6..bff21dd 100644 --- a/shell.nix +++ b/shell.nix @@ -26,5 +26,7 @@ pkgs.mkShell { git direnv haskellPackages.shake + # for emacs dev + ripgrep ]; } diff --git a/src/demo.org b/src/demo.org index 91145e1..131689a 100644 --- a/src/demo.org +++ b/src/demo.org @@ -344,9 +344,9 @@ After the rule. an image: +#+ATTR_HTML: The Experiment #+CAPTION: Testing include an image #+NAME: fig:test-image -#+ATTR_HTML: The Experiment [[../img/a.png]] diff --git a/src/posts/0013-how-to-choose-your-tools/index.org b/src/posts/0013-how-to-choose-your-tools/index.org index 6aa6279..9e116d2 100644 --- a/src/posts/0013-how-to-choose-your-tools/index.org +++ b/src/posts/0013-how-to-choose-your-tools/index.org @@ -19,8 +19,8 @@ And this week-end, in the morning I read those: - [[https://news.ycombinator.com/item?id=23107123][Making Emacs popular again]] - [[https://news.ycombinator.com/item?id=23092904][Github Codespace]] -#+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.g7OSuCGH0u7OIUA9vdxlTAEsCo%26pid%3DApi&f=1 @ 2020-05-09 12:49:34 #+ATTR_HTML: :alt Midsommar Welcome +#+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.g7OSuCGH0u7OIUA9vdxlTAEsCo%26pid%3DApi&f=1 @ 2020-05-09 12:49:34 [[file:2020-05-09_12-49-34_.jpeg]] @@ -93,8 +93,8 @@ For the single developers and open source developers this offer: But the price to pay is hidden. -#+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.FrCRrhENMjdfD4pUcAwKEgHaEK%26pid%3DApi&f=1 @ 2020-05-09 12:48:31 #+ATTR_HTML: :alt Midsommar Cry +#+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.FrCRrhENMjdfD4pUcAwKEgHaEK%26pid%3DApi&f=1 @ 2020-05-09 12:48:31 [[file:2020-05-09_12-48-31_.jpeg]] From 4df922b475de5da93e5addead3b0176f89060685 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 07:10:00 +0200 Subject: [PATCH 21/27] fix archive build --- Shakefile.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shakefile.hs b/Shakefile.hs index a6600e7..595c1ea 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -301,4 +301,4 @@ mkGetPost = newCache $ \path -> do mkGetPosts :: (FilePath -> Action b) -> Rules (() -> Action [b]) mkGetPosts getPost = - newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts/**.org"] + newCache $ \() -> mapM getPost =<< getDirectoryFiles "" ["src/posts//*.org"] From 62461dc616a1a115eb1afef0816036b52b924544 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 13:08:18 +0200 Subject: [PATCH 22/27] update --- Shakefile.hs | 60 ++++++++++++++++++++++++++-- src/posts/0010-Haskell-Now/index.org | 8 +--- templates/main.mustache | 15 ++++++- templates/post.mustache | 2 +- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 595c1ea..3d887e5 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -7,6 +7,9 @@ import Development.Shake import Development.Shake.Command import Development.Shake.FilePath +import Data.Time.Format.ISO8601 (iso8601Show) +import qualified Data.Time.Clock as Clock + import Control.Monad.Fail import Data.Aeson -- import qualified Text.Megaparsec as Megaparsec @@ -18,10 +21,12 @@ import qualified Text.Pandoc.Class as Pandoc import Text.Pandoc.Definition ( Pandoc(..) , Block(..) , Inline(..) + , MetaValue(..) , nullMeta , docTitle , docDate , docAuthors + , lookupMeta ) import Text.Pandoc.Options ( ReaderOptions(..) , WriterOptions(..) @@ -59,6 +64,8 @@ data BlogPost = , postDate :: T.Text , postAuthors :: [T.Text] , postUrl :: FilePath + , postTags :: [T.Text] + , postDescr :: T.Text , postToc :: Bool , postBody :: Pandoc } @@ -74,7 +81,10 @@ getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do title <- fmap (T.dropEnd 1) $ inlineToText $ docTitle meta date <- fmap (T.dropAround dateEnvelope) $ inlineToText $ docDate meta authors <- mapM inlineToText $ docAuthors meta - return $ BlogPost title date authors path toc pandoc + let tags = tagsToList $ lookupMeta "keywords" meta + description = descr $ lookupMeta "description" meta + liftIO $ print (lookupMeta "keywords" meta) + return $ BlogPost title date authors path tags description toc pandoc case eitherBlogpost of Left _ -> fail "BAD" Right bp -> return bp @@ -85,6 +95,16 @@ getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do dateEnvelope '[' = True dateEnvelope ']' = True dateEnvelope _ = False + tagsToList (Just (MetaList ms)) = map toStr ms + tagsToList _ = [] + descr (Just (MetaString t)) = t + descr _ = "" + toStr (MetaString t) = t + toStr (MetaInlines inlines) = T.intercalate " " $ map inlineToTxt inlines + toStr _ = "" + inlineToTxt (Str t) = t + inlineToTxt _ = "" + sortByPostDate :: [BlogPost] -> [BlogPost] @@ -152,6 +172,8 @@ buildArchive getPosts getTemplate out = do $ object [ "title" .= postTitle bp , "authors" .= postAuthors bp , "date" .= postDate bp + , "tags" .= postTags bp + , "description" .= postDescr bp , "body" .= innerHtml ] writeFile' out (toS htmlContent) @@ -174,6 +196,33 @@ replaceLinks = walk replaceOrgLink else lnk replaceOrgLink x = x +orgContentToText org = do + eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg (def { readerStandalone = True }) org + pandoc <- case eitherResult of + Left _ -> fail "BAD" + Right p -> return p + eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String (def {writerEmailObfuscation = ReferenceObfuscation}) pandoc + case eitherHtml of + Left _ -> fail "BAD" + Right innerHtml -> return innerHtml + +postamble now bp = + orgContentToText $ unlines $ + ["@@html:
@@" + , "" + , "/Any comment? Click on my email below and I'll add it./" + , "" + , "| author | [[mailto:Yann Esposito ?subject=yblog: " <> (postTitle bp) <> "][Yann Esposito ]] |" + , "| tags | " <> T.intercalate " " (map ("#"<>) (postTags bp)) <> " |" + , "| date | " <> postDate bp <> " |" + , "| rss | [[file:/rss.xml][RSS]] ([[https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fher.esy.fun%2Frss.xml][validate]]) |" + , "| size | XXK (html XXK, css XXK, img XXK) |" + , "| gz | XXK (html XXK, css XXK, img XXK) |" + , "| generated | " <> now <> " |" + , "" + , "@@html:
@@" + ] + genHtml :: (MonadIO m, MonadFail m) => BlogPost -> m Text genHtml bp = do let htmlBody = replaceLinks (postBody bp) @@ -184,9 +233,12 @@ genHtml bp = do , writerEmailObfuscation = ReferenceObfuscation }) htmlBody - case eitherHtml of + body <- case eitherHtml of Left _ -> fail "BAD" Right innerHtml -> return innerHtml + now <- liftIO Clock.getCurrentTime + footer <- postamble (toS (iso8601Show now)) bp + return (body <> footer) genHtmlAction :: (FilePath -> Action BlogPost) @@ -204,6 +256,8 @@ genHtmlAction getPost getTemplate out = do $ object [ "title" .= postTitle bp , "authors" .= postAuthors bp , "date" .= postDate bp + , "tags" .= postTags bp + , "description" .= postDescr bp , "body" .= innerHtml ] writeFile' out (toS htmlContent) @@ -230,7 +284,7 @@ genAsciiAction getPost out = do allHtmlAction :: Action () allHtmlAction = do - allOrgFiles <- getDirectoryFiles srcDir ["**.org"] + allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] let allHtmlFiles = map (-<.> "html") allOrgFiles need (map build allHtmlFiles) diff --git a/src/posts/0010-Haskell-Now/index.org b/src/posts/0010-Haskell-Now/index.org index 86da14f..4bc5b4f 100644 --- a/src/posts/0010-Haskell-Now/index.org +++ b/src/posts/0010-Haskell-Now/index.org @@ -4,13 +4,7 @@ #+author: Yann Esposito #+EMAIL: yann@esposito.host #+keywords: Haskell, programming, functional, tutorial -#+DESCRIPTION: A short and intense introduction to Haskell. -#+DESCRIPTION: This is an update of my old (2012) article. -#+DESCRIPTION: A lot of things have changed since then. -#+DESCRIPTION: Mostly I changed my approach about the easiest way to install -#+DESCRIPTION: a Haskell playground. -#+DESCRIPTION: I removed the not as important part, and added a short -#+DESCRIPTION: introduction about starting a new project. +#+DESCRIPTION: A short and intense introduction to Haskell. This is an update of my old (2012) article. A lot of things have changed since then. Mostly I changed my approach about the easiest way to install a Haskell playground. I removed the not as important part, and added a short introduction about starting a new project. #+OPTIONS: auto-id:t toc:t #+STARTUP: overview diff --git a/templates/main.mustache b/templates/main.mustache index a94c624..ee03523 100644 --- a/templates/main.mustache +++ b/templates/main.mustache @@ -6,7 +6,7 @@ {{title}} - + @@ -34,13 +34,24 @@
+
{{description}}
+ {{{ body }}}
-
+
Any comment? Click on my email below and I'll add it. From 931d9c44831f26e908eff49f5ecdc3ab13242d7d Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 14:22:58 +0200 Subject: [PATCH 23/27] improvements --- Shakefile.hs | 7 +- src/css/y.css | 8 +- src/drafts/XXXX-how-i-use-nix/index.org | 4 +- .../0013-how-to-choose-your-tools/index.org | 11 +- templates/main.mustache | 114 ++++++++-------- templates/post.mustache | 129 ++++++++---------- 6 files changed, 129 insertions(+), 144 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 3d887e5..e1a5a8c 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -208,11 +208,10 @@ orgContentToText org = do postamble now bp = orgContentToText $ unlines $ - ["@@html:
@@" + [ "@@html:
@@" + , "@@html:Any comment? Click on my email below and I'll add it.@@" , "" - , "/Any comment? Click on my email below and I'll add it./" - , "" - , "| author | [[mailto:Yann Esposito ?subject=yblog: " <> (postTitle bp) <> "][Yann Esposito ]] |" + , "| author | @@html:@@ [[mailto:Yann Esposito ?subject=yblog: " <> (postTitle bp) <> "][Yann Esposito ]] @@html:@@ |" , "| tags | " <> T.intercalate " " (map ("#"<>) (postTags bp)) <> " |" , "| date | " <> postDate bp <> " |" , "| rss | [[file:/rss.xml][RSS]] ([[https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fher.esy.fun%2Frss.xml][validate]]) |" diff --git a/src/css/y.css b/src/css/y.css index f349c5a..55776c9 100644 --- a/src/css/y.css +++ b/src/css/y.css @@ -309,9 +309,6 @@ dl dd { font-size: 85%; margin-bottom: 0.4rem; } -.footnotes { - border-top: 1px solid hsl(0, 0%, 39%); -} /* Center title and paragraph */ .abstract, @@ -319,7 +316,9 @@ dl dd { text-align: center; } .abstract { - margin: 2.25rem 0; + margin: 2.25rem; + font-size: 0.85rem; + font-style: italic; } /* Format the LaTeX symbol correctly (a higher up, e lower) */ @@ -430,6 +429,7 @@ footer { margin: 3em 0; border-bottom: solid 1px; line-height: 1em; font-size: 0.85em; + text-align: center; } td { border-bottom: none; padding: .2rem; } table { margin-top: 1rem; } diff --git a/src/drafts/XXXX-how-i-use-nix/index.org b/src/drafts/XXXX-how-i-use-nix/index.org index ef44c01..29eed30 100644 --- a/src/drafts/XXXX-how-i-use-nix/index.org +++ b/src/drafts/XXXX-how-i-use-nix/index.org @@ -3,9 +3,7 @@ #+Email: yann@esposito.host #+Date: [2020-06-14 Sun] #+KEYWORDS: nix, programming -#+DESCRIPTION: In this article I explain how I use nix. -#+DESCRIPTION: As a brew replacement, as home environment manager, -#+DESCRIPTION: to have reproductible dev environment. +#+DESCRIPTION: In this article I explain how I use nix. As a brew replacement, as home environment manager, to have reproductible dev environment. #+LANGUAGE: en #+LANG: en #+OPTIONS: H:5 auto-id:t toc:nil diff --git a/src/posts/0013-how-to-choose-your-tools/index.org b/src/posts/0013-how-to-choose-your-tools/index.org index 9e116d2..e345974 100644 --- a/src/posts/0013-how-to-choose-your-tools/index.org +++ b/src/posts/0013-how-to-choose-your-tools/index.org @@ -3,10 +3,7 @@ #+Email: yann@esposito.host #+Date: [2020-05-09 Sat] #+KEYWORDS: emacs, softwares -#+DESCRIPTION: Modern tools tend to disapears. -#+DESCRIPTION: An app on the web will change, and could break for the worst. -#+DESCRIPTION: Quite often investing in long living tools which are harder start -#+DESCRIPTION: with will be worth the investment. +#+DESCRIPTION: Modern tools tend to disapears. An app on the web will change, and could break for the worst. Quite often investing in long living tools which are harder start with will be worth the investment. #+LANGUAGE: en #+LANG: en #+OPTIONS: H:5 auto-id:t @@ -21,6 +18,8 @@ And this week-end, in the morning I read those: #+ATTR_HTML: :alt Midsommar Welcome #+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.g7OSuCGH0u7OIUA9vdxlTAEsCo%26pid%3DApi&f=1 @ 2020-05-09 12:49:34 +#+NAME: Welcome +#+CAPTION: Midsommar Welcome [[file:2020-05-09_12-49-34_.jpeg]] @@ -93,8 +92,9 @@ For the single developers and open source developers this offer: But the price to pay is hidden. -#+ATTR_HTML: :alt Midsommar Cry +#+ATTR_HTML: :alt Midsommar Sorrow #+DOWNLOADED: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.FrCRrhENMjdfD4pUcAwKEgHaEK%26pid%3DApi&f=1 @ 2020-05-09 12:48:31 +#+CAPTION: Midsommar Sorrow [[file:2020-05-09_12-48-31_.jpeg]] @@ -178,6 +178,7 @@ future. :CUSTOM_ID: post-conclusion :END: +#+ATTR_HTML: :alt Midsommar Joy #+CAPTION: Midsommar Joy [[./midsommar-joy.jpeg]] diff --git a/templates/main.mustache b/templates/main.mustache index ee03523..962faeb 100644 --- a/templates/main.mustache +++ b/templates/main.mustache @@ -1,62 +1,58 @@ - - - -{{title}} - - - - - - - - - -
-
- | -
-
-
-
- -

{{title}}

-
-
- -
{{description}}
- -{{{ body }}} - -
-
-
-
-
-
- + + + + {{title}} + + + + + + + + + + +
+
+ | +
+
+
+
+ +

{{title}}

+
+
+
+ {{description}} +
+ {{{ body }}} +
+
+
+ +
+
+
+ diff --git a/templates/post.mustache b/templates/post.mustache index 1bbe43c..e119c7b 100644 --- a/templates/post.mustache +++ b/templates/post.mustache @@ -1,72 +1,63 @@ - - - -{{title}} - - - - - - - - -
-
- | -
-
-
-
- -
-

{{title}}

-
{{authors}}
-
on - Yann Esposito's blog - - source - -
-
{{description}}
-
-
- {{{body}}} -
-
-
-
- -
-
- -
- + + + + {{title}} + + + + + + + +
+
+ | +
+
+
+
+ +
+

{{title}}

+
{{authors}}
+
on + Yann Esposito's blog - + source - + +
+
+ {{description}} +
+
+
+
+ {{{body}}} +
+
+
+ +
+
+
+ From f12936254a4de7f4ca48fc607e4011137ed76aa8 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 15:27:00 +0200 Subject: [PATCH 24/27] better templates --- Shakefile.hs | 40 +++++++++++++++++++++++++++------------- templates/main.mustache | 5 +---- templates/post.mustache | 7 ++++--- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index e1a5a8c..318022a 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -4,7 +4,7 @@ import Protolude import Development.Shake -import Development.Shake.Command +-- import Development.Shake.Command import Development.Shake.FilePath import Data.Time.Format.ISO8601 (iso8601Show) @@ -62,8 +62,9 @@ optimDir = "_optim" data BlogPost = BlogPost { postTitle :: T.Text , postDate :: T.Text - , postAuthors :: [T.Text] + , postAuthor :: T.Text , postUrl :: FilePath + , postSrc :: FilePath , postTags :: [T.Text] , postDescr :: T.Text , postToc :: Bool @@ -80,11 +81,14 @@ getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do eitherBlogpost <- liftIO $ Pandoc.runIO $ do title <- fmap (T.dropEnd 1) $ inlineToText $ docTitle meta date <- fmap (T.dropAround dateEnvelope) $ inlineToText $ docDate meta - authors <- mapM inlineToText $ docAuthors meta + author <- case head $ docAuthors meta of + Just m -> inlineToText m + Nothing -> return "" let tags = tagsToList $ lookupMeta "keywords" meta description = descr $ lookupMeta "description" meta + url = "/" dropDirectory1 path -<.> "org" liftIO $ print (lookupMeta "keywords" meta) - return $ BlogPost title date authors path tags description toc pandoc + return $ BlogPost title date author url path tags description toc pandoc case eitherBlogpost of Left _ -> fail "BAD" Right bp -> return bp @@ -155,7 +159,7 @@ buildArchive buildArchive getPosts getTemplate out = do css <- genAllDeps ["//*.css"] posts <- fmap sortByPostDate $ getPosts () - need $ css <> map postUrl posts + need $ css <> map postSrc posts let title :: Text title = "#+title: Posts" @@ -170,7 +174,7 @@ buildArchive getPosts getTemplate out = do let htmlContent = renderMustache template $ object [ "title" .= postTitle bp - , "authors" .= postAuthors bp + , "author" .= postAuthor bp , "date" .= postDate bp , "tags" .= postTags bp , "description" .= postDescr bp @@ -183,8 +187,7 @@ postInfo bp = "- " <> date <> ": " <> orglink where date = T.takeWhile (/= ' ') (postDate bp) - url = toS (dropDirectory1 (postUrl bp)) - orglink = "[[file:" <> url <> "][" <> (postTitle bp) <> "]]" + orglink = "[[file:" <> (toS (postUrl bp)) <> "][" <> (postTitle bp) <> "]]" replaceLinks :: Pandoc -> Pandoc replaceLinks = walk replaceOrgLink @@ -196,6 +199,7 @@ replaceLinks = walk replaceOrgLink else lnk replaceOrgLink x = x +orgContentToText :: (MonadIO m, MonadFail m) => Text -> m Text orgContentToText org = do eitherResult <- liftIO $ Pandoc.runIO $ Readers.readOrg (def { readerStandalone = True }) org pandoc <- case eitherResult of @@ -206,6 +210,7 @@ orgContentToText org = do Left _ -> fail "BAD" Right innerHtml -> return innerHtml +postamble :: (MonadIO m, MonadFail m) => Text -> BlogPost -> m Text postamble now bp = orgContentToText $ unlines $ [ "@@html:
@@" @@ -228,7 +233,7 @@ genHtml bp = do eitherHtml <- liftIO $ Pandoc.runIO $ Writers.writeHtml5String - (def { writerTableOfContents = (postToc bp) + (def { writerTableOfContents = postToc bp , writerEmailObfuscation = ReferenceObfuscation }) htmlBody @@ -239,11 +244,14 @@ genHtml bp = do footer <- postamble (toS (iso8601Show now)) bp return (body <> footer) +origin :: Text +origin = "https://her.esy.fun" + genHtmlAction :: (FilePath -> Action BlogPost) -> (FilePath -> Action Template) -> [Char] -> Action () genHtmlAction getPost getTemplate out = do - let isPost = takeDirectory1 (dropDirectory1 out) == "post" + let isPost = takeDirectory1 (dropDirectory1 out) == "posts" template <- getTemplate ("templates" if isPost then "post.mustache" else "main.mustache") let srcFile = srcDir (dropDirectory1 (out -<.> "org")) liftIO $ putText $ "need: " <> (toS srcFile) <> " -> " <> (toS out) @@ -253,11 +261,14 @@ genHtmlAction getPost getTemplate out = do let htmlContent = renderMustache template $ object [ "title" .= postTitle bp - , "authors" .= postAuthors bp + , "author" .= postAuthor bp , "date" .= postDate bp , "tags" .= postTags bp , "description" .= postDescr bp , "body" .= innerHtml + , "orgsource" .= T.pack (postUrl bp -<.> "org") + , "txtsource" .= T.pack (postUrl bp -<.> "txt") + , "permalink" .= T.pack (toS origin <> postUrl bp) ] writeFile' out (toS htmlContent) @@ -278,7 +289,10 @@ genAsciiAction getPost out = do bp <- getPost srcFile innerAscii <- genAscii bp let preamble = postTitle bp <> "\n" - <> postDate bp <> "\n\n" + <> T.replicate (T.length (postTitle bp)) "=" <> "\n\n" + <> postAuthor bp <> "\n" + <> postDate bp <> "\n" + <> toS origin <> toS (postUrl bp) <> "\n\n" writeFile' out (toS (preamble <> toS innerAscii)) allHtmlAction :: Action () @@ -289,7 +303,7 @@ allHtmlAction = do allAsciiAction :: Action () allAsciiAction = do - allOrgFiles <- getDirectoryFiles srcDir ["**.org"] + allOrgFiles <- getDirectoryFiles srcDir ["//*.org"] let allAsciiFiles = map (-<.> "txt") allOrgFiles need (map build allAsciiFiles) diff --git a/templates/main.mustache b/templates/main.mustache index 962faeb..8629892 100644 --- a/templates/main.mustache +++ b/templates/main.mustache @@ -5,7 +5,7 @@ {{title}} - + @@ -34,9 +34,6 @@

{{title}}

-
- {{description}} -
{{{ body }}}
diff --git a/templates/post.mustache b/templates/post.mustache index e119c7b..e963c55 100644 --- a/templates/post.mustache +++ b/templates/post.mustache @@ -4,9 +4,9 @@ {{title}} - + - + @@ -30,10 +30,11 @@

{{title}}

-
{{authors}}
+
{{author}}

on Yann Esposito's blog - source - + txt -
From 6c3f4f3031c703abce35e91875bb51138159497f Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 16:28:35 +0200 Subject: [PATCH 25/27] updated and mostly feature equal --- Shakefile.hs | 5 ++--- src/posts/0012-solaryzed-theme/index.org | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 318022a..53b5d16 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -80,14 +80,13 @@ getBlogpostFromMetas getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do eitherBlogpost <- liftIO $ Pandoc.runIO $ do title <- fmap (T.dropEnd 1) $ inlineToText $ docTitle meta - date <- fmap (T.dropAround dateEnvelope) $ inlineToText $ docDate meta + date <- fmap (T.takeWhile (/= ' ') . (T.dropAround dateEnvelope)) $ inlineToText $ docDate meta author <- case head $ docAuthors meta of Just m -> inlineToText m Nothing -> return "" let tags = tagsToList $ lookupMeta "keywords" meta description = descr $ lookupMeta "description" meta url = "/" dropDirectory1 path -<.> "org" - liftIO $ print (lookupMeta "keywords" meta) return $ BlogPost title date author url path tags description toc pandoc case eitherBlogpost of Left _ -> fail "BAD" @@ -246,7 +245,7 @@ genHtml bp = do origin :: Text origin = "https://her.esy.fun" - + genHtmlAction :: (FilePath -> Action BlogPost) -> (FilePath -> Action Template) -> [Char] -> Action () diff --git a/src/posts/0012-solaryzed-theme/index.org b/src/posts/0012-solaryzed-theme/index.org index 1811773..26ecfe4 100644 --- a/src/posts/0012-solaryzed-theme/index.org +++ b/src/posts/0012-solaryzed-theme/index.org @@ -58,6 +58,7 @@ Here is the CSS you could use: {{{colorbox(b1,black,#a7abb5)}}} {{{colorbox(b2,black,#e5e8f0)}}} {{{colorbox(b3,black,#f3f6fe)}}} +@@html:
@@ {{{colorbox(y,white,#ad8c51)}}} {{{colorbox(o,white,#a9664b)}}} {{{colorbox(r,white,#af6256)}}} From 78008d3df4af10ab1a823ca71662e80e3a7bffae Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 17:23:59 +0200 Subject: [PATCH 26/27] fixed almos everything --- Shakefile.hs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Shakefile.hs b/Shakefile.hs index 53b5d16..90ae396 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -75,12 +75,22 @@ inlineToText :: PandocMonad m => [Inline] -> m T.Text inlineToText inline = Writers.writeAsciiDoc def (Pandoc nullMeta [Plain inline]) +reformatDate :: Text -> Text +reformatDate = T.takeWhile (/= ' ') . (T.dropAround dateEnvelope) + where + dateEnvelope ' ' = True + dateEnvelope '\n' = True + dateEnvelope '\t' = True + dateEnvelope '[' = True + dateEnvelope ']' = True + dateEnvelope _ = False + getBlogpostFromMetas :: (MonadIO m, MonadFail m) => [Char] -> Bool -> Pandoc -> m BlogPost getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do eitherBlogpost <- liftIO $ Pandoc.runIO $ do title <- fmap (T.dropEnd 1) $ inlineToText $ docTitle meta - date <- fmap (T.takeWhile (/= ' ') . (T.dropAround dateEnvelope)) $ inlineToText $ docDate meta + date <- fmap reformatDate $ inlineToText $ docDate meta author <- case head $ docAuthors meta of Just m -> inlineToText m Nothing -> return "" @@ -92,12 +102,6 @@ getBlogpostFromMetas path toc pandoc@(Pandoc meta _) = do Left _ -> fail "BAD" Right bp -> return bp where - dateEnvelope ' ' = True - dateEnvelope '\n' = True - dateEnvelope '\t' = True - dateEnvelope '[' = True - dateEnvelope ']' = True - dateEnvelope _ = False tagsToList (Just (MetaList ms)) = map toStr ms tagsToList _ = [] descr (Just (MetaString t)) = t @@ -219,8 +223,8 @@ postamble now bp = , "| tags | " <> T.intercalate " " (map ("#"<>) (postTags bp)) <> " |" , "| date | " <> postDate bp <> " |" , "| rss | [[file:/rss.xml][RSS]] ([[https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fher.esy.fun%2Frss.xml][validate]]) |" - , "| size | XXK (html XXK, css XXK, img XXK) |" - , "| gz | XXK (html XXK, css XXK, img XXK) |" + , "| size | @@html:
XXK (html XXK, css XXK, img XXK)
@@ |" + , "| gz | @@html:
XXK (html XXK, css XXK, img XXK)
@@ |" , "| generated | " <> now <> " |" , "" , "@@html:@@" From 53fa73320945b7238cd683e9aa9eaca6e02b9476 Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jun 2020 17:42:33 +0200 Subject: [PATCH 27/27] minor fix --- src/css/y.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/css/y.css b/src/css/y.css index 55776c9..1afeece 100644 --- a/src/css/y.css +++ b/src/css/y.css @@ -554,6 +554,8 @@ body, body > div { } a,a:visited { color: var(--hl); } +figcaption { color: var(--fg0); } + /* ---- SYNTAX HIGHLIGHTING ---- */ #table-of-contents { text-align: left; }