hyakko 0.6.1 → 0.6.2
raw patch · 3 files changed
+68/−48 lines, 3 filesdep +aesondep +unordered-containersdep −containers
Dependencies added: aeson, unordered-containers
Dependencies removed: containers
Files
- hyakko.cabal +6/−3
- resources/languages.json +7/−0
- src/Hyakko.lhs +55/−45
hyakko.cabal view
@@ -1,5 +1,5 @@ name: hyakko-version: 0.6.1+version: 0.6.2 cabal-version: >= 1.6 build-type: Simple license: MIT@@ -17,6 +17,8 @@ quick-and-dirty, hundred-line-long, literate-programming-style documentation generator. data-files:+ -- language definition file+ resources/languages.json -- linear layout files resources/linear/hyakko.html resources/linear/hyakko.css@@ -62,14 +64,15 @@ ghc >= 7, filepath >= 1.2, regex-pcre >= 0.9,- containers >= 0.4,+ unordered-containers >= 0.2, directory >= 1, pandoc >= 1.10, bytestring >= 0.9, text >= 0.11, highlighting-kate >= 0.5, blaze-html >= 0.5,- cmdargs >= 0.10+ cmdargs >= 0.10,+ aeson >= 0.6 hs-source-dirs: src ghc-options: -O2 -Wall main-is: Hyakko.lhs
+ resources/languages.json view
@@ -0,0 +1,7 @@+{ ".hs": {"name": "haskell", "symbol": "--"}+, ".lhs": {"name": "haskell", "symbol": "--", "literate": true, "litSymbol": ">"}+, ".coffee": {"name": "coffee", "symbol": "#"}+, ".js": {"name": "javascript", "symbol": "//"}+, ".py": {"name": "python", "symbol": "#"}+, ".rb": {"name": "ruby", "symbol": "#"}+}
src/Hyakko.lhs view
@@ -27,7 +27,8 @@ There is a ["literate" style](http://www.haskell.org/haskellwiki/Literate_programming) of Haskell, only one supported at this time, but other literate styles can be added-fairly easily.+fairly easily via a [separate languages+file](https://github.com/sourrust/hyakko/blob/master/resources/languages.json). > {-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-} @@ -35,8 +36,9 @@ > import Text.Markdown -> import Data.Map (Map)-> import qualified Data.Map as M+> import Data.Aeson+> import Data.HashMap.Strict (HashMap)+> import qualified Data.HashMap.Strict as M > import Data.ByteString.Lazy.Char8 (ByteString) > import qualified Data.ByteString.Lazy.Char8 as L > import Data.Text (Text)@@ -45,6 +47,7 @@ > import Data.List (sort) > import Data.Maybe (fromJust, isNothing) > import Data.Version (showVersion)+> import Control.Applicative ((<$>), (<*>), empty) > import Control.Monad (filterM, (>=>), forM, forM_, unless) > import qualified Text.Blaze.Html as B > import Text.Blaze.Html.Renderer.Utf8 (renderHtml)@@ -58,6 +61,7 @@ > , createDirectoryIfMissing > , copyFile > )+> import System.IO.Unsafe (unsafePerformIO) > import System.FilePath ( takeBaseName > , takeExtension > , takeFileName@@ -102,7 +106,7 @@ individual **section** for it. Each section is Map with `docText` and `codeText` properties, and eventuall `docsHtml` and `codeHtml` as well. -> inSections :: [Text] -> ByteString -> [Map String Text]+> inSections :: [Text] -> ByteString -> Sections > inSections xs r = > let sections = sectionOff "" "" xs > in map M.fromList sections@@ -139,11 +143,11 @@ sanitates the file — turing literate into regular source and take out shebangs — then feed it to `inSections`, and finally return the results. -> parse :: Maybe (Map String ByteString) -> Text -> [Map String Text]+> parse :: Maybe Language -> Text -> Sections > parse Nothing _ = [] > parse (Just src) code =-> inSections (newlines line (M.lookup "literate" src) True)-> (src M.! "comment")+> inSections (newlines line (literate src) True)+> ("^\\s*" ++* symbol src ++* "\\s?") > where line :: [Text] > line = filter ((/=) "#!" . T.take 2) $ T.lines code @@ -151,12 +155,12 @@ style language. If it is normal, `newlines` for returns the same list of `Text` that was passed in. -> newlines :: [Text] -> Maybe ByteString -> Bool -> [Text]+> newlines :: [Text] -> Maybe Bool -> Bool -> [Text] > newlines [] _ _ = [] > newlines xs Nothing _ = xs > newlines (x:xs) lit isText =-> let s = src M.! "symbol"-> r = "^" ++* (src M.! "symbol2") ++* "\\s?"+> let s = symbol src+> r = "^" ++* (fromJust $ litSymbol src) ++* "\\s?" > r1 = L.pack "^\\s*$" > (x', y) = if T.unpack x =~ r then > (replace r x "", False)@@ -172,17 +176,17 @@ > where insert :: Bool -> Bool -> Text -> (Text, Bool) > insert True True _ = (T.pack . L.unpack-> $ src M.! "symbol", True)+> $ symbol src, True) > insert True False _ = ("", False) > insert False _ y = (y, True) Highlights the current file of code, using **Kate**, and outputs the the highlighted html to its caller. -> highlight :: FilePath -> [Map String Text] -> [Text]+> highlight :: FilePath -> Sections -> [Text] > highlight src section = > let language = fromJust $ getLanguage src-> langName = L.unpack $ language M.! "name"+> langName = L.unpack $ name_ language > input = map (\x -> T.unpack $ x M.! "codeText") section > html = B.toHtml . K.formatHtmlBlock K.defaultFormatOpts > . K.highlightAs langName@@ -192,7 +196,7 @@ `mapSections` is used to insert the html parts of the mapped sections of text into the corresponding keys of `docsHtml` and `codeHtml`. -> mapSections :: [Map String Text] -> [Text] -> [Map String Text]+> mapSections :: Sections -> [Text] -> Sections > mapSections section highlighted = > let docText s = toHTML . T.unpack $ s M.! "docsText" > codeText i = highlighted !! i@@ -225,7 +229,7 @@ Depending on the layout type, `sectionTemplate` will produce the HTML that will be hooked into the templates layout theme. -> sectionTemplate :: [Map String Text]+> sectionTemplate :: Sections > -> Maybe String > -> [Int] > -> [(String, String)]@@ -281,7 +285,7 @@ template found in `resources/linear/hyakko.html` or `resources/parallel/hyakko.html`. -> generateHTML :: Hyakko -> FilePath -> [Map String Text] -> IO ()+> generateHTML :: Hyakko -> FilePath -> Sections -> IO () > generateHTML opts src section = do > let title = takeFileName src > dest = destination (output opts) src@@ -311,6 +315,33 @@ Helpers & Setup --------------- +The `Sections` type is just an alias to keep type signatures short.++> type Sections = [HashMap String Text]++Alias `Languages`, for the multiple different languages inside the+`languages.json` file.++> type Languages = HashMap String Language++Better data type for language info — compared to the `Object` data type in+`Aeson`.++> data Language =+> Language { name_ :: ByteString+> , symbol :: ByteString+> , literate :: Maybe Bool+> , litSymbol :: Maybe ByteString+> }++> instance FromJSON Language where+> parseJSON (Object o) = Language+> <$> o .: "name"+> <*> o .: "symbol"+> <*> o .:? "literate"+> <*> o .:? "litSymbol"+> parseJSON _ = empty+ Infix functions for easier concatenation with Text and ByteString. > (++.) :: Text -> Text -> Text@@ -329,44 +360,23 @@ > (_, _, rp) = str =~ reg :: (String, String, String) > in y ++. (T.pack rp) +> readLanguageFile :: IO ByteString+> readLanguageFile = getDataFileName "resources/languages.json"+> >>= L.readFile A list of the languages that Hyakko supports, mapping the file extension to the name of the Pygments lexer and the symbol that indicates a comment. To add another language to Hyakko's repertoire, add it here. -> languages :: Map String (Map String ByteString)+> languages :: Languages > languages =-> let hashSymbol = ("symbol", "#")-> language = M.fromList [-> (".hs", M.fromList [-> ("name", "haskell"), ("symbol", "--")]),-> (".lhs", M.fromList [-> ("name", "haskell"), ("symbol", "--"),-> ("literate", "True"), ("symbol2", ">")]),-> (".coffee", M.fromList [-> ("name", "coffee-script"), hashSymbol]),-> (".js", M.fromList [-> ("name", "javascript"), ("symbol", "//")]),-> (".py", M.fromList [-> ("name", "python"), hashSymbol]),-> (".rb", M.fromList [-> ("name", "ruby"), hashSymbol])-> ]--Does the line begin with a comment?--> hasComments symbol = "^\\s*" ++* symbol ++* "\\s?"-> intoMap lang = M.insert "comment"-> (hasComments $ lang M.! "symbol")-> lang--Build out the appropriate matchers and delimiters for each language.--> in M.map intoMap language+> let content = unsafePerformIO $ readLanguageFile+> jsonData = decode' content+> in fromJust jsonData Get the current language we're documenting, based on the extension. -> getLanguage :: FilePath -> Maybe (Map String ByteString)+> getLanguage :: FilePath -> Maybe Language > getLanguage src = M.lookup (takeExtension src) languages Compute the destination HTML path for an input source file path. If the