@@ -12,6 +12,8 @@ import System.IO (SeekMode(RelativeSeek))
1212import Hakyll.Web.Html.RelativizeUrls (relativizeUrls )
1313import Hakyll.Web.Template.Context (defaultContext )
1414import Data.Maybe (isJust , fromJust , fromMaybe )
15+ import Text.Pandoc as Pandoc
16+ import qualified Data.Text as T
1517
1618--------------------------------------------------------------------------------------------------------
1719-- MAIN GENERATION -------------------------------------------------------------------------------------
@@ -176,7 +178,7 @@ main = hakyll $ do
176178 route idRoute
177179 compile $ do
178180 sponsors <- buildBoilerplateCtx (Just " Haskell Interlude" )
179- ctx <- podcastCtx . sortOn podcastOrd <$> loadAll (" podcast/*/index.markdown" .&&. hasVersion " raw" )
181+ ctx <- podcastListCtx . sortOn podcastOrd <$> loadAll (" podcast/*/index.markdown" .&&. hasVersion " raw" )
180182
181183 makeItem " "
182184 >>= loadAndApplyTemplate " templates/podcast/list.html" ctx
@@ -208,12 +210,18 @@ main = hakyll $ do
208210 match " podcast/*/transcript.markdown" $ compile pandocCompiler
209211 match " podcast/*/links.markdown" $ compile pandocCompiler
210212
213+ -- Description compiler --------------------------------------------------------------------------------
214+ --
215+ -- This identifier compiles the body the file to plain text, to be used in the OpenGraph description field
216+
217+ match " **/*.markdown" $ version " description" $ compile pandocPlainCompiler
218+
211219-- home page -------------------------------------------------------------------------------------------
212220 create [" index.html" ] $ do
213221 route idRoute
214222 compile $ do
215223 sponsors <- buildBoilerplateCtx (Just " Haskell Foundation" )
216- podcastsCtx <- podcastCtx . take 1 . reverse . sortOn podcastOrd <$> loadAll (" podcast/*/index.markdown" .&&. hasVersion " raw" )
224+ podcastsCtx <- podcastListCtx . take 1 . reverse . sortOn podcastOrd <$> loadAll (" podcast/*/index.markdown" .&&. hasVersion " raw" )
217225 careers <- loadAll @ String " careers/*.markdown"
218226 careersCtx <- careersCtx . reverse <$> loadAll " careers/*.markdown"
219227 announces <- take 1 <$> (recentFirst =<< loadAll @ String " news/*/**.markdown" )
@@ -304,14 +312,18 @@ buildBoilerplateCtx mtitle = boilerPlateCtx mtitle . sortOn itemIdentifier <$> l
304312-- We set the 'title' based on the title metadata for the item, if present,
305313-- or use the passed in Maybe title, if it is a Just, or "No title" if not.
306314boilerPlateCtx :: Maybe String -> [Item String ] -> Context String
307- boilerPlateCtx mtitle sponsors =
308- listField " monads" defaultContext (ofMetadataField " level" " Monad" sponsors) <>
309- listField " applicatives" defaultContext (ofMetadataField " level" " Applicative" sponsors) <>
310- listField " functors" defaultContext (ofMetadataField " level" " Functor" sponsors) <>
311- field " title" ( \ item -> do
315+ boilerPlateCtx mtitle sponsors = mconcat
316+ [ listField " monads" defaultContext (ofMetadataField " level" " Monad" sponsors)
317+ , listField " applicatives" defaultContext (ofMetadataField " level" " Applicative" sponsors)
318+ , listField " functors" defaultContext (ofMetadataField " level" " Functor" sponsors)
319+ , field " title" $ \ item -> do
312320 metadata <- getMetadata (itemIdentifier item)
313- return $ fromMaybe (fromMaybe " No title" mtitle) $ lookupString " title" metadata) <>
314- defaultContext
321+ return $ fromMaybe (fromMaybe " No title" mtitle) $ lookupString " title" metadata
322+ , field " description" $ \ item -> do
323+ desc <- loadBody (setVersion (Just " description" ) (itemIdentifier item))
324+ if null desc then noResult " Description empty" else pure (escapeHtml desc)
325+ , defaultContext
326+ ]
315327
316328-- affiliates ------------------------------------------------------------------------------------------
317329-- | Partition affiliates into affiliates and pending
@@ -385,8 +397,8 @@ whoWeAreCtx people =
385397 ) items'
386398
387399-- podcast ---------------------------------------------------------------------------------------------
388- podcastCtx :: [Item String ] -> Context String
389- podcastCtx episodes =
400+ podcastListCtx :: [Item String ] -> Context String
401+ podcastListCtx episodes =
390402 listField " episodes" defaultContext (return $ reverse episodes) <>
391403 defaultContext
392404
@@ -439,3 +451,39 @@ sortFromMetadataField field = sortByM (\a b -> do
439451 b' <- getMetadataField (itemIdentifier b) field
440452 return $ compare a' b'
441453 )
454+
455+ --------------------------------------------------------------------------------------------------------
456+ -- Pandoc extensions -----------------------------------------------------------------------------------
457+ --------------------------------------------------------------------------------------------------------
458+
459+ -- | Read a page render using pandoc, rendering its first paragraph as a plain string
460+ --
461+ -- Cargo-culted from pandocCompiler
462+ pandocPlainCompiler :: Compiler (Item String )
463+ pandocPlainCompiler = cached " pandocPlainCompiler" $
464+ getResourceBody >>=
465+ readPandocWith defaultHakyllReaderOptions >>=
466+ pure . fmap firstPara >>=
467+ pure . writePandocPlainWith defaultHakyllWriterOptions
468+
469+ -- | Write a document's first paragraph (as plain text) using pandoc, with the supplied options
470+ --
471+ -- Cargo-culted from hakyll’s writePandocWith
472+ writePandocPlainWith :: Pandoc. WriterOptions -- ^ Writer options for pandoc
473+ -> Item Pandoc. Pandoc -- ^ Document to write
474+ -> Item String -- ^ Resulting HTML
475+ writePandocPlainWith wopt (Item itemi doc) =
476+ case runPure $ writePlain wopt doc of
477+ Left err -> error $ " Hakyll.Web.Pandoc.writePandocWith: " ++ show err
478+ Right item' -> Item itemi $ T. unpack item'
479+
480+
481+ -- | Finds the first regular paragraph of a Pandoc doc
482+ firstPara :: Pandoc. Pandoc -> Pandoc. Pandoc
483+ firstPara (Pandoc. Pandoc meta blocks) = Pandoc. Pandoc meta (go blocks)
484+ where
485+ go :: [Pandoc. Block ] -> [Pandoc. Block ]
486+ go [] = [] -- I tried to use noResult "firstPara: No plain text found", but it made the build fail
487+ go (block@ (Pandoc. Plain _) : _) = [block]
488+ go (block@ (Pandoc. Para _) : _) = [block]
489+ go (_ : bs) = go bs
0 commit comments