diff --git a/Haskell/blog/Html.hs b/Haskell/blog/Html.hs new file mode 100644 index 0000000..444117e --- /dev/null +++ b/Haskell/blog/Html.hs @@ -0,0 +1,16 @@ +module Html + ( Html + , Title + , Structure + , html_ + , p_ + , h1_ + , body_ + , head_ + , title_ + , append_ + , render + ) + where + +import Html.Internal diff --git a/Haskell/blog/Html/Internal.hs b/Haskell/blog/Html/Internal.hs new file mode 100644 index 0000000..512a358 --- /dev/null +++ b/Haskell/blog/Html/Internal.hs @@ -0,0 +1,84 @@ +module Html.Internal where + +-- * Types + +newtype Html = Html String + +newtype Structure = Structure String + +type Title = String + +-- * EDSL + +html_ :: Title -> Structure -> Html +html_ title content = Html + $ el "html" + $ el "head" + $ (el "title" $ escape title) ++ el "body" (getStructuredString content) + +body_ :: String -> Structure +body_ = Structure . el "body" + +head_ :: String -> Structure +head_ = Structure . el "head" + +title_ :: String -> Structure +title_ = Structure . el "title" + +p_ :: String -> Structure +p_ = Structure . el "p" . escape + +h1_ :: String -> Structure +h1_ = Structure . el "h1" . escape + +append_ :: Structure -> Structure -> Structure +append_ c1 c2 = Structure (getStructuredString c1 ++ getStructuredString c2) + + +ul_ :: [Structure] -> Structure +ul_ = list "ul" + +ol_ :: [Structure] -> Structure +ol_ = list "ol" + +code_ :: String -> Structure +code_ = Structure . el "pre" . escape + +-- * Render + +render :: Html -> String +render html = + case html of + Html str -> str + +-- * Utilities + +el :: String -> String -> String +el tag content = + "<" ++ tag ++ ">" ++ content ++ "" + +getStructuredString :: Structure -> String +getStructuredString content = + case content of + Structure str -> str + +escape :: String -> String +escape = + let + escapeChar c = + case c of + '<' -> "<" + '>' -> ">" + '&' -> "&" + '"' -> """ + '\'' -> "'" + _ -> [c] + in + concat . map escapeChar + +list :: String -> [Structure] -> Structure +list listType = + Structure + . el listType + . concat + . map (el "li" . getStructuredString) diff --git a/Haskell/blog/Main.hs b/Haskell/blog/Main.hs index 514609d..dcef8bd 100644 --- a/Haskell/blog/Main.hs +++ b/Haskell/blog/Main.hs @@ -1,48 +1,6 @@ module Main where -newtype Html = Html String - -newtype Structure = Structure String - -type Title = String - -el :: String -> String -> String -el tag content = - "<" ++ tag ++ ">" ++ content ++ "" - -html_ :: Title -> Structure -> Html -html_ title content = Html - $ el "html" - $ el "head" - $ (el "title" title) ++ el "body" (getStructuredString content) - -body_ :: String -> Structure -body_ = Structure . el "body" - -head_ :: String -> Structure -head_ = Structure . el "head" - -title_ :: String -> Structure -title_ = Structure . el "title" - -p_ :: String -> Structure -p_ = Structure . el "p" - -h1_ :: String -> Structure -h1_ = Structure . el "h1" - -append_ :: Structure -> Structure -> Structure -append_ c1 c2 = Structure (getStructuredString c1 ++ getStructuredString c2) - -render :: Html -> String -render html = - case html of - Html str -> str - -getStructuredString :: Structure -> String -getStructuredString content = - case content of - Structure str -> str +import Html main :: IO () main = putStrLn