1module Options.Applicative.Help.Pretty 2 ( module Text.PrettyPrint.ANSI.Leijen 3 , (.$.) 4 , groupOrNestLine 5 , altSep 6 ) where 7 8import Control.Applicative 9import Data.Semigroup ((<>)) 10 11import Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>), columns) 12import Text.PrettyPrint.ANSI.Leijen.Internal (Doc (..), flatten) 13import qualified Text.PrettyPrint.ANSI.Leijen as PP 14 15import Prelude 16 17(.$.) :: Doc -> Doc -> Doc 18(.$.) = (PP.<$>) 19 20 21-- | Apply the function if we're not at the 22-- start of our nesting level. 23ifNotAtRoot :: (Doc -> Doc) -> Doc -> Doc 24ifNotAtRoot f doc = 25 Nesting $ \i -> 26 Column $ \j -> 27 if i == j 28 then doc 29 else f doc 30 31 32-- | Render flattened text on this line, or start 33-- a new line before rendering any text. 34-- 35-- This will also nest subsequent lines in the 36-- group. 37groupOrNestLine :: Doc -> Doc 38groupOrNestLine = 39 Union 40 <$> flatten 41 <*> ifNotAtRoot (line <>) . nest 2 42 43 44-- | Separate items in an alternative with a pipe. 45-- 46-- If the first document and the pipe don't fit 47-- on the line, then mandatorily flow the next entry 48-- onto the following line. 49-- 50-- The (<//>) softbreak ensures that if the document 51-- does fit on the line, there is at least a space, 52-- but it's possible for y to still appear on the 53-- next line. 54altSep :: Doc -> Doc -> Doc 55altSep x y = 56 group (x <+> char '|' <> line) <//> y 57