{-# LANGUAGE OverloadedStrings #-} module Turtle.Options.Scale ( Scale(..) , optScale , defScaleHelp , scale ) where import Turtle (ArgName, ShortName, HelpMessage, opt) import Data.Optional (Optional) import qualified Turtle import qualified Data.Text as Text import Control.Applicative ((<$>), (<*>), (*>), (<*)) import Text.Parsec import Turtle.Options.Parsers (Parser, percent, float) data Scale = Percentage Float | Size (Int, Int) | Width Int | Height Int deriving (Eq, Show) defScaleHelp :: Optional HelpMessage defScaleHelp = "Scale option. SCALE can be a percentage (20%), a size (480x320), a width (480x) or a height (x320)" width :: Parser Scale width = Width . read <$> try (many1 digit <* char 'x') height :: Parser Scale height = Height . read <$> try (char 'x' *> many1 digit) size :: Parser Scale size = Size <$> try (do w <- read <$> many1 digit <* char 'x' h <- read <$> many1 digit return (w, h)) percentage :: Parser Scale percentage = choice [try p, f] where f = do v <- float case v < 0 of True -> error "Error parsing scale: can't have a negative scale" False -> return $ Percentage v p = do v <- percent case v < 0 of True -> error "Error parsing scale percentage: can't have a negative value" False -> return $ Percentage v scale :: Parser Scale scale = choice [size, percentage, width, height] readScale :: String -> Maybe Scale readScale str = case (parse scale "Scale" str) of Left err -> error $ "Error parsing scale: " ++ (show err) Right s -> Just s optScale :: ArgName -> ShortName -> Optional HelpMessage -> Turtle.Parser Scale optScale = opt (readScale . Text.unpack)