diff --git a/.gitignore b/.gitignore index 6dd5f1775..4596713be 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ TAGS /tools/pandoc-drop-links /tools/pandoc-drop-notes /tools/pandoc-drop-toc +/tools/generatetimeclock # Tricksy rules ignoring some typical temp files. # For troubleshooting: git check-ignore --verbose PATHS... @@ -73,4 +74,3 @@ hledger-web/yesod-devel/ .hledger-web_client_session_key.aes # recent stuff - diff --git a/Shake.hs b/Shake.hs index 672b1fa4c..72c21a27d 100755 --- a/Shake.hs +++ b/Shake.hs @@ -67,7 +67,6 @@ usage = unlines ] pandoc = "stack exec -- pandoc" -- pandoc from project's stackage snapshot -pandocSiteFilter = "tools/pandoc-site" makeinfo = "makeinfo" -- nroff = "nroff" groff = "groff" @@ -297,11 +296,6 @@ main = do phony "website-render" $ do need webhtmlpages - pandocSiteFilter %> \out -> do - let source = out <.> "hs" - need [source] - cmd "stack --stack-yaml=stack-ghc8.2.yaml ghc -- -o" out source - "site/_site/files/README" : [ "site/_site//*" <.> ext | ext <- webcopyfileexts ] |%> \out -> do let input = "site" dropDirectory2 out copyFile' input out @@ -311,12 +305,12 @@ main = do pageTitle = takeBaseName out template = "site/site.tmpl" siteRoot = if "site/_site/doc//*" ?== out then "../.." else "." - need [source, template, pandocSiteFilter] + need [source, template] cmd Shell pandoc "--from markdown --to html" source "--template" template ("--metadata=siteRoot:" ++ siteRoot) ("--metadata=title:" ++ pageTitle) - "--filter" pandocSiteFilter + "--lua-filter" "tools/pandoc-site.lua" "--output" out -- cleanup diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index e31cb78da..000000000 --- a/tools/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -generatetimeclock -pandoc-site diff --git a/tools/pandoc-site.hs b/tools/pandoc-site.hs deleted file mode 100644 index 51909f123..000000000 --- a/tools/pandoc-site.hs +++ /dev/null @@ -1,53 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE CPP #-} - -import Text.Pandoc -import Text.Pandoc.Walk (query) -import Text.Pandoc.Builder (text, toList) -import Text.Pandoc.JSON (toJSONFilter) -import Text.Pandoc.Shared (hierarchicalize, Element(..)) - -import Data.Maybe (fromMaybe) - -collectHeaders :: Block -> [Block] -collectHeaders header@(Header _ (_, classes, _) _) = - if "notoc" `elem` classes - then [] - else [header] -collectHeaders _ = [] - -markupLink :: Attr -> [Inline] -> Inline -markupLink (headerId, _, headerProperties) headerText - = let linkText = fromMaybe headerText (fmap (toList . text) $ lookup "toc" headerProperties) - in Link nullAttr linkText (("#" ++ headerId), headerId) - -markupElement :: Element -> [Block] -markupElement (Sec _ _ hAttr hText headers) - | headers == [] = [link] - | otherwise = [link, markupElements headers] - where link = Plain [markupLink hAttr hText] -markupElement n = error $ "'markupElement' should only be passed a 'Sec'\n" - ++ " saw: " ++ show n - -markupElements :: [Element] -> Block -markupElements = OrderedList (1, Decimal, Period) . map markupElement - -createTable :: [Element] -> [Block] -createTable [] = [] -createTable headers - = let navBegin = RawBlock "html" "" - in [navBegin, Para [Str "Contents"], markupElements headers, navEnd] - -generateTOC :: [Block] -> Block -> [Block] -generateTOC toc (Para [Str "$toc$"]) = toc -generateTOC _ x = [x] - -tableOfContents :: Pandoc -> Pandoc -tableOfContents (Pandoc meta blks) - = let headers = query collectHeaders blks - toc = createTable . hierarchicalize $ headers - in Pandoc meta (concatMap (generateTOC toc) blks) - -main :: IO () -main = toJSONFilter tableOfContents diff --git a/tools/pandoc-site.lua b/tools/pandoc-site.lua new file mode 100644 index 000000000..79a008378 --- /dev/null +++ b/tools/pandoc-site.lua @@ -0,0 +1,59 @@ +local headers = {} + +function Header(h) + table.insert(headers, h) + return h +end + +function isTocBlock(blk) + if not (blk.t == "Para") then return false end + if not blk.content[1] then return false end + if not (blk.content[1].t == "Str") then return false end + if not (blk.content[1].text == "$toc$") then return false end + return true +end + +function markupLink(hAttr, headerText) + local headerId = hAttr.identifier + local headerProperties = hAttr.attributes + return pandoc.Link(headerText, "#" .. headerId, headerId) +end + +function markupElement(elem) + local hAttr = elem.attr + local hText = elem.label + local hNested = elem.contents + local link = pandoc.Plain(markupLink(hAttr, hText)) + if not hNested[1] then return {link} end + return {link, markupElements(hNested)} +end + +function markupElements(elems) + local newElems = {} + for _,e in pairs(elems) do + table.insert(newElems, markupElement(e)) + end + return pandoc.OrderedList(newElems, {"1", "Decimal", "Period"}) +end + +function createTable(elems) + local navBegin = pandoc.RawBlock("html", "") + local contentsP = pandoc.Para(pandoc.Str("Contents")) + return {navBegin, contentsP, markupElements(elems), navEnd} +end + +function Pandoc(doc) + newBlocks = {} + tocBlocks = createTable(pandoc.utils.hierarchicalize(headers)) + for _,blk in pairs(doc.blocks) do + if isTocBlock(blk) then + for _,tocBlk in pairs(tocBlocks) do + table.insert(newBlocks, tocBlk) + end + else + table.insert(newBlocks, blk) + end + end + return pandoc.Doc(newBlocks, doc.meta) +end