]> git.wincent.com - docvim.git/blob - lib/Docvim/Visitor/Symbol.hs
Initial cut at @mapping, @command, @option, @function
[docvim.git] / lib / Docvim / Visitor / Symbol.hs
1 module Docvim.Visitor.Symbol (getSymbols) where
2
3 import Data.Char (toLower)
4 import Data.List (nub, sort)
5 import qualified Data.Set as Set
6 import Docvim.AST
7 import Docvim.Visitor.Plugin (getPluginName)
8
9 -- TODO: return Set instead of [String]
10 -- TODO: use Either instead of dying unceremoniously with `error`
11 getSymbols :: Node -> [String]
12 getSymbols node = if length symbols == Set.size set
13                   then symbols
14                   else error $ "Duplicate symbol table entries: " ++ show duplicates
15   where
16     set                                     = Set.fromList symbols
17     symbols                                 = walk gatherSymbols [] node
18     gatherSymbols (CommandsAnnotation)      = genHeading "commands"
19     gatherSymbols (FunctionsAnnotation)     = genHeading "functions"
20     gatherSymbols (HeadingAnnotation h)     = genHeading h
21     gatherSymbols (LinkTargets ts)          = ts
22     -- TODO: probably don't want this target to exist in the symbol table when
23     -- emitting Markdown
24     gatherSymbols (PluginAnnotation name _) = [name, name ++ ".txt"]
25     gatherSymbols (MappingsAnnotation)      = genHeading "mappings"
26     gatherSymbols (OptionsAnnotation)       = genHeading "options"
27     gatherSymbols _                         = []
28     genHeading h                            = maybe [] (\x -> [sanitizeAnchor $ x ++ "-" ++ h]) (getPluginName node)
29     duplicates                              = nub $ f (sort symbols)
30       where
31         f [] = []
32         f [x] = []
33         f (x:xs) = if x == head xs
34                    then x : f xs
35                    else f xs
36
37 downcase :: String -> String
38 downcase = map toLower