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