packages feed

gemoire-1.0.0: src/Gemoire/Converter/Web.hs

{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      :  Gemoire.Converter.Web
-- Copyright   :  (c) 2025 Sena
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  contact@sena.pink
-- Stability   :  stable
-- Portability :  portable
--
-- Default configuration and templates for Gemini to HTML conversion
module Gemoire.Converter.Web
    ( -- * Defaults
      defWebConversion
    , escapeContent
    , escapeAttr
    , defDocument
    , defText
    , defLink
    , defH1
    , defH2
    , defH3
    , defList
    , defListItem
    , defQuote
    , defPre
    ) where

import Data.HashMap.Strict (empty)
import Data.Text (Text)
import qualified Data.Text as T

import Gemoire.Converter.Types (Conversion (..))
import Gemoire.Template (Template, template)

defWebConversion :: Conversion
defWebConversion =
    Conversion
        { targetExtension = ".html"
        , escaper = escapeContent
        , preEscaper = escapeContent
        , attrEscaper = escapeAttr
        , documentTemplate = defDocument
        , textTemplate = defText
        , linkTemplate = defLink
        , h1Template = defH1
        , h2Template = defH2
        , h3Template = defH3
        , listTemplates = (defList, defListItem)
        , quoteTemplate = defQuote
        , preTemplate = defPre
        , rewriteRules = []
        , conversionOverrides = empty
        }

escapeContent :: Text -> Text
escapeContent = T.replace ">" "&gt;" . T.replace "<" "&lt;" . T.replace "&" "&amp;"

escapeAttr :: Text -> Text
escapeAttr = T.replace "'" "&#39;" . T.replace "\"" "&quot;" . T.replace "&" "&amp;"

defDocument :: Template
defDocument =
    template . T.unlines $
        [ "<!DOCTYPE html>"
        , "<html>"
        , "  <head>"
        , "    <title>{&title:fname&}</title>"
        , "  </head>"
        , "  <body>"
        , ""
        , "{$body$}"
        , ""
        , "  </body>"
        , "</html>"
        ]

defText :: Template
defText = template "<p>{$text$}</p>"

defLink :: Template
defLink = template "<a href=\"{$link$}\">{&description:link&}</a>"

defH1 :: Template
defH1 = template "<h1>{$text$}</h1>"

defH2 :: Template
defH2 = template "<h2>{$text$}</h2>"

defH3 :: Template
defH3 = template "<h3>{$text$}</h3>"

defList :: Template
defList =
    template . T.intercalate "\LF" $
        [ "<ul>"
        , "{$items$}"
        , "</ul>"
        ]

defListItem :: Template
defListItem = template "  <li>{$text$}</li>"

defQuote :: Template
defQuote =
    template . T.intercalate "\LF" $
        [ "<blockquote>"
        , "  {$text$}"
        , "</blockquote>"
        ]

defPre :: Template
defPre =
    template . T.intercalate "\LF" $
        [ "<pre title=\"{$alt$}\">"
        , "{$text$}"
        , "</pre>"
        ]