packages feed

stylish-cabal-0.4.1.0: src/Render/Lib.hs

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}

module Render.Lib
  ( P(..)
  , renderBlockHead
  , showVersionRange
  , moduleDoc
  , rexpModuleDoc
  , filepath
  , renderTestedWith
  , exeDependencyAsDependency
  , renderDescription
  ) where

import Data.Char
import Data.List.Compat
import Data.Monoid.Compat
import Distribution.Compiler
import Distribution.ModuleName
import Distribution.PackageDescription
import Distribution.Pretty
import Distribution.Types.ExeDependency
import Distribution.Types.PackageName
import Distribution.Types.UnqualComponentName
import Distribution.Version
import Prelude.Compat
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>))

import Render.Lib.Haddock (renderDescription)
import Render.Options
import Types.Block

newtype P = P
  { unP :: String
  } deriving (Eq)

instance Ord P where
  compare (P "base") (P "base") = EQ
  compare (P "base") _ = LT
  compare _ (P "base") = GT
  compare (P p1) (P p2) = compare p1 p2

renderTestedWith ts =
  fillSep . punctuate comma <$>
  mapM (\(compiler, vers) -> showVersioned (showCompiler compiler, vers)) ts
  where
    showCompiler (OtherCompiler x) = x
    showCompiler (HaskellSuite x) = x
    showCompiler x = show x

showVersioned :: (String, VersionRange) -> Render Doc
showVersioned (pn, v')
  | v' == anyVersion = pure $ string pn
  | otherwise = fmap (string pn <+>) (showVersionRange v')

showVersionRange r = do
  opts <- ask
  return $
    cataVersionRange fold' $
    (if simplifyVersions opts
       then simplifyVersionRange
       else id)
      r
  where
    fold' AnyVersionF = empty
    fold' (ThisVersionF v) = green "==" <+> dullyellow (string (prettyShow v))
    fold' (LaterVersionF v) = green ">" <+> dullyellow (string (prettyShow v))
    fold' (OrLaterVersionF v) = green ">=" <+> dullyellow (string (prettyShow v))
    fold' (EarlierVersionF v) = green "<" <+> dullyellow (string (prettyShow v))
    fold' (OrEarlierVersionF v) = green "<=" <+> dullyellow (string (prettyShow v))
    fold' (WildcardVersionF v) = green "==" <+> dullyellow (string (prettyShow v) <> ".*")
    fold' (MajorBoundVersionF v) = green "^>=" <+> dullyellow (string (prettyShow v))
    fold' (UnionVersionRangesF a b) = a <+> green "||" <+> b
    fold' (IntersectVersionRangesF a b) = a <+> green "&&" <+> b
    fold' (VersionRangeParensF a) = parens a

filepath :: String -> Doc
filepath x
  | null x = string "\"\""
  | any isSpace x = string $ show x
  | otherwise = string x

moduleDoc = string . intercalate "." . components

rexpModuleDoc (ModuleReexport pkg origname name) =
  maybe empty (\f -> string (unPackageName f) <> colon) pkg <>
  (if origname == name
     then moduleDoc origname
     else moduleDoc origname <+> "as" <+> moduleDoc name)

exeDependencyAsDependency (ExeDependency pkg comp vers) =
  (P $ unPackageName pkg ++ ":" ++ unUnqualComponentName comp, vers)

renderBlockHead (If c) = (dullblue "if" <+>) <$> showPredicate c
renderBlockHead x = pure $ r x
  where
    r CustomSetup = dullgreen "custom-setup"
    r (SourceRepo_ k) = dullgreen "source-repository" <+> showKind k
      where
        showKind RepoHead = "head"
        showKind RepoThis = "this"
        showKind (RepoKindUnknown y) = string y
    r (Library_ Nothing) = dullgreen "library"
    r (Library_ (Just l)) = dullgreen "library" <+> string l
    r (ForeignLib_ l) = dullgreen "foreign-library" <+> string l
    r (Exe_ e) = dullgreen "executable" <+> string e
    r (TestSuite_ t) = dullgreen "test-suite" <+> string t
    r (Benchmark_ b) = dullgreen "benchmark" <+> string b
    r (Flag_ s) = dullgreen "flag" <+> string s
    r Else = dullblue "else"
    r _ = error "unreachable"

showPredicate :: Condition ConfVar -> Render Doc
showPredicate (Var x) = showVar x
showPredicate (CNot p) = fmap (dullmagenta (string "!") <>) (maybeParens p)
showPredicate (CAnd a b) =
  liftM2 (\x y -> x <+> dullblue (string "&&") <+> y) (maybeParens a) (maybeParens b)
showPredicate (COr a b) =
  liftM2 (\x y -> x <+> dullblue (string "||") <+> y) (maybeParens a) (maybeParens b)
showPredicate (Lit b) = pure $ string $ show b

maybeParens p =
  case p of
    Lit {} -> showPredicate p
    Var {} -> showPredicate p
    CNot {} -> showPredicate p
    _ -> parens <$> showPredicate p

showVar :: ConfVar -> Render Doc
showVar (Impl compiler vers) = do
  v <- showVersioned (prettyShow compiler, vers)
  pure $ dullgreen $ string "impl" <> parens (dullblue v)
showVar (Flag f) =
  pure $ dullgreen $ string "flag" <> parens (dullblue $ string (unFlagName f))
showVar (OS w) =
  pure $ dullgreen $ string "os" <> parens (dullblue $ string $ map toLower $ show w)
showVar (Arch a) =
  pure $ dullgreen $ string "arch" <> parens (dullblue $ string $ map toLower $ show a)