Compare commits
2 Commits
c34fa83504
...
62461dc616
Author | SHA1 | Date |
---|---|---|
Yann Esposito (Yogsototh) | 62461dc616 | |
Yann Esposito (Yogsototh) | 4df922b475 |
62
Shakefile.hs
62
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:<footer>@@"
|
||||
, ""
|
||||
, "/Any comment? Click on my email below and I'll add it./"
|
||||
, ""
|
||||
, "| author | [[mailto:Yann Esposito <yann@esposito.host>?subject=yblog: " <> (postTitle bp) <> "][Yann Esposito <yann@esposito.host>]] |"
|
||||
, "| 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:</footer>@@"
|
||||
]
|
||||
|
||||
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)
|
||||
|
||||
|
@ -301,4 +355,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"]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<title>{{title}}</title>
|
||||
<meta name="generator" content="ystgen">
|
||||
<meta name="author" content="Yann Esposito">
|
||||
<meta name="keywords" content="programming">
|
||||
<meta name="keywords" content="{{#tags}}{{.}} {{/tags}}">
|
||||
<link rel="stylesheet" href="/css/y.css"/>
|
||||
<link rel="alternate" type="application/rss+xml" href="/rss.xml" />
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
|
@ -34,13 +34,24 @@
|
|||
</div>
|
||||
<div id="content">
|
||||
|
||||
<div class="abstract">{{description}}</div>
|
||||
|
||||
{{{ body }}}
|
||||
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
<div class="content">
|
||||
<footer><i>Any comment? Click on my email below and I'll add it.</i>
|
||||
<table><tr><td>author</td><td><span class="author"><a href="mailto:Yann Esposito <yann@esposito.host>?subject=yblog: Yann Esposito's Website">Yann Esposito <yann@esposito.host></a></span></td></tr> <tr><td>tags</td><td> <span class="keywords"><code>#programming</code></span></td></tr> <tr><td>rss</td><td><div class="rss"><a rel="alternate" type="application/rss+xml" href="/rss.xml">RSS</a> (<a href="https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fher.esy.fun%2Frss.xml">validate</a>)</div></td></tr> <tr><td>size</td><td><div class="web-file-size">XXK (html XXK, css XXK, img XXK)</div></td></tr> <tr><td>gz</td><td><div class="gzweb-file-size">XXK (html XXK, css XXK, img XXK)</div></td></tr> <tr><td>generated</td><td><div class="date">2020-06-23 00:04:33</div></td></tr> <tr><td>gen-with</td><td><div class="creator"><a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noopener noreferrer">Emacs 26.3</a>, <a href="http://spacemacs.org" target="_blank" rel="noopener noreferrer">Spacemacs 0.300.0</a>, <a href="http://orgmode.org" target="_blank" rel="noopener noreferrer">Org Mode 9.3.6</a></div></td></tr> <tr><td>src</td><td><a href="https://gitea.esy.fun/yogsototh/her.esy.fun" target="_blank" rel="noopener noreferrer">Website source code</a></td></tr> <tr><td>org-file</td><td><a href="/index.org">/index.org</a></td></tr></table></footer><nav><a href="/index.html">Home</a> | <a href="/archive.html">Posts</a> | <a href="/slides.html">Slides</a> | <a href="/about-me.html">About</a>
|
||||
<table>
|
||||
<tr><td>author</td><td><span class="author"><a href="mailto:Yann Esposito <yann@esposito.host>?subject=yblog: Yann Esposito's Website">Yann Esposito <yann@esposito.host></a></span></td></tr>
|
||||
<tr><td>tags</td><td> <span class="keywords"><code>{{#tags}}#{{.}} {{/tags}}</code></span></td></tr>
|
||||
<tr><td>rss</td><td><div class="rss"><a rel="alternate" type="application/rss+xml" href="/rss.xml">RSS</a> (<a href="https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fher.esy.fun%2Frss.xml">validate</a>)</div></td></tr>
|
||||
<tr><td>size</td><td><div class="web-file-size">XXK (html XXK, css XXK, img XXK)</div></td></tr>
|
||||
<tr><td>gz</td><td><div class="gzweb-file-size">XXK (html XXK, css XXK, img XXK)</div></td></tr>
|
||||
<tr><td>generated</td><td><div class="date">2020-06-23 00:04:33</div></td></tr>
|
||||
<tr><td>gen-with</td><td><div class="creator"><a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noopener noreferrer">Emacs 26.3</a>, <a href="http://spacemacs.org" target="_blank" rel="noopener noreferrer">Spacemacs 0.300.0</a>, <a href="http://orgmode.org" target="_blank" rel="noopener noreferrer">Org Mode 9.3.6</a></div></td></tr>
|
||||
<tr><td>src</td><td><a href="https://gitea.esy.fun/yogsototh/her.esy.fun" target="_blank" rel="noopener noreferrer">Website source code</a></td></tr>
|
||||
<tr><td>org-file</td><td><a href="/index.org">/index.org</a></td></tr></table></footer><nav><a href="/index.html">Home</a> | <a href="/archive.html">Posts</a> | <a href="/slides.html">Slides</a> | <a href="/about-me.html">About</a>
|
||||
<span class="details">
|
||||
(<a href="https://gitea.esy.fun/yogsototh">code</a>
|
||||
<a href="https://espial.esy.fun/u:yogsototh">bookmarks</a>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
{{{body}}}
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="postamble" class="status">
|
||||
<div id="old2_postamble" class="status">
|
||||
<div class="content">
|
||||
<footer>
|
||||
<i>Any comment? Click on my email below and I'll add it.</i>
|
||||
|
|
Loading…
Reference in New Issue