Studio
Studio converts markdown files to organized HTML pages—having the flexibility to change templates and add custom CSS and JavaScript. With static webpages your site is fast, secure and easy to deploy.
I built this program during summer 2014. The purpose of this program was to improve my Haskell knowledge and to start posting online. I tried other static site generators but found they didn't meet my needs.
At the time, I was having fun doing code golf, so I set a goal to create a static-site generator in 100 lines of Haskell. I reached my goal, sacrificing all of the readability. I later corrected that, adding spaces and expanding the equations.
.md text files are the inputs to studio. I used markdown which is a standard so you can add titles, links and images. We take the titles in the text files and create a table of contents for a main page, generating a link for each article.
Haskell is a functional language, so I had to separate pure functions from the parts that touch the real world. It is also a dense language; you can do a lot of modifications in a few lines of code compared to other languages. We divide this program into 3 steps.
I made a data structure called Page which has the file path and date.
data Page = Page { title :: FilePath -- Path to words
, static :: [FilePath] -- List of static files
, date :: [String] -- Month,day,year
} deriving (Show)
Create and order pages
Each folder in a directory is added to a list and sent to the getPages function, this returns an IO with the pages seen inside. GetStatic file creates a list of extra js or css files linked to the article. This offered some flexibility to have custom assets for an article
getPages :: [FilePath] -> IO [Page]
getPages = mapM (\x -> do static <- getStatic ("Articles/" ++ x)
date <- getPageDate ("Articles/" ++ x ++ "/words.md")
return (Page x static date))
Create html from template and pages
To write a page required a template in the form of a HTML and a Page from above. Pandoc library converted the markdown text files to HTML
writePage :: String -> Page -> IO ()
writePage template page = do
let year = last $ date page
let urlTitle = urlConvert (title page)
mdArt <- readFile ("Articles/" ++ urlTitle ++ "/words.md")
let pandocArt = readMarkdown def mdArt
let html = writeHtmlString (siteOptions template) pandocArt
createDirectoryIfMissing True $ "Output/" ++ year ++ "/" ++ urlTitle
writeFile ("Output/" ++ year ++ "/" ++ urlTitle ++ "/index.html") html
Write table of contents
The table of contents also use the template but also include some html to make it look pretty
writeTOC :: String -> [Page] -> IO ()
writeTOC template pages = do
list <- mapM getItem pages
let html = writeHtmlString (siteOptions template) (tocWrap list)
createDirectoryIfMissing True $ "Output/archives"
writeFile "Output/archives/index.html" html
That is most likely 80% of the functions of the studio. With most other things being moving files around. Thank you for reading. You can find the code here