@@ -16,7 +16,9 @@ import Data.Text (Text)
1616import Data.Text qualified as T
1717import Data.Text.Encoding qualified as TE
1818import Data.Text.IO qualified as TIO
19+ import Data.Text.Lazy qualified as TL
1920import Data.Time (defaultTimeLocale , formatTime )
21+ import Lucid
2022
2123generateDomainCssClass :: Text -> Text
2224generateDomainCssClass domain =
@@ -84,39 +86,41 @@ renderAll blogroll = do
8486 putStrLn " Generated index.html (25 recent) and all.html"
8587
8688renderHtml :: [FeedEntry ] -> Text -> Text -> Maybe Text -> Text
87- renderHtml entries title faviconCss maybeFontBase64 =
88- let entriesHtml = T. concat $ map renderEntry entries
89- fontFace = case maybeFontBase64 of
90- Just fontBase64 ->
91- " " " @font-face {
92- font-family: 'IBM Plex Sans';
93- src: url(data:font/woff2;base64," " "
94- <> fontBase64
95- <> " " " ) format('woff2');
96- font-weight: 400;
97- }" " "
98- Nothing ->
99- " " " @font-face {
100- font-family: 'IBM Plex Sans';
101- src: url('IBMPlexSans-Regular.woff2') format('woff2');
102- font-weight: 400;
103- }" " "
104- in " " "
105- <!DOCTYPE html>
106- <html>
107- <head>
108- <meta name=" viewport" content=" width= device- width, initial- scale= 1.0 " >
109- <title>RSS Reader</title>
110- <style>
111- " " "
112- <> fontFace
113- <> " " "
89+ renderHtml entries pageTitle faviconCss maybeFontBase64 =
90+ TL. toStrict $ renderText $ doctype_ <> html_ (do
91+ head_ (do
92+ meta_ [name_ " viewport" , content_ " width=device-width, initial-scale=1.0" ]
93+ title_ " RSS Reader"
94+ style_ [] (toHtmlRaw $ generateStyles faviconCss maybeFontBase64))
95+ body_ (do
96+ h1_ (toHtml pageTitle)
97+ ul_ (do
98+ mapM_ renderEntry entries
99+ li_ (a_ [href_ " all.html" ] " See all" ))))
100+ where
101+ generateStyles :: Text -> Maybe Text -> Text
102+ generateStyles css maybeFontB64 =
103+ let fontFace = case maybeFontB64 of
104+ Just fontBase64 ->
105+ " " " @font-face {
106+ font-family: 'IBM Plex Sans';
107+ src: url(data:font/woff2;base64," " "
108+ <> fontBase64
109+ <> " " " ) format('woff2');
110+ font-weight: 400;
111+ }" " "
112+ Nothing ->
113+ " " " @font-face {
114+ font-family: 'IBM Plex Sans';
115+ src: url('IBMPlexSans-Regular.woff2') format('woff2');
116+ font-weight: 400;
117+ }" " "
118+ in fontFace
119+ <> " " "
114120 body {
115121 font-family: 'IBM Plex Sans', -apple-system, sans-serif;
116122 max-width: 800px;
117123 margin: 0 auto;
118- /* padding-left: 0.5em; */
119- /* padding-right: 0.5em; */
120124 color: #333;
121125 display: flex;
122126 flex-flow: column;
@@ -154,36 +158,16 @@ renderHtml entries title faviconCss maybeFontBase64 =
154158 padding-left: 0.5em;
155159 }
156160 " " "
157- <> faviconCss
158- <> " " "
159- </style>
160- </head>
161- <body>
162- <h1>" " "
163- <> title
164- <> " " " </h1>
165- <ul>
166- " " "
167- <> entriesHtml
168- <> " " "
169- <li><a href=\" all.html\" >See all</a></li>
170- </ul>
171- </body>
172- </html>
173- " " "
174- where
161+ <> css
162+
163+ renderEntry :: FeedEntry -> Html ()
175164 renderEntry entry =
176- T. concat
177- [ " <li><div><a href=\" " ,
178- T. pack $ show $ entryLink entry,
179- " \" class=\" " ,
180- generateDomainCssClass (extractDomain entry. entrySiteUrl),
181- " \" >" ,
182- entryTitle entry,
183- " </a><span class=\" source\" >(" ,
184- extractDomain entry. entrySiteUrl,
185- " )</span></div>" ,
186- " <div class=\" date\" >" ,
187- T. pack $ formatTime defaultTimeLocale " %Y-%m-%d" entry. entryDate,
188- " </div></li>"
189- ]
165+ li_ (do
166+ div_ (do
167+ a_
168+ [ href_ (T. pack $ show $ entryLink entry),
169+ class_ (generateDomainCssClass (extractDomain entry. entrySiteUrl))
170+ ]
171+ (toHtml $ entryTitle entry)
172+ span_ [class_ " source" ] (toHtml $ " (" <> extractDomain entry. entrySiteUrl <> " )" ))
173+ div_ [class_ " date" ] (toHtml $ T. pack $ formatTime defaultTimeLocale " %Y-%m-%d" entry. entryDate))
0 commit comments