docvim-0.3.0.0: lib/Text/Docvim/Visitor/Symbol.hs
module Text.Docvim.Visitor.Symbol (getSymbols) where
import Data.List
import Text.Docvim.AST
import Text.Docvim.Visitor.Plugin
import qualified Data.Set as Set
-- TODO: return Set instead of [String]
-- TODO: use Either instead of dying unceremoniously with `error`
getSymbols :: Node -> [String]
getSymbols node = if length symbols == Set.size set
then symbols
-- BUG: validation doesn't seem to run at all for:
-- ppm "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" thing\n\"\n\" # thingz\n\" # thingz\n"
-- but it does run for:
-- ppm "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" |thing|\n\"\n\" # thingz\n\" # thingz\n"
-- yet the AST for the first tree does trip us up in here:
-- let x (Right y) = y
-- let y = parseUnit "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" thing\n\"\n\" # thingz\n\" # thingz\n"
-- getSymbols (x y) -- BOOM!
-- what's making the expection get swallowed in the ppm case?
else error $ "Duplicate symbol table entries: " ++ show duplicates
where
set = Set.fromList symbols
symbols = walk gatherSymbols [] node
gatherSymbols (CommandAnnotation n _) = [":" ++ n]
gatherSymbols CommandsAnnotation = genHeading "commands"
gatherSymbols FunctionsAnnotation = genHeading "functions"
gatherSymbols (HeadingAnnotation h) = genHeading h
gatherSymbols (LinkTargets ts) = ts
-- TODO: probably don't want this target to exist in the symbol table when
-- emitting Markdown
gatherSymbols (PluginAnnotation name _) = [name, name ++ ".txt"]
gatherSymbols (MappingAnnotation m) = [m]
gatherSymbols MappingsAnnotation = genHeading "mappings"
gatherSymbols OptionsAnnotation = genHeading "options"
gatherSymbols _ = []
genHeading h = maybe [] (\x -> [sanitizeAnchor $ x ++ "-" ++ h]) (getPluginName node)
duplicates = nub $ f (sort symbols)
where
f [] = []
f [_] = []
f (x:xs) = if x == head xs
then x : f xs
else f xs