Shake, tools/pandoc-site.{hs => lua}: switch to building site with Lua filter
This commit is contained in:
		
							parent
							
								
									f3d81631e9
								
							
						
					
					
						commit
						16200908e8
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -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 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								Shake.hs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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 | ||||
|  | ||||
							
								
								
									
										2
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tools/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,2 +0,0 @@ | ||||
| generatetimeclock | ||||
| pandoc-site | ||||
| @ -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" "<nav id=\"toc\" class=\"right-toc\">" | ||||
|           navEnd    = RawBlock "html" "</nav>" | ||||
|        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 | ||||
							
								
								
									
										59
									
								
								tools/pandoc-site.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								tools/pandoc-site.lua
									
									
									
									
									
										Normal file
									
								
							| @ -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", "<nav id=\"toc\" class=\"right-toc\">") | ||||
|   local navEnd    = pandoc.RawBlock("html", "</nav>") | ||||
|   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 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user