]> git.wincent.com - docvim.git/blob - lib/Text/Docvim/Visitor/Symbol.hs
106c2c4ea882625f84f690a0c4aa414a3cd27696
[docvim.git] / lib / Text / Docvim / Visitor / Symbol.hs
1 module Text.Docvim.Visitor.Symbol (getSymbols) where
2
3 import Data.Char
4 import Data.List
5 import Text.Docvim.AST
6 import Text.Docvim.Visitor.Plugin
7 import qualified Data.Set as Set
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                   -- BUG: validation doesn't seem to run at all for:
15                   --   ppm "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" thing\n\"\n\" # thingz\n\" # thingz\n"
16                   -- but it does run for:
17                   --   ppm "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" |thing|\n\"\n\" # thingz\n\" # thingz\n"
18                   -- yet the AST for the first tree does trip us up in here:
19                   --   let x (Right y) = y
20                   --   let y = parseUnit "\"\" @plugin ZZZZ thing\n\" # thing\n\" # thingz\n\" # thingy\n\" thing\n\"\n\" # thingz\n\" # thingz\n"
21                   --   getSymbols (x y) -- BOOM!
22                   -- what's making the expection get swallowed in the ppm case?
23                   else error $ "Duplicate symbol table entries: " ++ show duplicates
24   where
25     set                                     = Set.fromList symbols
26     symbols                                 = walk gatherSymbols [] node
27     gatherSymbols (CommandAnnotation n _)   = [":" ++ n]
28     gatherSymbols CommandsAnnotation        = genHeading "commands"
29     gatherSymbols FunctionsAnnotation       = genHeading "functions"
30     gatherSymbols (HeadingAnnotation h)     = genHeading h
31     gatherSymbols (LinkTargets ts)          = ts
32     -- TODO: probably don't want this target to exist in the symbol table when
33     -- emitting Markdown
34     gatherSymbols (PluginAnnotation name _) = [name, name ++ ".txt"]
35     gatherSymbols (MappingAnnotation m)     = [m]
36     gatherSymbols MappingsAnnotation        = genHeading "mappings"
37     gatherSymbols OptionsAnnotation         = genHeading "options"
38     gatherSymbols _                         = []
39     genHeading h                            = maybe [] (\x -> [sanitizeAnchor $ x ++ "-" ++ h]) (getPluginName node)
40     duplicates                              = nub $ f (sort symbols)
41       where
42         f [] = []
43         f [_] = []
44         f (x:xs) = if x == head xs
45                    then x : f xs
46                    else f xs