module ZMidi.Core.Internal.SimpleFormat
(
Doc
, width
, output
, sep
, ssep
, char
, text
, multiply
, padl
, padr
, hex2
, hex4
, integral
) where
import Data.Monoid
import Data.Word
import Numeric
type H a = [a] -> [a]
type HString = H Char
spaceH :: Int -> HString
spaceH n = showString $ replicate n ' '
fromH :: H a -> [a]
fromH = ($ [])
data Doc = Doc { width :: !Int, doch :: HString }
doc :: String -> Doc
doc s = Doc (length s) (showString s)
output :: Doc -> String
output = fromH . doch
instance Monoid Doc where
mempty = Doc 0 id
Doc i1 f1 `mappend` Doc i2 f2 = Doc (i1+i2) (f1 . f2)
infixr 6 `sep`
sep :: Doc -> Doc -> Doc
sep = mappend
infixr 6 `ssep`
ssep :: Doc -> Doc -> Doc
ssep (Doc i1 f1) (Doc i2 f2) = Doc (1+i1+i2) (f1 . (' ':) . f2)
char :: Char -> Doc
char c = Doc 1 (c:)
text :: String -> Doc
text = doc
multiply :: Int -> Char -> Doc
multiply n c = Doc n (showString $ replicate n c)
padl :: Int -> Doc -> Doc
padl i d@(Doc n f) | i > n = Doc i (spaceH (in) . f)
| otherwise = d
padr :: Int -> Doc -> Doc
padr i d@(Doc n f) | i > n = Doc i (f . spaceH (in))
| otherwise = d
hex2 :: Word8 -> Doc
hex2 n | n < 0x10 = Doc 2 (('0' :) . showHex n)
| otherwise = Doc 2 (showHex n)
hex4 :: Word16 -> Doc
hex4 n | n < 0x10 = Doc 4 (('0':) . ('0':) . ('0':) . showHex n)
| n < 0x100 = Doc 4 (('0':) . ('0':) . showHex n)
| n < 0x1000 = Doc 4 (('0':) . showHex n)
| otherwise = Doc 4 (showHex n)
integral :: Integral a => a -> Doc
integral = doc . show