Filter for linking Agda identifiers in inline code spans
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

47 lines
1.3 KiB

2 years ago
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Main where
  3. import qualified Data.HashMap.Strict as HashMap
  4. import Data.HashMap.Strict (HashMap)
  5. import qualified Data.Text as T
  6. import Data.Text (Text)
  7. import Data.Maybe
  8. import Data.List
  9. import System.Environment
  10. import System.Exit
  11. import Text.Pandoc.Definition
  12. import Text.HTML.TagSoup
  13. import Text.Pandoc.Walk
  14. import Text.Pandoc.JSON
  15. main :: IO ()
  16. main = toJSONFilter linkDocument
  17. linkDocument :: Pandoc -> Pandoc
  18. linkDocument (Pandoc meta blocks) =
  19. let hm = parseSymbolRefs blocks
  20. in Pandoc meta (walk (link hm) blocks)
  21. link :: HashMap Text Text -> Inline -> Inline
  22. link hm (Code attrs xs)
  23. | Just sp <- HashMap.lookup xs hm = RawInline (Format "html") sp
  24. link _ x = x
  25. parseSymbolRefs :: [Block] -> HashMap Text Text
  26. parseSymbolRefs = go mempty . concat . mapMaybe getHTML where
  27. getHTML (RawBlock (Format x) xs)
  28. | x == "html" = Just (parseTags (T.unpack xs))
  29. getHTML _ = Nothing
  30. go map (TagOpen "a" meta:TagText t:TagClose "a":xs)
  31. | Just id <- lookup "id" meta, Just cls <- lookup "class" meta
  32. = go (HashMap.insert (T.pack t) (T.pack (renderTags tags)) map) xs
  33. | otherwise = go map xs
  34. where
  35. tags = [ TagOpen "span" [("class", "Agda")], TagOpen "a" meta', TagText t, TagClose "a", TagClose "span" ]
  36. meta' = filter ((/= "id") . fst) meta
  37. go map (_:xs) = go map xs
  38. go map [] = map