{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}

module Lucid.Hyperscript.QuasiQuoter (_hs, __) where

import Data.Text (Text(..))
import qualified Data.Text as Text
import GHC.Exts (IsString (..))
import qualified Language.Haskell.TH as TH
import Language.Haskell.TH.Quote ( QuasiQuoter(QuasiQuoter) )
import Lucid (script_, toHtml, type_)
import Lucid.Base (makeAttribute)

__ :: QuasiQuoter
__ :: QuasiQuoter
__ =
  (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((\Text
text -> [|makeAttribute "_" text|]) (Text -> Q Exp) -> (String -> Text) -> String -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
processString)
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use __ as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use __ as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use __ as a dec")

_hs :: QuasiQuoter
_hs :: QuasiQuoter
_hs =
  (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    ((\Text
text -> [|script_ [type_ "text/hyperscript"] $ toHtml text|]) (Text -> Q Exp) -> (String -> Text) -> String -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
processString)
    (String -> String -> Q Pat
forall a. HasCallStack => String -> a
error String
"Cannot use _hs as a pattern")
    (String -> String -> Q Type
forall a. HasCallStack => String -> a
error String
"Cannot use _hs as a type")
    (String -> String -> Q [Dec]
forall a. HasCallStack => String -> a
error String
"Cannot use _hs as a dec")

processString :: String -> Text
processString :: String -> Text
processString = Text -> Text
Text.strip (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
removeCRs (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack
  where
    removeCRs :: Text -> Text
removeCRs = (Char -> Bool) -> Text -> Text
Text.filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\r')