aboutsummaryrefslogblamecommitdiff
path: root/haddock-api/src/Haddock/Options.hs
blob: 0feca92b1df202a7ff5bd976342b6a4d3d4a9f6a (plain) (tree)
1
2
3
4
5
6
7
8

                                                                             

                                                  
                          
  

                                              
  
                                                       
                                                                             

                        
           


                 
             
                   
             
          
              
                       
                       
                
             
                
                     
            
           
                
                 
                    
                    

       
                                  
                             
                                    



                                                            
                                    
                               
                              
                                      
                                                    
 
         
                      
            
                  
                             
                             
                             

                       
                   
                           


                                
                             
                             
                             
                          
                       
                          
                         
                       
             
                         
                
                                    
                         
                                   




                           
                          
                              
                      
                         
                   
                     
                       
                   
                   
                     
                             
                   
                           
                              
                        
                                  
                                
                             
                     


                                  























                                                                
                                                     
                            




































































































































































































                                                                                                                      
   
 


                                                       

                                                                  

                                                     



                                                                      
 

                                                          
                                                             



                                                                        
 
                                  

                                                            

                               

                                                                 








                                                                      

                                                          
                                                                      
 
                                                                       
                  



                                                        
 
                                                                


                                                     
 
                                 
                                                           
 

                                                                              
                                                                              
 

                                                                    

                                                              
                                                            
 
                                                   
                                                                          






                                                                     
 

                                                                               



                                                                           
 
                                



                                                               
 
                                                                         
 

                                                         

                                                                
 
                                                                            
       
                                                      
                               



                                                        
 


                                                                          






                                                                               

                                                              
                                                                               
                                                    
                                                                 
                                                       
                                                             
   
                                                       
-----------------------------------------------------------------------------
-- |
-- Module      :  Haddock.Options
-- Copyright   :  (c) Simon Marlow      2003-2006,
--                    David Waern       2006-2009,
--                    Mateusz Kowalczyk 2013
-- License     :  BSD-like
--
-- Maintainer  :  haddock@projects.haskell.org
-- Stability   :  experimental
-- Portability :  portable
--
-- Definition of the command line interface of Haddock.
-----------------------------------------------------------------------------
module Haddock.Options (
  parseHaddockOpts,
  Flag(..),
  getUsage,
  optTitle,
  outputDir,
  optContentsUrl,
  optIndexUrl,
  optCssFile,
  optSourceCssFile,
  sourceUrls,
  wikiUrls,
  baseUrl,
  optParCount,
  optDumpInterfaceFile,
  optShowInterfaceFile,
  optLaTeXStyle,
  optMathjax,
  qualification,
  sinceQualification,
  verbosity,
  ghcFlags,
  reexportFlags,
  readIfaceArgs,
  optPackageName,
  optPackageVersion,
  modulePackageInfo,
  ignoredSymbols
) where


import qualified Data.Char as Char
import           Data.Version
import           Control.Applicative
import qualified Data.Char                     as Char
import           Data.Version
import           GHC                            ( Module
                                                , moduleUnit
                                                )
import           GHC.Data.FastString
import           GHC.Unit.State
import           Haddock.Types
import           Haddock.Utils
import           System.Console.GetOpt
import qualified Text.ParserCombinators.ReadP  as RP


data Flag
  = Flag_BuiltInThemes
  | Flag_CSS String
  | Flag_Org
--  | Flag_DocBook
  | Flag_ReadInterface String
  | Flag_DumpInterface String
  | Flag_ShowInterface String
  | Flag_Heading String
  | Flag_Html
  | Flag_Hoogle
  | Flag_Lib String
  | Flag_OutputDir FilePath
  | Flag_Prologue FilePath
  | Flag_SourceBaseURL    String
  | Flag_SourceModuleURL  String
  | Flag_SourceEntityURL  String
  | Flag_SourceLEntityURL String
  | Flag_WikiBaseURL   String
  | Flag_BaseURL       String
  | Flag_WikiModuleURL String
  | Flag_WikiEntityURL String
  | Flag_LaTeX
  | Flag_LaTeXStyle String
  | Flag_QuickJumpIndex
  | Flag_HyperlinkedSource
  | Flag_SourceCss String
  | Flag_Mathjax String
  | Flag_Help
  | Flag_Verbosity String
  | Flag_Version
  | Flag_CompatibleInterfaceVersions
  | Flag_InterfaceVersion
  | Flag_BypassInterfaceVersonCheck
  | Flag_UseContents String
  | Flag_GenContents
  | Flag_UseIndex String
  | Flag_GenIndex
  | Flag_IgnoreAllExports
  | Flag_HideModule String
  | Flag_ShowModule String
  | Flag_ShowAllModules
  | Flag_ShowExtensions String
  | Flag_OptGhc String
  | Flag_GhcLibDir String
  | Flag_GhcVersion
  | Flag_PrintGhcPath
  | Flag_PrintGhcLibDir
  | Flag_NoWarnings
  | Flag_UseUnicode
  | Flag_NoTmpCompDir
  | Flag_Qualification String
  | Flag_PrettyHtml
  | Flag_NoPrintMissingDocs
  | Flag_PackageName String
  | Flag_PackageVersion String
  | Flag_Reexport String
  | Flag_SinceQualification String
  | Flag_IgnoreLinkSymbol String
  | Flag_ParCount (Maybe Int)
  deriving (Eq, Show)


options :: Bool -> [OptDescr Flag]
options backwardsCompat =
  [ Option ['B']
           []
           (ReqArg Flag_GhcLibDir "DIR")
           "path to a GHC lib dir, to override the default path"
  , Option ['o']
           ["odir"]
           (ReqArg Flag_OutputDir "DIR")
           "directory in which to put the output files"
  , Option ['l']
           ["lib"]
           (ReqArg Flag_Lib "DIR")
           "location of Haddock's auxiliary files"
  , Option ['i']
           ["read-interface"]
           (ReqArg Flag_ReadInterface "FILE")
           "read an interface from FILE"
  , Option ['D']
           ["dump-interface"]
           (ReqArg Flag_DumpInterface "FILE")
           "write the resulting interface to FILE"
  , Option []
           ["show-interface"]
           (ReqArg Flag_ShowInterface "FILE")
           "print the interface in a human readable form"
  ,
--    Option ['S']  ["docbook"]  (NoArg Flag_DocBook)
--  "output in DocBook XML",
    Option ['h'] ["html"]  (NoArg Flag_Html)  "output in HTML (XHTML 1.0)"
  , Option ['O'] ["org"]   (NoArg Flag_Org)   "output in Org"
  , Option []    ["latex"] (NoArg Flag_LaTeX) "use experimental LaTeX rendering"
  , Option []
           ["latex-style"]
           (ReqArg Flag_LaTeXStyle "FILE")
           "provide your own LaTeX style in FILE"
  , Option [] ["mathjax"] (ReqArg Flag_Mathjax "URL") "URL FOR mathjax"
  , Option ['U']
           ["use-unicode"]
           (NoArg Flag_UseUnicode)
           "use Unicode in HTML output"
  , Option
    []
    ["hoogle"]
    (NoArg Flag_Hoogle)
    "output for Hoogle; you may want --package-name and --package-version too"
  , Option []
           ["quickjump"]
           (NoArg Flag_QuickJumpIndex)
           "generate an index for interactive documentation navigation"
  , Option
    []
    ["hyperlinked-source"]
    (NoArg Flag_HyperlinkedSource)
    "generate highlighted and hyperlinked source code (for use with --html)"
  , Option []
           ["source-css"]
           (ReqArg Flag_SourceCss "FILE")
           "use custom CSS file instead of default one in hyperlinked source"
  , Option []
           ["source-base"]
           (ReqArg Flag_SourceBaseURL "URL")
           "URL for a source code link on the contents\nand index pages"
  , Option
    ['s']
    (if backwardsCompat then ["source", "source-module"] else ["source-module"])
    (ReqArg Flag_SourceModuleURL "URL")
    "URL for a source code link for each module\n(using the %{FILE} or %{MODULE} vars)"
  , Option
    []
    ["source-entity"]
    (ReqArg Flag_SourceEntityURL "URL")
    "URL for a source code link for each entity\n(using the %{FILE}, %{MODULE}, %{NAME},\n%{KIND} or %{LINE} vars)"
  , Option
    []
    ["source-entity-line"]
    (ReqArg Flag_SourceLEntityURL "URL")
    "URL for a source code link for each entity.\nUsed if name links are unavailable, eg. for TH splices."
  , Option []
           ["comments-base"]
           (ReqArg Flag_WikiBaseURL "URL")
           "URL for a comments link on the contents\nand index pages"
  , Option
    []
    ["base-url"]
    (ReqArg Flag_BaseURL "URL")
    "Base URL for static assets (eg. css, javascript, json files etc.).\nWhen given statis assets will not be copied."
  , Option
    []
    ["comments-module"]
    (ReqArg Flag_WikiModuleURL "URL")
    "URL for a comments link for each module\n(using the %{MODULE} var)"
  , Option
    []
    ["comments-entity"]
    (ReqArg Flag_WikiEntityURL "URL")
    "URL for a comments link for each entity\n(using the %{FILE}, %{MODULE}, %{NAME},\n%{KIND} or %{LINE} vars)"
  , Option ['c']
           ["css", "theme"]
           (ReqArg Flag_CSS "PATH")
           "the CSS file or theme directory to use for HTML output"
  , Option []
           ["built-in-themes"]
           (NoArg Flag_BuiltInThemes)
           "include all the built-in haddock themes"
  , Option ['p']
           ["prologue"]
           (ReqArg Flag_Prologue "FILE")
           "file containing prologue text"
  , Option ['t'] ["title"] (ReqArg Flag_Heading "TITLE") "page heading"
  , Option
    ['q']
    ["qual"]
    (ReqArg Flag_Qualification "QUAL")
    "qualification of names, one of \n'none' (default), 'full', 'local'\n'relative' or 'aliased'"
  , Option ['?'] ["help"] (NoArg Flag_Help) "display this help and exit"
  , Option ['V']
           ["version"]
           (NoArg Flag_Version)
           "output version information and exit"
  , Option []
           ["compatible-interface-versions"]
           (NoArg Flag_CompatibleInterfaceVersions)
           "output compatible interface file versions and exit"
  , Option []
           ["interface-version"]
           (NoArg Flag_InterfaceVersion)
           "output interface file version and exit"
  , Option []
           ["bypass-interface-version-check"]
           (NoArg Flag_BypassInterfaceVersonCheck)
           "bypass the interface file version check (dangerous)"
  , Option ['v']
           ["verbosity"]
           (ReqArg Flag_Verbosity "VERBOSITY")
           "set verbosity level"
  , Option []
           ["use-contents"]
           (ReqArg Flag_UseContents "URL")
           "use a separately-generated HTML contents page"
  , Option []
           ["gen-contents"]
           (NoArg Flag_GenContents)
           "generate an HTML contents from specified\ninterfaces"
  , Option []
           ["use-index"]
           (ReqArg Flag_UseIndex "URL")
           "use a separately-generated HTML index"
  , Option []
           ["gen-index"]
           (NoArg Flag_GenIndex)
           "generate an HTML index from specified\ninterfaces"
  , Option []
           ["ignore-all-exports"]
           (NoArg Flag_IgnoreAllExports)
           "behave as if all modules have the\nignore-exports attribute"
  , Option []
           ["hide"]
           (ReqArg Flag_HideModule "MODULE")
           "behave as if MODULE has the hide attribute"
  , Option []
           ["show"]
           (ReqArg Flag_ShowModule "MODULE")
           "behave as if MODULE does not have the hide attribute"
  , Option []
           ["show-all"]
           (NoArg Flag_ShowAllModules)
           "behave as if not modules have the hide attribute"
  , Option []
           ["show-extensions"]
           (ReqArg Flag_ShowExtensions "MODULE")
           "behave as if MODULE has the show-extensions attribute"
  , Option []
           ["optghc"]
           (ReqArg Flag_OptGhc "OPTION")
           "option to be forwarded to GHC"
  , Option []
           ["ghc-version"]
           (NoArg Flag_GhcVersion)
           "output GHC version in numeric format"
  , Option []
           ["print-ghc-path"]
           (NoArg Flag_PrintGhcPath)
           "output path to GHC binary"
  , Option []
           ["print-ghc-libdir"]
           (NoArg Flag_PrintGhcLibDir)
           "output GHC lib dir"
  , Option ['w'] ["no-warnings"] (NoArg Flag_NoWarnings) "turn off all warnings"
  , Option []
           ["no-tmp-comp-dir"]
           (NoArg Flag_NoTmpCompDir)
           "do not re-direct compilation output to a temporary directory"
  , Option []
           ["pretty-html"]
           (NoArg Flag_PrettyHtml)
           "generate html with newlines and indenting (for use with --html)"
  , Option []
           ["no-print-missing-docs"]
           (NoArg Flag_NoPrintMissingDocs)
           "don't print information about any undocumented entities"
  , Option []
           ["reexport"]
           (ReqArg Flag_Reexport "MOD")
           "reexport the module MOD, adding it to the index"
  , Option []
           ["package-name"]
           (ReqArg Flag_PackageName "NAME")
           "name of the package being documented"
  , Option []
           ["package-version"]
           (ReqArg Flag_PackageVersion "VERSION")
           "version of the package being documented in usual x.y.z.w format"
  , Option
    []
    ["since-qual"]
    (ReqArg Flag_SinceQualification "QUAL")
    "package qualification of @since, one of\n'always' (default) or 'only-external'"
  , Option
    []
    ["ignore-link-symbol"]
    (ReqArg Flag_IgnoreLinkSymbol "SYMBOL")
    "name of a symbol which does not trigger a warning in case of link issue"
  , Option ['j']
           []
           (OptArg (\count -> Flag_ParCount (fmap read count)) "n")
           "load modules in parallel"
  ]


getUsage :: IO String
getUsage = do
  prog <- getProgramName
  return $ usageInfo (usageHeader prog) (options False)
 where
  usageHeader :: String -> String
  usageHeader prog = "Usage: " ++ prog ++ " [OPTION...] file...\n"


parseHaddockOpts :: [String] -> IO ([Flag], [String])
parseHaddockOpts params = case getOpt Permute (options True) params of
  (flags, args, []    ) -> return (flags, args)
  (_    , _   , errors) -> do
    usage <- getUsage
    throwE (concat errors ++ usage)

optPackageVersion :: [Flag] -> Maybe Data.Version.Version
optPackageVersion flags =
  let ver = optLast [ v | Flag_PackageVersion v <- flags ]
  in  ver >>= fmap fst . optLast . RP.readP_to_S parseVersion

optPackageName :: [Flag] -> Maybe PackageName
optPackageName flags =
  optLast [ PackageName $ mkFastString n | Flag_PackageName n <- flags ]


optTitle :: [Flag] -> Maybe String
optTitle flags = case [ str | Flag_Heading str <- flags ] of
  []      -> Nothing
  (t : _) -> Just t


outputDir :: [Flag] -> FilePath
outputDir flags = case [ path | Flag_OutputDir path <- flags ] of
  []    -> "."
  paths -> last paths


optContentsUrl :: [Flag] -> Maybe String
optContentsUrl flags = optLast [ url | Flag_UseContents url <- flags ]


optIndexUrl :: [Flag] -> Maybe String
optIndexUrl flags = optLast [ url | Flag_UseIndex url <- flags ]


optCssFile :: [Flag] -> Maybe FilePath
optCssFile flags = optLast [ str | Flag_CSS str <- flags ]

optSourceCssFile :: [Flag] -> Maybe FilePath
optSourceCssFile flags = optLast [ str | Flag_SourceCss str <- flags ]

sourceUrls
  :: [Flag] -> (Maybe String, Maybe String, Maybe String, Maybe String)
sourceUrls flags =
  ( optLast [ str | Flag_SourceBaseURL str <- flags ]
  , optLast [ str | Flag_SourceModuleURL str <- flags ]
  , optLast [ str | Flag_SourceEntityURL str <- flags ]
  , optLast [ str | Flag_SourceLEntityURL str <- flags ]
  )


wikiUrls :: [Flag] -> (Maybe String, Maybe String, Maybe String)
wikiUrls flags =
  ( optLast [ str | Flag_WikiBaseURL str <- flags ]
  , optLast [ str | Flag_WikiModuleURL str <- flags ]
  , optLast [ str | Flag_WikiEntityURL str <- flags ]
  )


baseUrl :: [Flag] -> Maybe String
baseUrl flags = optLast [ str | Flag_BaseURL str <- flags ]

optDumpInterfaceFile :: [Flag] -> Maybe FilePath
optDumpInterfaceFile flags = optLast [ str | Flag_DumpInterface str <- flags ]

optShowInterfaceFile :: [Flag] -> Maybe FilePath
optShowInterfaceFile flags = optLast [ str | Flag_ShowInterface str <- flags ]

optLaTeXStyle :: [Flag] -> Maybe String
optLaTeXStyle flags = optLast [ str | Flag_LaTeXStyle str <- flags ]

optMathjax :: [Flag] -> Maybe String
optMathjax flags = optLast [ str | Flag_Mathjax str <- flags ]

optParCount :: [Flag] -> Maybe (Maybe Int)
optParCount flags = optLast [ n | Flag_ParCount n <- flags ]

qualification :: [Flag] -> Either String QualOption
qualification flags =
  case map (map Char.toLower) [ str | Flag_Qualification str <- flags ] of
    []            -> Right OptNoQual
    [ "none"    ] -> Right OptNoQual
    [ "full"    ] -> Right OptFullQual
    [ "local"   ] -> Right OptLocalQual
    [ "relative"] -> Right OptRelativeQual
    [ "aliased" ] -> Right OptAliasedQual
    [ arg       ] -> Left $ "unknown qualification type " ++ show arg
    _ :         _ -> Left "qualification option given multiple times"

sinceQualification :: [Flag] -> Either String SinceQual
sinceQualification flags =
  case map (map Char.toLower) [ str | Flag_SinceQualification str <- flags ] of
    []            -> Right Always
    [ "always"  ] -> Right Always
    [ "external"] -> Right External
    [ arg       ] -> Left $ "unknown since-qualification type " ++ show arg
    _ :         _ -> Left "since-qualification option given multiple times"

verbosity :: [Flag] -> Verbosity
verbosity flags = case [ str | Flag_Verbosity str <- flags ] of
  []    -> Normal
  x : _ -> case parseVerbosity x of
    Left  e -> throwE e
    Right v -> v

ignoredSymbols :: [Flag] -> [String]
ignoredSymbols flags = [ symbol | Flag_IgnoreLinkSymbol symbol <- flags ]

ghcFlags :: [Flag] -> [String]
ghcFlags flags = [ option | Flag_OptGhc option <- flags ]

reexportFlags :: [Flag] -> [String]
reexportFlags flags = [ option | Flag_Reexport option <- flags ]


readIfaceArgs :: [Flag] -> [(DocPaths, FilePath)]
readIfaceArgs flags = [ parseIfaceOption s | Flag_ReadInterface s <- flags ]
  where
    parseIfaceOption :: String -> (DocPaths, FilePath)
    parseIfaceOption str =
      case break (==',') str of
        (fpath, ',':rest) ->
          case break (==',') rest of
            (src, ',':file) -> ((fpath, Just src), file)
            (file, _) -> ((fpath, Nothing), file)
        (file, _) -> (("", Nothing), file)


-- | Like 'listToMaybe' but returns the last element instead of the first.
optLast :: [a] -> Maybe a
optLast [] = Nothing
optLast xs = Just (last xs)


-- | This function has a potential to return 'Nothing' because package name and
-- versions can no longer reliably be extracted in all cases: if the package is
-- not installed yet then this info is no longer available.
--
-- The @--package-name@ and @--package-version@ Haddock flags allow the user to
-- specify this information manually and it is returned here if present.
modulePackageInfo
  :: UnitState
  -> [Flag] -- ^ Haddock flags are checked as they may contain
                            -- the package name or version provided by the user
                            -- which we prioritise
  -> Maybe Module
  -> (Maybe PackageName, Maybe Data.Version.Version)
modulePackageInfo _unit_state _flags Nothing = (Nothing, Nothing)
modulePackageInfo unit_state flags (Just modu) =
  ( optPackageName flags <|> fmap unitPackageName pkgDb
  , optPackageVersion flags <|> fmap unitPackageVersion pkgDb
  )
  where pkgDb = lookupUnit unit_state (moduleUnit modu)