-- | "Compile" a set of translation units into a project.
compile :: [Node] -> Node
compile ns = do
    let ast = foldr ($) (Project ns) [ injectCommands
                                     , injectFunctions
                                     , injectMappings
                                     , injectOptions
                                     ]
    let steps = [ extract extractHeader
                , extract extractPlugin
                , extract extractCommands
                , extract extractCommand
                , extract extractMappings
                , extract extractMapping
                , extract extractOptions
                , extract extractOption
                , extract extractFunctions
                , extract extractFunction
                , extract extractFooter
                ]
    let (remainder, sections) = foldl reduce (ast, []) steps
    let (beginning, rest) = splitAt 1 sections
    optimize $ injectTOC $ Project $ (concat . concat) [beginning, [[remainder]], rest]
  where
    reduce (remainder', sections') step = do
      let (r', s') = step remainder'
      (r', sections' ++ [s'])
compile :: [Node] -> Node
compile ns = do
    let ast = foldr ($) (Project ns) [ injectCommands
                                     , injectFunctions
                                     , injectMappings
                                     , injectOptions
                                     ]
    let steps = [ extract extractHeader
                , extract extractPlugin
                , extract extractCommands
                , extract extractCommand
                , extract extractMappings
                , extract extractMapping
                , extract extractOptions
                , extract extractOption
                , extract extractFunctions
                , extract extractFunction
                , extract extractFooter
                ]
    let (remainder, sections) = foldl reduce (ast, []) steps
    let (beginning, rest) = splitAt 1 sections
    optimize $ injectTOC $ Project $ (concat . concat) [beginning, [[remainder]], rest]
  where
    reduce (remainder', sections') step = do
      let (r', s') = step remainder'
      (r', sections' ++ [s'])
compile ns = do
    let ast = foldr ($) (Project ns) [ injectCommands
                                     , injectFunctions
                                     , injectMappings
                                     , injectOptions
                                     ]
    let steps = [ extract extractHeader
                , extract extractPlugin
                , extract extractCommands
                , extract extractCommand
                , extract extractMappings
                , extract extractMapping
                , extract extractOptions
                , extract extractOption
                , extract extractFunctions
                , extract extractFunction
                , extract extractFooter
                ]
    let (remainder, sections) = foldl reduce (ast, []) steps
    let (beginning, rest) = splitAt 1 sections
    optimize $ injectTOC $ Project $ (concat . concat) [beginning, [[remainder]], rest]
  where
    reduce (remainder', sections') step = do
      let (r', s') = step remainder'
      (r', sections' ++ [s'])