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