]> git.wincent.com - docvim.git/commitdiff
Mostly-working TOC generation for AST
authorGreg Hurrell <greg@hurrell.net>
Thu, 9 Jun 2016 02:52:52 +0000 (19:52 -0700)
committerGreg Hurrell <greg@hurrell.net>
Thu, 9 Jun 2016 02:52:52 +0000 (19:52 -0700)
Not used in printers yet, and also note that because the printers may generate
headings of their own, we are missing generated headings.

docvim.cabal
lib/Docvim/AST.hs
lib/Docvim/Compile.hs
lib/Docvim/Printer/Vim.hs
lib/Docvim/Visitor/Heading.hs [new file with mode: 0644]
tests/fixtures/parser/integration-docvim.golden
tests/fixtures/parser/integration-ferret-plugin.golden
tests/fixtures/parser/integration-pinnacle.golden
tests/fixtures/parser/minimal-annotation.golden
tests/fixtures/parser/plugin-annotation.golden
tests/fixtures/parser/simple-annotations.golden

index f7d7d5a0c48dc590941016782f15fec3838c6237..670f79d31c292ea134bcd1bec7f6784656a565e8 100644 (file)
@@ -99,6 +99,7 @@ library
                  ,  Docvim.Visitor.Footer
                  ,  Docvim.Visitor.Function
                  ,  Docvim.Visitor.Functions
+                 ,  Docvim.Visitor.Heading
                  ,  Docvim.Visitor.Mapping
                  ,  Docvim.Visitor.Mappings
                  ,  Docvim.Visitor.Option
index 03f757da607d804393a168bb983d7260c04168df..0e4db57f3244e4c9a54a0e6f46765420fce6f635 100644 (file)
@@ -4,7 +4,7 @@ module Docvim.AST where
 
 import Control.Lens.Fold (foldlOf)
 import Control.Lens.Getter (to)
-import Control.Lens.Plated (cosmosOf)
+import Control.Lens.Plated (Plated, cosmosOf)
 import Data.Char (toLower)
 import Data.Data
 import Data.Data.Lens (uniplate)
@@ -70,6 +70,9 @@ data Node
           | OptionAnnotation Name Type (Maybe Default)
           | HeadingAnnotation String
           | SubheadingAnnotation String
+
+          -- Docvim nodes: synthesized nodes
+          | TOC [String]
   deriving (Data, Eq, Show, Typeable)
 
 -- The VimScript (VimL) grammar is embodied in the implementation of
@@ -89,6 +92,8 @@ data ArgumentList = ArgumentList [Argument]
 data Argument = Argument String
   deriving (Data, Eq, Show, Typeable)
 
+instance Plated Node
+
 type Default = String
 type Description = String
 type Name = String
index 8702711c41e0824adb5051200ed7460261a3be93..9c83289abbc69051763dda4b3b3e38123285c791 100644 (file)
@@ -6,6 +6,7 @@ import Docvim.Visitor.Commands (extractCommands)
 import Docvim.Visitor.Footer (extractFooter)
 import Docvim.Visitor.Function (extractFunction)
 import Docvim.Visitor.Functions (extractFunctions)
+import Docvim.Visitor.Heading (injectTOC)
 import Docvim.Visitor.Mapping (extractMapping)
 import Docvim.Visitor.Mappings (extractMappings)
 import Docvim.Visitor.Option (extractOption)
@@ -36,15 +37,15 @@ compile ns = do
   let (ast9, options) = extract extractOptions ast8
   let (ast10, option) = extract extractOption ast9
   let (ast11, footer) = extract extractFooter ast10
-  Project $ concat [ plugin
-                   , [ast11]
-                   , commands
-                   , command
-                   , mappings
-                   , mapping
-                   , options
-                   , option
-                   , functions
-                   , function
-                   , footer
-                   ]
+  injectTOC $ Project $ concat [ plugin
+                               , [ast11]
+                               , commands
+                               , command
+                               , mappings
+                               , mapping
+                               , options
+                               , option
+                               , functions
+                               , function
+                               , footer
+                               ]
index 1cbf7e53ad495937bdb91481af268abb608678fa..b6178579c1eb9f5575d096fc6abb4ab96a6d91ae 100644 (file)
@@ -137,14 +137,6 @@ node n = case n of
   Fenced f                   -> fenced f
   FunctionsAnnotation        -> heading "functions"
   FunctionDeclaration {}     -> nodes $ functionBody n
-  -- TODO: Vim will only highlight this as a heading if it has a trailing
-  -- LinkTarget on the same line; figure out how to handle that; may need to
-  -- address it in the Parser
-  --
-  -- Looking at the Ferret fixtures, seems like I had an idea for this which was
-  -- to auto-gen the targets based on the plugin name + the heading text.
-  --
-  -- I could also just make people specify a target explicitly.
   HeadingAnnotation h        -> heading h
   Link l                     -> append $ link l
   LinkTargets l              -> linkTargets l True
@@ -152,16 +144,10 @@ node n = case n of
   ListItem l                 -> listitem l
   MappingAnnotation m        -> mapping m
   MappingsAnnotation         -> heading "mappings"
-  -- TODO: if there is no OptionsAnnotation but there are OptionAnnotations, we
-  -- need to insert a `heading "options"` before the first option (ditto for
-  -- functions, mappings, commands)
   OptionAnnotation {}        -> option n
   OptionsAnnotation          -> heading "options"
   Paragraph p                -> nodes p >>= nl >>= nl
   Plaintext p                -> plaintext p
-  -- TODO: this should be order-independent and always appear at the top.
-  -- Note that I don't really have anywhere to put the description; maybe I should
-  -- scrap it (nope: need it in the Vim help version).
   PluginAnnotation name desc -> plugin name desc
   Project p                  -> nodes p
   Separator                  -> append $ "---" ++ "\n\n"
@@ -225,10 +211,7 @@ option (OptionAnnotation n t d) = do
     rhs = t ++ " (default: " ++ fromMaybe "none" d ++ ")\n\n"
 
 whitespace :: Env
-whitespace =
-  -- if current line > 80 "\n" else " "
-  -- but note, really need to do this BEFORE 80
-  append " "
+whitespace = append " "
 
 blockquote :: [Node] -> Env
 blockquote ps = do
diff --git a/lib/Docvim/Visitor/Heading.hs b/lib/Docvim/Visitor/Heading.hs
new file mode 100644 (file)
index 0000000..6623220
--- /dev/null
@@ -0,0 +1,27 @@
+module Docvim.Visitor.Heading ( getHeadings
+                              , injectTOC
+                              ) where
+
+import Control.Lens
+import Control.Lens.Plated (transform)
+import Data.Data.Lens (uniplate)
+import Docvim.AST
+
+-- | Returns a list of all headings, in the order in which they appear in the
+-- AST.
+getHeadings :: Node -> [String]
+getHeadings = walk gather []
+  where
+    gather (HeadingAnnotation h) = [h]
+    gather _                     = []
+
+-- | Injects a table of contents immediately after any `PluginAnnotation` in an
+-- AST (note: there should only be one).
+-- TODO: warn or error if there is more than one.
+-- or use a monadic variant of transform to do only the first...
+injectTOC :: Node -> Node
+injectTOC ast = transform inject $ ast
+  where
+    inject n = case n of
+      PluginAnnotation {} -> DocBlock $ [n] ++ [TOC $ getHeadings ast]
+      _                   -> n
index fc6e217d440171b0a10a7ffb7cb91602bd6d913e..94832768c274c21c2cf17a2b957f8800a57ff58e 100644 (file)
@@ -1,6 +1,18 @@
 Project
-  [ PluginAnnotation
-      "docvim" "Syntax highlighting for docvim comments"
+  [ DocBlock
+      [ PluginAnnotation
+          "docvim" "Syntax highlighting for docvim comments"
+      , TOC
+          [ "Intro"
+          , "Installation"
+          , "Related"
+          , "Website"
+          , "License"
+          , "Development"
+          , "Authors"
+          , "History"
+          ]
+      ]
   , LinkTargets [ "vim-docvim" ]
   , HeadingAnnotation "Intro"
   , Paragraph
index faa8ba3733a3d6aa450e9e9a389c686af749ba5c..f653324361de169ea00a9b7a993de8c3505e685e 100644 (file)
@@ -1,5 +1,21 @@
 Project
-  [ PluginAnnotation "ferret" "Ferret plug-in for Vim"
+  [ DocBlock
+      [ PluginAnnotation "ferret" "Ferret plug-in for Vim"
+      , TOC
+          [ "Intro"
+          , "Installation"
+          , "Custom autocommands"
+          , "Overrides"
+          , "Troubleshooting"
+          , "FAQ"
+          , "Related"
+          , "Website"
+          , "License"
+          , "Development"
+          , "Authors"
+          , "History"
+          ]
+      ]
   , HeadingAnnotation "Intro"
   , Blockquote
       [ Paragraph
index afb912ffee6f3bd0a9d959751fef2b61b9bb5fbb..4088fd691235e811d8cf3b15d40b9af3d098624f 100644 (file)
@@ -1,6 +1,17 @@
 Project
-  [ PluginAnnotation
-      "Pinnacle" "Highlight group manipulation for Vim"
+  [ DocBlock
+      [ PluginAnnotation
+          "Pinnacle" "Highlight group manipulation for Vim"
+      , TOC
+          [ "Intro"
+          , "Installation"
+          , "Website"
+          , "License"
+          , "Development"
+          , "Authors"
+          , "History"
+          ]
+      ]
   , HeadingAnnotation "Intro"
   , Paragraph
       [ Plaintext "Pinnacle"
index 4e7b5c5746506398bf75f284d06eb7af1ca8f40e..899351d6ce8ee908ac81ab1465715405307460a1 100644 (file)
@@ -1,2 +1,4 @@
 Project
-  [ PluginAnnotation "Foo" "Bar" , Project [ Unit [ DocBlock [] ] ] ]
+  [ DocBlock [ PluginAnnotation "Foo" "Bar" , TOC [] ]
+  , Project [ Unit [ DocBlock [] ] ]
+  ]
index 98ba356b6de338e6af1b22de065ae5a73a47a9eb..085f0e0a81fd59ee5bde0b3c63a81a051f2caa47 100644 (file)
@@ -1,4 +1,7 @@
 Project
-  [ PluginAnnotation "Foo" "Description with trailing whitespace"
+  [ DocBlock
+      [ PluginAnnotation "Foo" "Description with trailing whitespace"
+      , TOC []
+      ]
   , Project [ Unit [ DocBlock [] ] ]
   ]
index e332ff80c5dc126fa81ab7b41fc27fd6ab700429..a002a58f3a8d087a1104e2ce3bc062447bb50303 100644 (file)
@@ -1,5 +1,5 @@
 Project
-  [ PluginAnnotation "foo" "bar"
+  [ DocBlock [ PluginAnnotation "foo" "bar" , TOC [] ]
   , DedentAnnotation
   , Project
       [ Unit