atomo-0.4: src/Atomo/Kernel/Pretty.hs
{-# LANGUAGE QuasiQuotes #-}
module Atomo.Kernel.Pretty (load) where
import Text.PrettyPrint
import Atomo as A
import Atomo.Pretty
import Atomo.Valuable
load :: VM ()
load = do
([$p|Pretty|] =::) =<< eval [$e|Object clone|]
[$p|(o: Object) pretty|] =:
here "o" >>= toValue . pretty
[$p|(p: -> Pretty) pretty|] =::: [$e|p|]
-- Converting values to documents
[$p|Pretty char: (c: Character)|] =:
here "c" >>= findCharacter >>= toValue . char . fromCharacter
[$p|Pretty text: (s: String)|] =:
getString [$e|s|] >>= toValue . text
[$p|Pretty zero-width-text: (s: String)|] =:
getString [$e|s|] >>= toValue . zeroWidthText
[$p|Pretty int: (i: Integer)|] =:
here "i" >>= findInteger >>= toValue . integer . A.fromInteger
[$p|Pretty integer: (i: Integer)|] =:
here "i" >>= findInteger >>= toValue . integer . A.fromInteger
[$p|Pretty float: (d: Double)|] =:
here "d" >>= findDouble >>= toValue . double . fromDouble
[$p|Pretty double: (d: Double)|] =:
here "d" >>= findDouble >>= toValue . double . fromDouble
[$p|Pretty rational: (r: Rational)|] =:
here "r" >>= findRational
>>= toValue . rational . (\(Rational r) -> r)
-- Simple derived documents
[$p|Pretty semi|] =: toValue semi
[$p|Pretty comma|] =: toValue comma
[$p|Pretty colon|] =: toValue colon
[$p|Pretty space|] =: toValue space
[$p|Pretty equals|] =: toValue equals
[$p|Pretty lparen|] =: toValue lparen
[$p|Pretty rparen|] =: toValue rparen
[$p|Pretty lbrack|] =: toValue lbrack
[$p|Pretty rbrack|] =: toValue rbrack
[$p|Pretty lbrace|] =: toValue lbrace
[$p|Pretty rbrace|] =: toValue rbrace
-- Wrapping documents in delimiters
[$p|Pretty parens: (p: Pretty)|] =:
here "p" >>= fromValue >>= toValue . parens
[$p|Pretty brackets: (p: Pretty)|] =:
here "p" >>= fromValue >>= toValue . brackets
[$p|Pretty braces: (p: Pretty)|] =:
here "p" >>= fromValue >>= toValue . braces
[$p|Pretty quotes: (p: Pretty)|] =:
here "p" >>= fromValue >>= toValue . quotes
[$p|Pretty double-quotes: (p: Pretty)|] =:
here "p" >>= fromValue >>= toValue . doubleQuotes
-- Combining documents
[$p|Pretty empty|] =: toValue empty
[$p|(a: Pretty) <> (b: Pretty)|] =: do
liftM2 (<>) (here "a" >>= fromValue) (here "b" >>= fromValue)
>>= toValue
[$p|(a: Pretty) <+> (b: Pretty)|] =: do
liftM2 (<+>) (here "a" >>= fromValue) (here "b" >>= fromValue)
>>= toValue
[$p|Pretty hcat: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . hcat
[$p|Pretty hsep: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . hsep
[$p|(a: Pretty) \\ (b: Pretty)|] =: do
liftM2 ($$) (here "a" >>= fromValue) (here "b" >>= fromValue)
>>= toValue
[$p|(a: Pretty) \+\ (b: Pretty)|] =: do
liftM2 ($+$) (here "a" >>= fromValue) (here "b" >>= fromValue)
>>= toValue
[$p|Pretty vcat: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . vcat
[$p|Pretty sep: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . sep
[$p|Pretty cat: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . cat
[$p|Pretty fsep: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . fsep
[$p|Pretty fcat: (ps: List)|] =: do
getList [$e|ps|] >>= mapM fromValue >>= toValue . fcat
[$p|(p: Pretty) nest: (i: Integer)|] =: do
d <- here "p" >>= fromValue
i <- here "i" >>= liftM (fromIntegral . A.fromInteger) . findInteger
toValue (nest i d)
[$p|(a: Pretty) hang: (b: Pretty) indented: (i: Integer)|] =: do
a <- here "a" >>= fromValue
b <- here "b" >>= fromValue
i <- here "i" >>= liftM (fromIntegral . A.fromInteger) . findInteger
toValue (hang a i b)
[$p|(delimiter: Pretty) punctuate: (ps: List)|] =: do
d <- here "delimiter" >>= fromValue
ps <- getList [$e|ps|] >>= mapM fromValue
liftM list (mapM toValue (punctuate d ps))
-- Predicates on documents
[$p|(p: Pretty) empty?|] =:
liftM (Boolean . isEmpty) (here "p" >>= fromValue)
-- Rendering documents
[$p|(p: -> Pretty) render &mode: @page &line-length: 100 &ribbons-per-line: 1.5|] =: do
d <- here "p" >>= fromValue
m <- here "mode" >>= findParticle
sl <- here "line-length" >>= liftM (fromIntegral . A.fromInteger) . findInteger
sr <- here "ribbons-per-line" >>= liftM (fromRational . toRational . fromDouble) . findDouble
sm <-
case m of
Particle (Single { mName = "page" }) ->
return PageMode
Particle (Single { mName = "zig-zag" }) ->
return ZigZagMode
Particle (Single { mName = "left" }) ->
return LeftMode
Particle (Single { mName = "one-line" }) ->
return OneLineMode
_ ->
raise ["unknown-render-mode", "must-be"]
[ m
, list
[ particle "page"
, particle "zig-zag"
, particle "left"
, particle "one-line"
]
]
return (string (renderStyle (Style sm sl sr) d))