77 lines
1.8 KiB
Haskell
77 lines
1.8 KiB
Haskell
module PDF.Output (
|
|
OBuilder(..)
|
|
, Output(..)
|
|
, byteString
|
|
, char
|
|
, join
|
|
, lift
|
|
, newLine
|
|
, nextLine
|
|
, string
|
|
, render
|
|
) where
|
|
|
|
import Data.ByteString.Builder (Builder, char8, lazyByteString, string8, toLazyByteString)
|
|
import Data.ByteString.Lazy.Char8 (ByteString)
|
|
import Data.String (IsString(..))
|
|
import Control.Monad.Reader (MonadReader(..), Reader, runReader)
|
|
import qualified PDF.EOL as EOL (Style(..))
|
|
|
|
newtype OBuilder = OBuilder (Reader EOL.Style Builder)
|
|
|
|
lift :: (a -> Builder) -> a -> OBuilder
|
|
lift f a = OBuilder $ return (f a)
|
|
|
|
instance Monoid OBuilder where
|
|
mempty = OBuilder (return mempty)
|
|
mappend (OBuilder a) (OBuilder b) = OBuilder (mappend <$> a <*> b)
|
|
|
|
instance IsString OBuilder where
|
|
fromString = string
|
|
|
|
class Output a where
|
|
output :: a -> OBuilder
|
|
|
|
instance Output OBuilder where
|
|
output = id
|
|
|
|
instance Output Bool where
|
|
output False = string "false"
|
|
output True = string "true"
|
|
|
|
instance Output Float where
|
|
output = string . show
|
|
|
|
instance Output a => Output [a] where
|
|
output = foldl mappend mempty . fmap output
|
|
|
|
join :: Output a => String -> [a] -> OBuilder
|
|
join _ [] = mempty
|
|
join _ [a] = output a
|
|
join separator (a:as) =
|
|
output a `mappend` string separator `mappend` (join separator as)
|
|
|
|
newLine :: OBuilder
|
|
newLine = OBuilder $ buildEOL <$> ask
|
|
where
|
|
buildEOL EOL.CR = char8 '\r'
|
|
buildEOL EOL.LF = char8 '\n'
|
|
buildEOL EOL.CRLF = string8 "\r\n"
|
|
|
|
nextLine :: OBuilder -> OBuilder -> OBuilder
|
|
nextLine a b = a `mappend` newLine `mappend` b
|
|
|
|
char :: Char -> OBuilder
|
|
char = lift char8
|
|
|
|
string :: String -> OBuilder
|
|
string = lift string8
|
|
|
|
byteString :: ByteString -> OBuilder
|
|
byteString = lift lazyByteString
|
|
|
|
render :: Output a => EOL.Style -> a -> ByteString
|
|
render eolStyle a =
|
|
let OBuilder r = output a in
|
|
toLazyByteString $ runReader r eolStyle
|