commit 73beb6d0aa8c422c901bf9075a88ea655f7d7b01 Author: Abigail Magalhães Date: Tue May 25 21:06:43 2021 -0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e40f471 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/.site +/.store +/.stack-work +/.vscode + +/fonts +/css/fonts + +/.mailmap diff --git a/css/colors.scss b/css/colors.scss new file mode 100644 index 0000000..a37d146 --- /dev/null +++ b/css/colors.scss @@ -0,0 +1,31 @@ +$black: #282c34; +$white: #abb2bf; +$light_red: #e06c75; +$dark_red: #be5046; +$green: #98c379; +$light_yellow: #e5c07b; +$dark_yellow: #d19a66; +$blue: #61afef; +$magenta: #c678dd; +$cyan: #56b6c2; +$gutter_grey: #4b5263; +$comment_grey: #5c6370; + +$orange: #ffac5f; +$blonde: #f5ddbc; +$light-purple: #f2f1f8; +$purple: #7060eb; +$yugo: #ea8472; + +$code-background: $black; +$code-language-background: lighten($black, 5%); + +$code-language-color: $white; + +$code-fg: $white; +$code-kw: $light_red; +$code-dt: $dark_yellow; +$code-ot: $code-fg; +$code-co: $comment_grey; + +// comment \ No newline at end of file diff --git a/css/default.scss b/css/default.scss new file mode 100644 index 0000000..53ebc94 --- /dev/null +++ b/css/default.scss @@ -0,0 +1,208 @@ +$purple: #424969; +$orange: #ffac5f; +$blonde: #f5ddbc; +$light-purple: #faf0fa; + +$card-bg: #dde; + +$header: $orange; +$header-height: 50px; + +$max-width: 80ch; + +$pfp-size: 64px; + +html, body { + min-height: 100%; + height: 100%; + margin: 0; + + background-color: white; + + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; +} + +body { + display: flex; + flex-direction: column; + + counter-reset: theorem figure; +} + +div#header { + background-color: $header; + height: $header-height; + + display: flex; + flex-direction: row; + align-items: stretch; + justify-content: space-between; + + flex-wrap: nowrap; + overflow-x: auto; + + div#logo { + margin: auto; + line-height: $header-height; + + padding-left: .5em; + padding-right: .5em; + font-size: 18pt; + + a { + color: black; + text-decoration: none; + } + + transition: background-color .2s ease-in-out; + } + + div#logo:hover { + background-color: darken($header, 10%); + } +} + +.column { + list-style: none; + display: flex; + flex-flow: column nowrap; +} + +.columns { + display: flex; + flex-flow: row nowrap; + > * { + width: 50%; + padding: 0px; + } +} + +div#content { + max-width: $max-width; + margin: 0px auto 0px auto; + flex: 1 0 auto; + + font-size: 14pt; + line-height: 1.6; + + p { + text-align: justify; + letter-spacing: 1.75; + + code { + display: inline-block; + } + + span.qed { + float: right; + } + + span.theorem ::after { + counter-increment: theorem; + content: " " counter(theorem); + } + + span.theorem, span.paragraph-marker { + font-style: italic; + } + } + + h1 { + font-variant: small-caps; + max-width: 120ch; + } + + * { + max-width: 100%; + } + + .person { + margin: 5px 5px; + padding: 0.5em; + + background-color: $card-bg; + border: 1px solid darken($card-bg, 10%); + border-radius: 5px; + + .header { + display: flex; + + img.pfp { + width: $pfp-size; + height: $pfp-size; + border-radius: 5px; + } + + div.default-pfp { + background-color: black; + width: $pfp-size; + height: $pfp-size; + border-radius: 3px; + img { + filter: invert(1); + } + } + + line-height: $pfp-size; + + .name { + padding-left: 10px; + font-size: 18pt; + } + + .pronouns { + font-size: 10pt; + } + } + } +} + +details[open].person { + summary::before { + transform: rotate(90deg); + } + + .guts { + height: unset; + } + + summary ~ * { + animation: sweep .5s ease-in-out; + } +} + +@keyframes sweep { + 0% { + font-size: 0pt; + } + 100% { + font-size: unset; + } +} + +details.person { + > summary::before { + content: '▸'; + margin-right: 1em; + + transition: transform 0.5s; + } +} + +.footnote-back { + margin-left: 0.5em; +} + +@media only screen and (max-width: $max-width) { + div#content { + margin-left: 1em; + margin-right: 1em; + } + + .columns { + flex-flow: column nowrap; + > * { + width: unset; + } + } +} \ No newline at end of file diff --git a/hie.yaml b/hie.yaml new file mode 100644 index 0000000..142e69f --- /dev/null +++ b/hie.yaml @@ -0,0 +1,2 @@ +cradle: + stack: \ No newline at end of file diff --git a/offtopia-org.cabal b/offtopia-org.cabal new file mode 100644 index 0000000..8e2fda7 --- /dev/null +++ b/offtopia-org.cabal @@ -0,0 +1,27 @@ +name: offtopia-org +version: 0.1.0.0 +build-type: Simple +cabal-version: >= 1.10 + +executable site + main-is: site.hs + build-depends: base + , hakyll + , pandoc + , skylighting + , process + , containers + , directory + , pandoc-types + , bytestring + , uri-encode + , deepseq + , text + , hsass + , aeson + , hakyll-sass + , unordered-containers + ghc-options: -threaded + default-language: Haskell2010 + + ghc-options: -optl-fuse-ld=lld diff --git a/pages/index.html b/pages/index.html new file mode 100644 index 0000000..cc327e0 --- /dev/null +++ b/pages/index.html @@ -0,0 +1,36 @@ +--- +title: offtopia.org +--- + +We do open source. Sometimes. I need this text to be at least 95 characters long so that the webpage flows right, it's really quite annoying. + +

What we do

+ + + + +

Who we are

+ +
+ + + +
diff --git a/pages/people/abby.md b/pages/people/abby.md new file mode 100644 index 0000000..525043c --- /dev/null +++ b/pages/people/abby.md @@ -0,0 +1,16 @@ +--- +name: Abbie + +link: https://abby.how +pfp: https://plt.abby.how/means/c3Qs.png + +pronouns: she/her + +projects: + - name: Amulet + url: https://amulet.works + desc: | + Amulet is a functional programming language in the ML tradition. +--- + +Hi! I'm a type-theorist-in-training from the south of Brazil. I also made this website, which is why it looks _exactly_ like my blog: Powered by the same stuff, too! \ No newline at end of file diff --git a/pages/projects/ahti.md b/pages/projects/ahti.md new file mode 100644 index 0000000..6fc8590 --- /dev/null +++ b/pages/projects/ahti.md @@ -0,0 +1,9 @@ +--- +name: ahti.space +link: https://ahti.space + +participants: + - a + - b + - c +--- \ No newline at end of file diff --git a/site.hs b/site.hs new file mode 100644 index 0000000..49975c1 --- /dev/null +++ b/site.hs @@ -0,0 +1,190 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE OverloadedStrings #-} + +import Control.DeepSeq (rnf) +import Control.Concurrent +import Control.Exception +import Control.Monad + +import qualified Data.ByteString.Lazy.Char8 as BS +import Data.ByteString.Lazy.Char8 (pack, unpack) +import qualified Data.Text.Encoding as T +import qualified Data.HashMap.Strict as HMap +import qualified Data.Map.Strict as Map +import qualified Data.Text as T +import Data.Functor +import Data.Monoid +import Data.Aeson +import Data.Maybe +import Data.List +import Data.Char + +import Debug.Trace + +import Hakyll.Core.Compiler.Internal +import Hakyll.Core.Compiler +import Hakyll.Web.Sass +import Hakyll + +import qualified Network.URI.Encode as URI (encode) + +import qualified Skylighting as Sky + +import System.Environment +import System.Process +import System.Exit +import System.IO + +import Text.Pandoc.Walk (query, walkM) +import Text.Pandoc.Highlighting +import Text.Pandoc.Definition +import Text.Pandoc.Options +import Text.Sass.Functions + +readerOpts :: ReaderOptions +readerOpts = def { readerExtensions = pandocExtensions + , readerIndentedCodeClasses = ["amulet"] } + +writerOptions :: Compiler WriterOptions +writerOptions = do + syntaxMap <- loadAllSnapshots "syntax/*.xml" "syntax" + <&> foldr (Sky.addSyntaxDefinition . itemBody) Sky.defaultSyntaxMap + + pure $ defaultHakyllWriterOptions + { writerExtensions = extensionsFromList + [ Ext_tex_math_dollars + , Ext_tex_math_double_backslash + , Ext_latex_macros + ] <> writerExtensions defaultHakyllWriterOptions + , writerSyntaxMap = syntaxMap + , writerHighlightStyle = Just kate + } + +rssfeed :: FeedConfiguration +rssfeed + = FeedConfiguration { feedTitle = "Abigail's Blag: Latest articles" + , feedDescription = "" + , feedAuthorName = "Abigail Magalhães" + , feedAuthorEmail = "magalhaes.alcantara@pucpr.edu.br" + , feedRoot = "https://abby.how" + } + +conf :: Configuration +conf = def { destinationDirectory = ".site" + , storeDirectory = ".store" + , tmpDirectory = ".store/tmp" + , deployCommand = "./sync" } + +main :: IO () +main = hakyllWith conf $ do + let compiler = do + wops <- writerOptions + pandocCompilerWithTransformM readerOpts wops pure + + match "static/*" $ do + route idRoute + compile copyFileCompiler + + match "css/*.scss" $ do + route $ setExtension "css" + compile $ sassCompilerWith def { sassOutputStyle = SassStyleCompressed + , sassImporters = Nothing + } + + match "pages/**/*" $ do + route $ setExtension "html" + + compile $ do + id <- getUnderlying + meta <- getMetadata id + let category = takeWhile (/= '/') $ tail $ dropWhile (/= '/') (toFilePath id) + compiler + >>= loadAndApplyTemplate (fromFilePath ("templates/" ++ category ++ ".html")) (metaToContext meta) + >>= saveSnapshot "content" + + match "pages/*.html" $ do + route $ gsubRoute "pages/" (const "") + compile $ do + ppl <- loadAll "pages/people/*" + let (ppl_a, ppl_b) = explode ppl + + projects <- loadAll "pages/projects/*" + + let indexCtx = + listField "people-1" postCtx (return ppl_a) <> + listField "people-2" postCtx (return ppl_b) <> + listField "projects" postCtx (return projects) <> + constField "title" "Home" <> + defaultContext + getResourceBody + >>= applyAsTemplate indexCtx + >>= loadAndApplyTemplate "templates/default.html" indexCtx + >>= relativizeUrls + + match "pages/*.md" $ do + route $ gsubRoute "pages/" (const "") <> setExtension "html" + compile $ compiler + >>= loadAndApplyTemplate "templates/default.html" defaultContext + >>= relativizeUrls + + match "templates/*" $ compile templateBodyCompiler + +postCtx :: Context String +postCtx = dateField "date" "%B %e, %Y" + <> defaultContext + +pathFromTitle :: Metadata -> Routes +pathFromTitle meta = + let + declaredCategory = + case lookupString "category" meta of + Just s -> ((s ++ "/") ++) + Nothing -> ("posts/" <>) + + !titleString = + case lookupString "title" meta of + Just s -> s + Nothing -> error "post has no title?" + + title = filter (/= "") . map (filter isAlphaNum . map toLower) . words $ titleString + + (category, title') = + if | "or" `elem` title -> (declaredCategory, takeWhile (/= "or") title) + | ["a", "quickie"] `isPrefixOf` title -> (("quick/" ++), drop 2 title) + | otherwise -> (declaredCategory, title) + in + case lookupString "path" meta of + Just p -> constRoute (category (p <> ".html")) + Nothing -> constRoute (category (intercalate "-" title' <> ".html")) + +foldMapM :: (Monad w, Monoid m, Foldable f) => (a -> w m) -> f a -> w m +foldMapM k = foldr (\x y -> do { m <- k x; (m <>) <$> y }) (pure mempty) + +explode :: [a] -> ([a], [a]) +explode = go True where + go True (x:xs) = + let (as, bs) = go False xs + in (x:as, bs) + go False (x:xs) = + let (as, bs) = go True xs + in (as, x:bs) + go _ [] = ([], []) + +metaToContext :: Object -> Context String +metaToContext obj = HMap.foldrWithKey go mempty obj <> defaultContext where + go :: T.Text -> Value -> Context String -> Context String + go key (String x) ctx = constField (T.unpack key) (T.unpack x) <> ctx + go key (Array xs) ctx = listField (T.unpack key) (Context jsonContext) (traverse makeItem (foldr (:) [] xs)) + + jsonContext key idk item = do + let x = itemBody item + objToField key x + + objToField key x = + case x of + String x -> pure $ StringField (T.unpack x) + Object m -> objToField (tail (dropWhile (/= '.') key)) (fromJust (HMap.lookup (T.pack (takeWhile (/= '.') key)) m)) + Array xs -> do + is <- traverse makeItem (foldr (:) [] xs) + pure $ ListField (Context jsonContext) is \ No newline at end of file diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..5cf9222 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,6 @@ +resolver: lts-16.20 + +extra-deps: +- hakyll-sass-0.2.4@sha256:4d2fbd8b63f5ef15483fc6dda09e10eefd63b4f873ad38dec2a3607eb504a8ba,939 +- hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899 +- hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565 diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000..367ecc8 --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,33 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + hackage: hakyll-sass-0.2.4@sha256:4d2fbd8b63f5ef15483fc6dda09e10eefd63b4f873ad38dec2a3607eb504a8ba,939 + pantry-tree: + size: 217 + sha256: c03e74e71d010f009b8d972efc31fbd6dd25183e6d9afbec55f4b7f0d4a74b47 + original: + hackage: hakyll-sass-0.2.4@sha256:4d2fbd8b63f5ef15483fc6dda09e10eefd63b4f873ad38dec2a3607eb504a8ba,939 +- completed: + hackage: hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899 + pantry-tree: + size: 1448 + sha256: b25aeb947cb4e0b550f8a6f226d06503ef0edcb54712ad9cdd4fb2b05bf16c7c + original: + hackage: hsass-0.8.0@sha256:05fb3d435dbdf9f66a98db4e1ee57a313170a677e52ab3a5a05ced1fc42b0834,2899 +- completed: + hackage: hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565 + pantry-tree: + size: 11229 + sha256: 39b62f1f3f30c5a9e12f9c6a040d6863edb5ce81951452e649152a18145ee1bc + original: + hackage: hlibsass-0.1.10.1@sha256:08db56c633e9a83a642d8ea57dffa93112b092d05bf8f3b07491cfee9ee0dfa5,2565 +snapshots: +- completed: + size: 532177 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/20.yaml + sha256: 0e14ba5603f01e8496e8984fd84b545a012ca723f51a098c6c9d3694e404dc6d + original: lts-16.20 diff --git a/static/default-pfp.png b/static/default-pfp.png new file mode 100644 index 0000000..888361f Binary files /dev/null and b/static/default-pfp.png differ diff --git a/sync b/sync new file mode 100755 index 0000000..8b57c61 --- /dev/null +++ b/sync @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +rsync .site/ "${SYNC_SERVER}:/var/www/offtopia.abby.how/" -vuar0 diff --git a/templates/default.html b/templates/default.html new file mode 100644 index 0000000..310bd3c --- /dev/null +++ b/templates/default.html @@ -0,0 +1,46 @@ + + + + + + + $title$ + + + + + + + + + + + + $if(fastbuild)$ + + $endif$ + + + +
+ +
+ +
+

+ $body$ +
+ + diff --git a/templates/people.html b/templates/people.html new file mode 100644 index 0000000..0f48e2f --- /dev/null +++ b/templates/people.html @@ -0,0 +1,52 @@ +
+ + $if(pfp)$ + $name$'s profile picture + $else$ +
+ $name$ does not have a profile picture +
+ $endif$ + +
+ + $if(link)$ + $name$ + $else$ + $name$ + $endif$ + + + $if(pronouns)$ + $pronouns$ + $else$ + ?/? + $endif$ + +
+
+
+ $body$ + + $if(projects)$ +

$name$'s projects

+
    + $for(projects)$ +
  • +
    + + $name$ click to read more + + $desc$ +
    +
  • + $endfor$ +
+ $endif$ +
+
\ No newline at end of file diff --git a/templates/projects.html b/templates/projects.html new file mode 100644 index 0000000..e95c3c6 --- /dev/null +++ b/templates/projects.html @@ -0,0 +1,18 @@ +

+ $if(link)$ + $name$ + $else$ + $name$ + $endif$ +

+ +$if(participants)$ + + People involved: +$for(participants)$ +$name$$sep$, +$endfor$ + +$endif$ + +$body$ \ No newline at end of file