From 51a3979480d3abed9929227912ffe89d24e85dbb Mon Sep 17 00:00:00 2001 From: Julien Moutinho <julm+symantic@autogeree.net> Date: Mon, 12 Mar 2018 06:18:54 +0100 Subject: [PATCH] Polish symantic-document. --- .../Language/Symantic/Document/Sym.hs | 67 ++++++++++--------- .../Language/Symantic/Document/Term.hs | 16 ++--- .../Symantic/Document/Term/Dimension.hs | 17 ++--- .../Language/Symantic/Document/Term/IO.hs | 26 +++---- 4 files changed, 58 insertions(+), 68 deletions(-) diff --git a/symantic-document/Language/Symantic/Document/Sym.hs b/symantic-document/Language/Symantic/Document/Sym.hs index 71ede01..b8c4970 100644 --- a/symantic-document/Language/Symantic/Document/Sym.hs +++ b/symantic-document/Language/Symantic/Document/Sym.hs @@ -12,8 +12,8 @@ import Data.Maybe (Maybe(..)) import Data.Ord (Ord(..), Ordering(..)) import Data.Semigroup (Semigroup(..)) import Data.String (String, IsString) -import Prelude (Integer, toInteger, fromIntegral, Num(..), undefined, Integral, Real, Enum) -import Text.Show (Show) +import Prelude (Integer, fromIntegral, Num(..), pred, undefined, Integral, Real, Enum) +import Text.Show (Show(..)) import qualified Data.List as List import qualified Data.Text as Text import qualified Data.Text.Lazy as TL @@ -53,6 +53,7 @@ type Indent = Column -- * Class 'Textable' class (IsString d, Semigroup d) => Textable d where + empty :: d charH :: Char -- ^ XXX: MUST NOT be '\n' -> d stringH :: String -- ^ XXX: MUST NOT contain '\n' @@ -61,22 +62,17 @@ class (IsString d, Semigroup d) => Textable d where -> d ltextH :: TL.Text -- ^ XXX: MUST NOT contain '\n' -> d - replicate :: Int -> d -> d - integer :: Integer -> d - default replicate :: Textable (ReprOf d) => Trans d => Int -> d -> d - default integer :: Textable (ReprOf d) => Trans d => Integer -> d + default empty :: Textable (ReprOf d) => Trans d => d default charH :: Textable (ReprOf d) => Trans d => Char -> d default stringH :: Textable (ReprOf d) => Trans d => String -> d default textH :: Textable (ReprOf d) => Trans d => Text.Text -> d default ltextH :: Textable (ReprOf d) => Trans d => TL.Text -> d - charH = trans . charH - stringH = trans . stringH - textH = trans . textH - ltextH = trans . ltextH - replicate = trans1 . replicate - integer = trans . integer + empty = trans empty + charH = trans . charH + stringH = trans . stringH + textH = trans . textH + ltextH = trans . ltextH - empty :: d newline :: d space :: d -- | @x '<+>' y = x '<>' 'space' '<>' y@ @@ -84,6 +80,7 @@ class (IsString d, Semigroup d) => Textable d where -- | @x '</>' y = x '<>' 'newline' '<>' y@ (</>) :: d -> d -> d int :: Int -> d + integer :: Integer -> d char :: Char -> d string :: String -> d text :: Text.Text -> d @@ -94,34 +91,31 @@ class (IsString d, Semigroup d) => Textable d where foldWith :: Foldable f => (d -> d) -> f d -> d intercalate :: Foldable f => d -> f d -> d between :: d -> d -> d -> d + replicate :: Int -> d -> d - newline = "\n" - space = char ' ' - x <+> y = x <> space <> y - x </> y = x <> newline <> y - int = integer . toInteger - char = \case '\n' -> newline; c -> charH c - string = catV . fmap stringH . lines - text = catV . fmap textH . Text.lines - ltext = catV . fmap ltextH . TL.lines - catH = foldr (<>) empty - catV = foldrWith (\x y -> x<>newline<>y) + newline = "\n" + space = char ' ' + x <+> y = x <> space <> y + x </> y = x <> newline <> y + int = stringH . show + integer = stringH . show + char = \case '\n' -> newline; c -> charH c + string = catV . fmap stringH . lines + text = catV . fmap textH . Text.lines + ltext = catV . fmap ltextH . TL.lines + catH = foldr (<>) empty + catV = foldrWith (\x y -> x<>newline<>y) foldrWith f ds = if null ds then empty else foldr1 f ds foldWith f = foldrWith $ \a acc -> a <> f acc intercalate sep = foldrWith (\x y -> x<>sep<>y) between o c d = o<>d<>c - -- default catH :: Textable (ReprOf d) => Trans d => Foldable f => Functor f => f d -> d - -- default catV :: Textable (ReprOf d) => Trans d => Foldable f => Functor f => f d -> d - -- catH l = trans (catH (fmap unTrans l)) - -- catV l = trans (catV (fmap unTrans l)) + replicate cnt t | cnt <= 0 = empty + | otherwise = t <> replicate (pred cnt) t -- * Class 'Indentable' class Textable d => Indentable d where -- | @('align' d)@ make @d@ uses current 'Column' as 'Indent' level. align :: d -> d - -- | @('hang' ind d)@ make @d@ uses current 'Column' plus @ind@ as 'Indent' level. - hang :: Indent -> d -> d - hang ind = align . incrIndent ind -- | @('incrIndent' ind d)@ make @d@ uses current 'Indent' plus @ind@ as 'Indent' level. incrIndent :: Indent -> d -> d -- | @('withIndent' ind d)@ make @d@ uses @ind@ as 'Indent' level. @@ -136,6 +130,11 @@ class Textable d => Indentable d where column :: (Column -> d) -> d -- | @('indent' f)@ write @f@ applied to the current 'Indent'. indent :: (Indent -> d) -> d + + -- | @('hang' ind d)@ make @d@ uses current 'Column' plus @ind@ as 'Indent' level. + hang :: Indent -> d -> d + hang ind = align . incrIndent ind + -- | @('endToEndWidth' d f)@ write @d@ then -- @f@ applied to the difference between -- the end 'Column' and start 'Column' of @d@. @@ -186,23 +185,29 @@ class (Textable d, Indentable d) => Breakable d where -- write @onNoBreak@ then @d@ if they fit, -- @onBreak@ otherwise. breakpoint :: d -> d -> d -> d + -- | @('breakableEmpty' d)@ write @d@ if it fits, 'newline' then @d@ otherwise. breakableEmpty :: d -> d breakableEmpty = breakpoint empty newline + -- | @x '><' y = x '<>' 'breakableEmpty' y@ (><) :: d -> d -> d x >< y = x <> breakableEmpty y + -- | @('breakableSpace' d)@ write 'space' then @d@ it they fit, -- 'newline' then @d@ otherwise. breakableSpace :: d -> d breakableSpace = breakpoint space newline + -- | @x '>+<' y = x '<>' 'breakableSpace' y@ (>+<) :: d -> d -> d x >+< y = x <> breakableSpace y + -- | @'breakableSpaces' ds@ intercalate a 'breakableSpace' -- between items of @ds@. breakableSpaces :: Foldable f => f d -> d breakableSpaces = foldWith breakableSpace + -- | @('intercalateHorV' sep ds)@ -- write @ds@ with @sep@ intercalated if the whole fits, -- otherwise write 'align' of @ds@ with 'newline' and @sep@ intercalated. diff --git a/symantic-document/Language/Symantic/Document/Term.hs b/symantic-document/Language/Symantic/Document/Term.hs index 78dfe42..4658033 100644 --- a/symantic-document/Language/Symantic/Document/Term.hs +++ b/symantic-document/Language/Symantic/Document/Term.hs @@ -14,7 +14,6 @@ import Data.String (IsString(..)) import GHC.Exts (IsList(..)) import Prelude (pred, fromIntegral, Num(..)) import System.Console.ANSI -import Text.Show (Show(..)) import qualified Data.List as List import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Builder as TLB @@ -102,8 +101,6 @@ instance Textable Term where stringH t = writeH (length t) (fromString t) textH t = writeH (length t) (TLB.fromText t) ltextH t = writeH (length t) (TLB.fromLazyText t) - int = stringH . show - integer = stringH . show replicate cnt t | cnt <= 0 = empty | otherwise = t <> replicate (pred cnt) t newline = Term $ \ro -> unTerm (reader_newline ro) ro @@ -129,11 +126,10 @@ instance Breakable Term where Nothing -> ko Just{} -> (\_sx _tx -> unTerm y ro st ok ko) breakpoint onNoBreak onBreak t = Term $ \ro st ok ko -> + unTerm (onNoBreak <> t) ro st ok $ case reader_breakable ro of - Nothing -> unTerm t ro st ok ko - Just{} -> - unTerm (onNoBreak <> t) ro st ok - (\_sp _tp -> unTerm (onBreak <> t) ro st ok ko) + Nothing -> ko + Just{} -> (\_sp _tp -> unTerm (onBreak <> t) ro st ok ko) writeSGR :: (Reader -> Bool) -> SGR -> Term -> Term writeSGR isOn s (Term t) = @@ -185,6 +181,6 @@ instance Colorable Term where instance Decorable Term where decorable f = Term $ \ro -> unTerm (f (reader_decorable ro)) ro withDecorable b t = Term $ \ro -> unTerm t ro{reader_decorable=b} - bold = writeSGR reader_decorable $ SetConsoleIntensity BoldIntensity - underline = writeSGR reader_decorable $ SetUnderlining SingleUnderline - italic = writeSGR reader_decorable $ SetItalicized True + bold = writeSGR reader_decorable $ SetConsoleIntensity BoldIntensity + underline = writeSGR reader_decorable $ SetUnderlining SingleUnderline + italic = writeSGR reader_decorable $ SetItalicized True diff --git a/symantic-document/Language/Symantic/Document/Term/Dimension.hs b/symantic-document/Language/Symantic/Document/Term/Dimension.hs index 7ceb685..634e378 100644 --- a/symantic-document/Language/Symantic/Document/Term/Dimension.hs +++ b/symantic-document/Language/Symantic/Document/Term/Dimension.hs @@ -13,7 +13,7 @@ import Data.Ord (Ord(..)) import Data.Semigroup (Semigroup(..)) import Data.String (IsString(..)) import GHC.Exts (IsList(..)) -import Prelude ((+), pred) +import Prelude ((+)) import Text.Show (Show(..)) import Language.Symantic.Document.Sym @@ -54,7 +54,7 @@ defReader :: Reader defReader = Reader { reader_indent = 0 , reader_newline = newlineWithIndent - , reader_breakable = Just $ Nat 80 + , reader_breakable = Nothing , reader_colorable = True , reader_decorable = True } @@ -117,11 +117,7 @@ instance Textable Dimension where stringH = writeH . length textH = writeH . length ltextH = writeH . length - int = stringH . show - integer = stringH . show - replicate cnt p | cnt <= 0 = empty - | otherwise = p <> replicate (pred cnt) p - newline = Dimension $ \ro -> unDimension (reader_newline ro) ro + newline = Dimension $ \ro -> unDimension (reader_newline ro) ro instance Indentable Dimension where align p = Dimension $ \ro st -> unDimension p ro{reader_indent=st} st withNewline nl p = Dimension $ \ro -> unDimension p ro{reader_newline=nl} @@ -154,11 +150,10 @@ instance Breakable Dimension where Nothing -> ko Just{} -> (\_sx _tx -> unDimension y ro st ok ko) breakpoint onNoBreak onBreak t = Dimension $ \ro st ok ko -> + unDimension (onNoBreak <> t) ro st ok $ case reader_breakable ro of - Nothing -> unDimension t ro st ok ko - Just{} -> - unDimension (onNoBreak <> t) ro st ok - (\_sp _tp -> unDimension (onBreak <> t) ro st ok ko) + Nothing -> ko + Just{} -> (\_sp _tp -> unDimension (onBreak <> t) ro st ok ko) instance Colorable Dimension where colorable f = Dimension $ \ro -> unDimension (f (reader_colorable ro)) ro withColorable b t = Dimension $ \ro -> unDimension t ro{reader_colorable=b} diff --git a/symantic-document/Language/Symantic/Document/Term/IO.hs b/symantic-document/Language/Symantic/Document/Term/IO.hs index 66c6e52..cf53460 100644 --- a/symantic-document/Language/Symantic/Document/Term/IO.hs +++ b/symantic-document/Language/Symantic/Document/Term/IO.hs @@ -5,17 +5,16 @@ module Language.Symantic.Document.Term.IO import Control.Applicative (Applicative(..)) import Data.Bool -import Data.Function (($), (.), id) +import Data.Function (($), id) import Data.Maybe (Maybe(..)) import Data.Monoid (Monoid(..)) import Data.Ord (Ord(..)) import Data.Semigroup (Semigroup(..)) import Data.String (IsString(..)) import GHC.Exts (IsList(..)) -import Prelude (pred, fromIntegral, Num(..)) +import Prelude (fromIntegral, Num(..)) import System.Console.ANSI import System.IO (IO) -import Text.Show (Show(..)) import qualified Data.List as List import qualified Data.Text.IO as Text import qualified Data.Text.Lazy.IO as TL @@ -42,7 +41,7 @@ defReader = Reader , reader_newline = newlineWithIndent , reader_sgr = [] , reader_handle = IO.stdout - , reader_breakable = Just $ Nat 80 + , reader_breakable = Nothing , reader_colorable = True , reader_decorable = True } @@ -101,11 +100,7 @@ instance Textable TermIO where stringH t = writeH (length t) (`IO.hPutStr` t) textH t = writeH (length t) (`Text.hPutStr` t) ltextH t = writeH (length t) (`TL.hPutStr` t) - int = stringH . show - integer = stringH . show - replicate cnt t | cnt <= 0 = empty - | otherwise = t <> replicate (pred cnt) t - newline = TermIO $ \ro -> unTermIO (reader_newline ro) ro + newline = TermIO $ \ro -> unTermIO (reader_newline ro) ro instance Indentable TermIO where align t = TermIO $ \ro st -> unTermIO t ro{reader_indent=st} st withNewline nl t = TermIO $ \ro -> unTermIO t ro{reader_newline=nl} @@ -128,11 +123,10 @@ instance Breakable TermIO where Nothing -> ko Just{} -> (\_sx _tx -> unTermIO y ro st ok ko) breakpoint onNoBreak onBreak t = TermIO $ \ro st ok ko -> + unTermIO (onNoBreak <> t) ro st ok $ case reader_breakable ro of - Nothing -> unTermIO t ro st ok ko - Just{} -> - unTermIO (onNoBreak <> t) ro st ok - (\_sp _tp -> unTermIO (onBreak <> t) ro st ok ko) + Nothing -> ko + Just{} -> (\_sp _tp -> unTermIO (onBreak <> t) ro st ok ko) writeSGR :: (Reader -> Bool) -> SGR -> TermIO -> TermIO writeSGR isOn s (TermIO t) = @@ -184,6 +178,6 @@ instance Colorable TermIO where instance Decorable TermIO where decorable f = TermIO $ \ro -> unTermIO (f (reader_decorable ro)) ro withDecorable b t = TermIO $ \ro -> unTermIO t ro{reader_decorable=b} - bold = writeSGR reader_decorable $ SetConsoleIntensity BoldIntensity - underline = writeSGR reader_decorable $ SetUnderlining SingleUnderline - italic = writeSGR reader_decorable $ SetItalicized True + bold = writeSGR reader_decorable $ SetConsoleIntensity BoldIntensity + underline = writeSGR reader_decorable $ SetUnderlining SingleUnderline + italic = writeSGR reader_decorable $ SetItalicized True -- 2.47.2