aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMirek Kratochvil <exa.exa@gmail.com>2023-05-22 23:23:25 +0200
committerMirek Kratochvil <exa.exa@gmail.com>2023-05-22 23:23:25 +0200
commit3d34bd4a406296de9d711ef421f4f80a0b9b0efa (patch)
tree3736d2534f7663632e8809270c4b09e054ad6fcd
parent903a308167ac59b3736944f766f8672a9997e47e (diff)
downloadreploy-3d34bd4a406296de9d711ef421f4f80a0b9b0efa.tar.gz
reploy-3d34bd4a406296de9d711ef421f4f80a0b9b0efa.tar.bz2
even more
-rw-r--r--site.hs121
1 files changed, 121 insertions, 0 deletions
diff --git a/site.hs b/site.hs
new file mode 100644
index 0000000..826534e
--- /dev/null
+++ b/site.hs
@@ -0,0 +1,121 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+import Control.Monad (unless, when)
+import Control.Monad.IO.Class
+import Control.Monad.Trans.State.Lazy
+import Data.Default (def)
+import Data.Foldable (traverse_)
+import Data.List.Extra (stripSuffix)
+import qualified Data.Map as M
+import Data.Maybe (isJust)
+import qualified Data.Text as T
+import qualified Data.Text.Encoding
+import qualified Data.Text.IO as TIO
+import qualified Data.Yaml as Y
+import Hakyll.Core.Util.File (getRecursiveContents, makeDirectories)
+import Lens.Micro
+import Lens.Micro.Aeson
+import Lens.Micro.Mtl
+import Lens.Micro.TH
+import System.Environment (getArgs)
+import System.FilePath ((</>), splitPath)
+import Text.Pandoc.Class (runIOorExplode)
+import qualified Text.Pandoc.Definition
+import qualified Text.Pandoc.Extensions
+import Text.Pandoc.Options (ReaderOptions(..))
+import Text.Pandoc.Readers.Markdown (readMarkdown)
+
+import Debug.Trace
+
+io :: MonadIO m => IO a -> m a
+io = liftIO
+
+just _ (Just val) = val
+just err Nothing = error ("Missing: " ++ err)
+
+data SiteState =
+ SiteState
+ { _pages :: M.Map FilePath ( FilePath
+ , Y.Value
+ , Text.Pandoc.Definition.Pandoc -- loc -> (source, meta, markdown)
+ )
+ , _redirects :: M.Map FilePath FilePath -- from -> to
+ , _htags :: M.Map [String] [FilePath] -- tag sequence -> tagged locs
+ , _installs :: M.Map FilePath FilePath -- file hash -> install location
+ , _templates :: M.Map FilePath () -- TODO mustache templates
+ , _outputDir :: FilePath
+ }
+ deriving (Show)
+
+makeLenses ''SiteState
+
+emptySiteState out =
+ SiteState
+ { _pages = M.empty
+ , _redirects = M.empty
+ , _htags = M.empty
+ , _installs = M.empty
+ , _templates = M.empty
+ , _outputDir = out
+ }
+
+type Site a = StateT SiteState IO a
+
+hasSuffix s = isJust . stripSuffix s
+
+sourcePages :: FilePath -> Site ()
+sourcePages fp = do
+ links <-
+ io $ filter (hasSuffix ".md" . last . splitPath) <$>
+ getRecursiveContents (pure . const False) fp
+ traverse_ loadPage (map (fp </>) links)
+
+markdownReadOpts =
+ def
+ { readerExtensions =
+ Text.Pandoc.Extensions.enableExtension
+ Text.Pandoc.Extensions.Ext_smart
+ Text.Pandoc.Extensions.pandocExtensions
+ }
+
+loadPage :: FilePath -> Site ()
+loadPage fp = do
+ txt <- io $ TIO.readFile fp
+ (T.take 4 txt == "---\n") `unless`
+ error ("metadata block start missing in " ++ fp)
+ let (meta, markdown) = T.breakOn "\n---\n" (T.drop 4 txt)
+ T.null meta `when` error ("metadata block bad in " ++ fp)
+ yml <- Y.decodeThrow $ Data.Text.Encoding.encodeUtf8 meta
+ md <- io $ runIOorExplode $ readMarkdown markdownReadOpts (T.drop 5 markdown)
+ let mount =
+ T.unpack . just ("mount point of " ++ fp) $ yml ^? key "title" . _String
+ pages %= M.insert mount (fp, yml, md)
+
+sourceTemplates :: FilePath -> Site ()
+sourceTemplates _ = pure ()
+
+installPage :: FilePath -> Site ()
+installPage = undefined
+
+installFile :: FilePath -> Site FilePath
+installFile = undefined
+
+makeRedirect :: FilePath -> FilePath -> Site ()
+makeRedirect = undefined
+
+makeRedirects :: Site ()
+makeRedirects = undefined
+
+renderTag :: [String] -> Site ()
+renderTag = undefined
+
+renderTags :: Site ()
+renderTags = undefined
+
+main = do
+ [targetDir] <- getArgs
+ flip runStateT (emptySiteState targetDir) $ do
+ traverse sourceTemplates ["templates"]
+ traverse sourcePages ["external"]
+ get >>= io . print