{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
module Text.DocLayout (
render
, cr
, blankline
, blanklines
, space
, literal
, text
, char
, prefixed
, flush
, nest
, hang
, beforeNonBlank
, nowrap
, afterBreak
, lblock
, cblock
, rblock
, vfill
, nestle
, chomp
, inside
, braces
, brackets
, parens
, quotes
, doubleQuotes
, empty
, (<+>)
, ($$)
, ($+$)
, hcat
, hsep
, vcat
, vsep
, isEmpty
, offset
, minOffset
, updateColumn
, height
, charWidth
, realLength
, realLengthNarrowContext
, realLengthWideContext
, realLengthNarrowContextNoShortcut
, realLengthWideContextNoShortcut
, isSkinToneModifier
, isEmojiVariation
, isZWJ
, unfoldD
, Doc(..)
, HasChars(..)
)
where
import Prelude
import Data.Maybe (fromMaybe, isJust, mapMaybe)
import Safe (lastMay, initSafe)
import Control.Monad
import Control.Monad.State.Strict
import GHC.Generics
import Data.Bifunctor (second)
import Data.Char (isSpace, ord)
import Data.List (foldl', intersperse)
import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import qualified Data.Map.Internal as MInt
import Data.Data (Data, Typeable)
import Data.String
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.Text (Text)
#if MIN_VERSION_base(4,11,0)
#else
import Data.Semigroup
#endif
import Text.Emoji (baseEmojis)
class (IsString a, Semigroup a, Monoid a, Show a) => HasChars a where
foldrChar :: (Char -> b -> b) -> b -> a -> b
foldlChar :: (b -> Char -> b) -> b -> a -> b
replicateChar :: Int -> Char -> a
replicateChar Int
n Char
c = String -> a
forall a. IsString a => String -> a
fromString (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n Char
c)
isNull :: a -> Bool
isNull = (Char -> Bool -> Bool) -> Bool -> a -> Bool
forall a b. HasChars a => (Char -> b -> b) -> b -> a -> b
foldrChar (\Char
_ Bool
_ -> Bool
False) Bool
True
splitLines :: a -> [a]
splitLines a
s = (String -> a
forall a. IsString a => String -> a
fromString String
firstline a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
otherlines)
where
(String
firstline, [a]
otherlines) = (Char -> (String, [a]) -> (String, [a]))
-> (String, [a]) -> a -> (String, [a])
forall a b. HasChars a => (Char -> b -> b) -> b -> a -> b
foldrChar Char -> (String, [a]) -> (String, [a])
forall a. IsString a => Char -> (String, [a]) -> (String, [a])
go ([],[]) a
s
go :: Char -> (String, [a]) -> (String, [a])
go Char
'\n' (String
cur,[a]
lns) = ([], String -> a
forall a. IsString a => String -> a
fromString String
cur a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
lns)
go Char
c (String
cur,[a]
lns) = (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
cur, [a]
lns)
instance HasChars Text where
foldrChar :: (Char -> b -> b) -> b -> Text -> b
foldrChar = (Char -> b -> b) -> b -> Text -> b
forall b. (Char -> b -> b) -> b -> Text -> b
T.foldr
foldlChar :: (b -> Char -> b) -> b -> Text -> b
foldlChar = (b -> Char -> b) -> b -> Text -> b
forall b. (b -> Char -> b) -> b -> Text -> b
T.foldl'
splitLines :: Text -> [Text]
splitLines = Text -> Text -> [Text]
T.splitOn Text
"\n"
replicateChar :: Int -> Char -> Text
replicateChar Int
n Char
c = Int -> Text -> Text
T.replicate Int
n (Char -> Text
T.singleton Char
c)
isNull :: Text -> Bool
isNull = Text -> Bool
T.null
instance HasChars String where
foldrChar :: (Char -> b -> b) -> b -> String -> b
foldrChar = (Char -> b -> b) -> b -> String -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
foldlChar :: (b -> Char -> b) -> b -> String -> b
foldlChar = (b -> Char -> b) -> b -> String -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
splitLines :: String -> [String]
splitLines = String -> [String]
lines (String -> [String]) -> (String -> String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\n")
replicateChar :: Int -> Char -> String
replicateChar = Int -> Char -> String
forall a. Int -> a -> [a]
replicate
isNull :: String -> Bool
isNull = String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
instance HasChars TL.Text where
foldrChar :: (Char -> b -> b) -> b -> Text -> b
foldrChar = (Char -> b -> b) -> b -> Text -> b
forall b. (Char -> b -> b) -> b -> Text -> b
TL.foldr
foldlChar :: (b -> Char -> b) -> b -> Text -> b
foldlChar = (b -> Char -> b) -> b -> Text -> b
forall b. (b -> Char -> b) -> b -> Text -> b
TL.foldl'
splitLines :: Text -> [Text]
splitLines = Text -> Text -> [Text]
TL.splitOn Text
"\n"
replicateChar :: Int -> Char -> Text
replicateChar Int
n Char
c = Int64 -> Text -> Text
TL.replicate (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) (Char -> Text
TL.singleton Char
c)
isNull :: Text -> Bool
isNull = Text -> Bool
TL.null
data Doc a = Text Int a
| Block Int [a]
| VFill Int a
| Prefixed Text (Doc a)
| BeforeNonBlank (Doc a)
| Flush (Doc a)
| BreakingSpace
| AfterBreak Text
| CarriageReturn
| NewLine
| BlankLines Int
| Concat (Doc a) (Doc a)
| Empty
deriving (Int -> Doc a -> String -> String
[Doc a] -> String -> String
Doc a -> String
(Int -> Doc a -> String -> String)
-> (Doc a -> String)
-> ([Doc a] -> String -> String)
-> Show (Doc a)
forall a. Show a => Int -> Doc a -> String -> String
forall a. Show a => [Doc a] -> String -> String
forall a. Show a => Doc a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Doc a] -> String -> String
$cshowList :: forall a. Show a => [Doc a] -> String -> String
show :: Doc a -> String
$cshow :: forall a. Show a => Doc a -> String
showsPrec :: Int -> Doc a -> String -> String
$cshowsPrec :: forall a. Show a => Int -> Doc a -> String -> String
Show, ReadPrec [Doc a]
ReadPrec (Doc a)
Int -> ReadS (Doc a)
ReadS [Doc a]
(Int -> ReadS (Doc a))
-> ReadS [Doc a]
-> ReadPrec (Doc a)
-> ReadPrec [Doc a]
-> Read (Doc a)
forall a. Read a => ReadPrec [Doc a]
forall a. Read a => ReadPrec (Doc a)
forall a. Read a => Int -> ReadS (Doc a)
forall a. Read a => ReadS [Doc a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Doc a]
$creadListPrec :: forall a. Read a => ReadPrec [Doc a]
readPrec :: ReadPrec (Doc a)
$creadPrec :: forall a. Read a => ReadPrec (Doc a)
readList :: ReadS [Doc a]
$creadList :: forall a. Read a => ReadS [Doc a]
readsPrec :: Int -> ReadS (Doc a)
$creadsPrec :: forall a. Read a => Int -> ReadS (Doc a)
Read, Doc a -> Doc a -> Bool
(Doc a -> Doc a -> Bool) -> (Doc a -> Doc a -> Bool) -> Eq (Doc a)
forall a. Eq a => Doc a -> Doc a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Doc a -> Doc a -> Bool
$c/= :: forall a. Eq a => Doc a -> Doc a -> Bool
== :: Doc a -> Doc a -> Bool
$c== :: forall a. Eq a => Doc a -> Doc a -> Bool
Eq, Eq (Doc a)
Eq (Doc a)
-> (Doc a -> Doc a -> Ordering)
-> (Doc a -> Doc a -> Bool)
-> (Doc a -> Doc a -> Bool)
-> (Doc a -> Doc a -> Bool)
-> (Doc a -> Doc a -> Bool)
-> (Doc a -> Doc a -> Doc a)
-> (Doc a -> Doc a -> Doc a)
-> Ord (Doc a)
Doc a -> Doc a -> Bool
Doc a -> Doc a -> Ordering
Doc a -> Doc a -> Doc a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Doc a)
forall a. Ord a => Doc a -> Doc a -> Bool
forall a. Ord a => Doc a -> Doc a -> Ordering
forall a. Ord a => Doc a -> Doc a -> Doc a
min :: Doc a -> Doc a -> Doc a
$cmin :: forall a. Ord a => Doc a -> Doc a -> Doc a
max :: Doc a -> Doc a -> Doc a
$cmax :: forall a. Ord a => Doc a -> Doc a -> Doc a
>= :: Doc a -> Doc a -> Bool
$c>= :: forall a. Ord a => Doc a -> Doc a -> Bool
> :: Doc a -> Doc a -> Bool
$c> :: forall a. Ord a => Doc a -> Doc a -> Bool
<= :: Doc a -> Doc a -> Bool
$c<= :: forall a. Ord a => Doc a -> Doc a -> Bool
< :: Doc a -> Doc a -> Bool
$c< :: forall a. Ord a => Doc a -> Doc a -> Bool
compare :: Doc a -> Doc a -> Ordering
$ccompare :: forall a. Ord a => Doc a -> Doc a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Doc a)
Ord, a -> Doc b -> Doc a
(a -> b) -> Doc a -> Doc b
(forall a b. (a -> b) -> Doc a -> Doc b)
-> (forall a b. a -> Doc b -> Doc a) -> Functor Doc
forall a b. a -> Doc b -> Doc a
forall a b. (a -> b) -> Doc a -> Doc b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Doc b -> Doc a
$c<$ :: forall a b. a -> Doc b -> Doc a
fmap :: (a -> b) -> Doc a -> Doc b
$cfmap :: forall a b. (a -> b) -> Doc a -> Doc b
Functor, Doc a -> Bool
(a -> m) -> Doc a -> m
(a -> b -> b) -> b -> Doc a -> b
(forall m. Monoid m => Doc m -> m)
-> (forall m a. Monoid m => (a -> m) -> Doc a -> m)
-> (forall m a. Monoid m => (a -> m) -> Doc a -> m)
-> (forall a b. (a -> b -> b) -> b -> Doc a -> b)
-> (forall a b. (a -> b -> b) -> b -> Doc a -> b)
-> (forall b a. (b -> a -> b) -> b -> Doc a -> b)
-> (forall b a. (b -> a -> b) -> b -> Doc a -> b)
-> (forall a. (a -> a -> a) -> Doc a -> a)
-> (forall a. (a -> a -> a) -> Doc a -> a)
-> (forall a. Doc a -> [a])
-> (forall a. Doc a -> Bool)
-> (forall a. Doc a -> Int)
-> (forall a. Eq a => a -> Doc a -> Bool)
-> (forall a. Ord a => Doc a -> a)
-> (forall a. Ord a => Doc a -> a)
-> (forall a. Num a => Doc a -> a)
-> (forall a. Num a => Doc a -> a)
-> Foldable Doc
forall a. Eq a => a -> Doc a -> Bool
forall a. Num a => Doc a -> a
forall a. Ord a => Doc a -> a
forall m. Monoid m => Doc m -> m
forall a. Doc a -> Bool
forall a. Doc a -> Int
forall a. Doc a -> [a]
forall a. (a -> a -> a) -> Doc a -> a
forall m a. Monoid m => (a -> m) -> Doc a -> m
forall b a. (b -> a -> b) -> b -> Doc a -> b
forall a b. (a -> b -> b) -> b -> Doc a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Doc a -> a
$cproduct :: forall a. Num a => Doc a -> a
sum :: Doc a -> a
$csum :: forall a. Num a => Doc a -> a
minimum :: Doc a -> a
$cminimum :: forall a. Ord a => Doc a -> a
maximum :: Doc a -> a
$cmaximum :: forall a. Ord a => Doc a -> a
elem :: a -> Doc a -> Bool
$celem :: forall a. Eq a => a -> Doc a -> Bool
length :: Doc a -> Int
$clength :: forall a. Doc a -> Int
null :: Doc a -> Bool
$cnull :: forall a. Doc a -> Bool
toList :: Doc a -> [a]
$ctoList :: forall a. Doc a -> [a]
foldl1 :: (a -> a -> a) -> Doc a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Doc a -> a
foldr1 :: (a -> a -> a) -> Doc a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Doc a -> a
foldl' :: (b -> a -> b) -> b -> Doc a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Doc a -> b
foldl :: (b -> a -> b) -> b -> Doc a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Doc a -> b
foldr' :: (a -> b -> b) -> b -> Doc a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Doc a -> b
foldr :: (a -> b -> b) -> b -> Doc a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Doc a -> b
foldMap' :: (a -> m) -> Doc a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Doc a -> m
foldMap :: (a -> m) -> Doc a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Doc a -> m
fold :: Doc m -> m
$cfold :: forall m. Monoid m => Doc m -> m
Foldable, Functor Doc
Foldable Doc
Functor Doc
-> Foldable Doc
-> (forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Doc a -> f (Doc b))
-> (forall (f :: * -> *) a.
Applicative f =>
Doc (f a) -> f (Doc a))
-> (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Doc a -> m (Doc b))
-> (forall (m :: * -> *) a. Monad m => Doc (m a) -> m (Doc a))
-> Traversable Doc
(a -> f b) -> Doc a -> f (Doc b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Doc (m a) -> m (Doc a)
forall (f :: * -> *) a. Applicative f => Doc (f a) -> f (Doc a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Doc a -> m (Doc b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Doc a -> f (Doc b)
sequence :: Doc (m a) -> m (Doc a)
$csequence :: forall (m :: * -> *) a. Monad m => Doc (m a) -> m (Doc a)
mapM :: (a -> m b) -> Doc a -> m (Doc b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Doc a -> m (Doc b)
sequenceA :: Doc (f a) -> f (Doc a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Doc (f a) -> f (Doc a)
traverse :: (a -> f b) -> Doc a -> f (Doc b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Doc a -> f (Doc b)
$cp2Traversable :: Foldable Doc
$cp1Traversable :: Functor Doc
Traversable,
Typeable (Doc a)
DataType
Constr
Typeable (Doc a)
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a))
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a))
-> (Doc a -> Constr)
-> (Doc a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Doc a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Doc a)))
-> ((forall b. Data b => b -> b) -> Doc a -> Doc a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Doc a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Doc a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a))
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a))
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a))
-> Data (Doc a)
Doc a -> DataType
Doc a -> Constr
(forall d. Data d => c (t d)) -> Maybe (c (Doc a))
(forall b. Data b => b -> b) -> Doc a -> Doc a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a)
forall a. Data a => Typeable (Doc a)
forall a. Data a => Doc a -> DataType
forall a. Data a => Doc a -> Constr
forall a. Data a => (forall b. Data b => b -> b) -> Doc a -> Doc a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Doc a -> u
forall a u. Data a => (forall d. Data d => d -> u) -> Doc a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
forall a r r'.
Data a =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Doc a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Doc a))
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Doc a -> u
forall u. (forall d. Data d => d -> u) -> Doc a -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Doc a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Doc a))
$cEmpty :: Constr
$cConcat :: Constr
$cBlankLines :: Constr
$cNewLine :: Constr
$cCarriageReturn :: Constr
$cAfterBreak :: Constr
$cBreakingSpace :: Constr
$cFlush :: Constr
$cBeforeNonBlank :: Constr
$cPrefixed :: Constr
$cVFill :: Constr
$cBlock :: Constr
$cText :: Constr
$tDoc :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
gmapMp :: (forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
gmapM :: (forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Doc a -> m (Doc a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Doc a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Doc a -> u
gmapQ :: (forall d. Data d => d -> u) -> Doc a -> [u]
$cgmapQ :: forall a u. Data a => (forall d. Data d => d -> u) -> Doc a -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Doc a -> r
gmapT :: (forall b. Data b => b -> b) -> Doc a -> Doc a
$cgmapT :: forall a. Data a => (forall b. Data b => b -> b) -> Doc a -> Doc a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Doc a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Doc a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Doc a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Doc a))
dataTypeOf :: Doc a -> DataType
$cdataTypeOf :: forall a. Data a => Doc a -> DataType
toConstr :: Doc a -> Constr
$ctoConstr :: forall a. Data a => Doc a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Doc a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Doc a -> c (Doc a)
$cp1Data :: forall a. Data a => Typeable (Doc a)
Data, Typeable, (forall x. Doc a -> Rep (Doc a) x)
-> (forall x. Rep (Doc a) x -> Doc a) -> Generic (Doc a)
forall x. Rep (Doc a) x -> Doc a
forall x. Doc a -> Rep (Doc a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Doc a) x -> Doc a
forall a x. Doc a -> Rep (Doc a) x
$cto :: forall a x. Rep (Doc a) x -> Doc a
$cfrom :: forall a x. Doc a -> Rep (Doc a) x
Generic)
instance Semigroup (Doc a) where
Doc a
x <> :: Doc a -> Doc a -> Doc a
<> Doc a
Empty = Doc a
x
Doc a
Empty <> Doc a
x = Doc a
x
Doc a
x <> Doc a
y = Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
x Doc a
y
instance Monoid (Doc a) where
mappend :: Doc a -> Doc a -> Doc a
mappend = Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
(<>)
mempty :: Doc a
mempty = Doc a
forall a. Doc a
Empty
instance HasChars a => IsString (Doc a) where
fromString :: String -> Doc a
fromString = String -> Doc a
forall a. HasChars a => String -> Doc a
text
unfoldD :: Doc a -> [Doc a]
unfoldD :: Doc a -> [Doc a]
unfoldD Doc a
Empty = []
unfoldD (Concat x :: Doc a
x@Concat{} Doc a
y) = Doc a -> [Doc a]
forall a. Doc a -> [Doc a]
unfoldD Doc a
x [Doc a] -> [Doc a] -> [Doc a]
forall a. Semigroup a => a -> a -> a
<> Doc a -> [Doc a]
forall a. Doc a -> [Doc a]
unfoldD Doc a
y
unfoldD (Concat Doc a
x Doc a
y) = Doc a
x Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: Doc a -> [Doc a]
forall a. Doc a -> [Doc a]
unfoldD Doc a
y
unfoldD Doc a
x = [Doc a
x]
isEmpty :: Doc a -> Bool
isEmpty :: Doc a -> Bool
isEmpty Doc a
Empty = Bool
True
isEmpty Doc a
_ = Bool
False
empty :: Doc a
empty :: Doc a
empty = Doc a
forall a. Monoid a => a
mempty
hcat :: [Doc a] -> Doc a
hcat :: [Doc a] -> Doc a
hcat = [Doc a] -> Doc a
forall a. Monoid a => [a] -> a
mconcat
infixr 6 <+>
(<+>) :: Doc a -> Doc a -> Doc a
<+> :: Doc a -> Doc a -> Doc a
(<+>) Doc a
x Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
x = Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
y = Doc a
x
| Bool
otherwise = Doc a
x Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
forall a. Doc a
space Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
y
hsep :: [Doc a] -> Doc a
hsep :: [Doc a] -> Doc a
hsep = (Doc a -> Doc a -> Doc a) -> Doc a -> [Doc a] -> Doc a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
(<+>) Doc a
forall a. Doc a
empty
infixr 5 $$
($$) :: Doc a -> Doc a -> Doc a
$$ :: Doc a -> Doc a -> Doc a
($$) Doc a
x Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
x = Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
y = Doc a
x
| Bool
otherwise = Doc a
x Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
forall a. Doc a
cr Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
y
infixr 5 $+$
($+$) :: Doc a -> Doc a -> Doc a
$+$ :: Doc a -> Doc a -> Doc a
($+$) Doc a
x Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
x = Doc a
y
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
y = Doc a
x
| Bool
otherwise = Doc a
x Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
forall a. Doc a
blankline Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
y
vcat :: [Doc a] -> Doc a
vcat :: [Doc a] -> Doc a
vcat = (Doc a -> Doc a -> Doc a) -> Doc a -> [Doc a] -> Doc a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
($$) Doc a
forall a. Doc a
empty
vsep :: [Doc a] -> Doc a
vsep :: [Doc a] -> Doc a
vsep = (Doc a -> Doc a -> Doc a) -> Doc a -> [Doc a] -> Doc a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
($+$) Doc a
forall a. Doc a
empty
nestle :: Doc a -> Doc a
nestle :: Doc a -> Doc a
nestle Doc a
d =
case Doc a
d of
BlankLines Int
_ -> Doc a
forall a. Doc a
Empty
Doc a
NewLine -> Doc a
forall a. Doc a
Empty
Concat (Concat Doc a
x Doc a
y) Doc a
z -> Doc a -> Doc a
forall a. Doc a -> Doc a
nestle (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
x (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
y Doc a
z))
Concat BlankLines{} Doc a
x -> Doc a -> Doc a
forall a. Doc a -> Doc a
nestle Doc a
x
Concat Doc a
NewLine Doc a
x -> Doc a -> Doc a
forall a. Doc a -> Doc a
nestle Doc a
x
Doc a
_ -> Doc a
d
chomp :: Doc a -> Doc a
chomp :: Doc a -> Doc a
chomp Doc a
d =
case Doc a
d of
BlankLines Int
_ -> Doc a
forall a. Doc a
Empty
Doc a
NewLine -> Doc a
forall a. Doc a
Empty
Doc a
CarriageReturn -> Doc a
forall a. Doc a
Empty
Doc a
BreakingSpace -> Doc a
forall a. Doc a
Empty
Prefixed Text
s Doc a
d' -> Text -> Doc a -> Doc a
forall a. Text -> Doc a -> Doc a
Prefixed Text
s (Doc a -> Doc a
forall a. Doc a -> Doc a
chomp Doc a
d')
Concat (Concat Doc a
x Doc a
y) Doc a
z -> Doc a -> Doc a
forall a. Doc a -> Doc a
chomp (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
x (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
y Doc a
z))
Concat Doc a
x Doc a
y ->
case Doc a -> Doc a
forall a. Doc a -> Doc a
chomp Doc a
y of
Doc a
Empty -> Doc a -> Doc a
forall a. Doc a -> Doc a
chomp Doc a
x
Doc a
z -> Doc a
x Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
z
Doc a
_ -> Doc a
d
type DocState a = State (RenderState a) ()
data RenderState a = RenderState{
RenderState a -> [a]
output :: [a]
, RenderState a -> Text
prefix :: Text
, RenderState a -> Bool
usePrefix :: Bool
, RenderState a -> Maybe Int
lineLength :: Maybe Int
, RenderState a -> Int
column :: Int
, RenderState a -> Int
newlines :: Int
}
newline :: HasChars a => DocState a
newline :: DocState a
newline = do
RenderState a
st' <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let rawpref :: Text
rawpref = RenderState a -> Text
forall a. RenderState a -> Text
prefix RenderState a
st'
Bool -> DocState a -> DocState a
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& RenderState a -> Bool
forall a. RenderState a -> Bool
usePrefix RenderState a
st' Bool -> Bool -> Bool
&& Bool -> Bool
not (Text -> Bool
T.null Text
rawpref)) (DocState a -> DocState a) -> DocState a -> DocState a
forall a b. (a -> b) -> a -> b
$ do
let pref :: a
pref = String -> a
forall a. IsString a => String -> a
fromString (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Text -> Text
T.dropWhileEnd Char -> Bool
isSpace Text
rawpref
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
st -> RenderState a
st{ output :: [a]
output = a
pref a -> [a] -> [a]
forall a. a -> [a] -> [a]
: RenderState a -> [a]
forall a. RenderState a -> [a]
output RenderState a
st
, column :: Int
column = RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
+ a -> Int
forall a. HasChars a => a -> Int
realLength a
pref }
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
st -> RenderState a
st { output :: [a]
output = a
"\n" a -> [a] -> [a]
forall a. a -> [a] -> [a]
: RenderState a -> [a]
forall a. RenderState a -> [a]
output RenderState a
st
, column :: Int
column = Int
0
, newlines :: Int
newlines = RenderState a -> Int
forall a. RenderState a -> Int
newlines RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
}
outp :: HasChars a => Int -> a -> DocState a
outp :: Int -> a -> DocState a
outp Int
off a
s = do
RenderState a
st' <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let pref :: a
pref = String -> a
forall a. IsString a => String -> a
fromString (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ RenderState a -> Text
forall a. RenderState a -> Text
prefix RenderState a
st'
Bool -> DocState a -> DocState a
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& RenderState a -> Bool
forall a. RenderState a -> Bool
usePrefix RenderState a
st' Bool -> Bool -> Bool
&& Bool -> Bool
not (a -> Bool
forall a. HasChars a => a -> Bool
isNull a
pref)) (DocState a -> DocState a) -> DocState a -> DocState a
forall a b. (a -> b) -> a -> b
$
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
st -> RenderState a
st{ output :: [a]
output = a
pref a -> [a] -> [a]
forall a. a -> [a] -> [a]
: RenderState a -> [a]
forall a. RenderState a -> [a]
output RenderState a
st
, column :: Int
column = RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
+ a -> Int
forall a. HasChars a => a -> Int
realLength a
pref }
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
st -> RenderState a
st{ output :: [a]
output = a
s a -> [a] -> [a]
forall a. a -> [a] -> [a]
: RenderState a -> [a]
forall a. RenderState a -> [a]
output RenderState a
st
, column :: Int
column = RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off
, newlines :: Int
newlines = Int
0 }
render :: HasChars a => Maybe Int -> Doc a -> a
render :: Maybe Int -> Doc a -> a
render Maybe Int
linelen Doc a
doc = [a] -> a
forall a. Monoid a => [a] -> a
mconcat ([a] -> a) -> (RenderState a -> [a]) -> RenderState a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
reverse ([a] -> [a]) -> (RenderState a -> [a]) -> RenderState a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RenderState a -> [a]
forall a. RenderState a -> [a]
output (RenderState a -> a) -> RenderState a -> a
forall a b. (a -> b) -> a -> b
$
State (RenderState a) () -> RenderState a -> RenderState a
forall s a. State s a -> s -> s
execState (Doc a -> State (RenderState a) ()
forall a. HasChars a => Doc a -> DocState a
renderDoc Doc a
doc) RenderState a
forall a. RenderState a
startingState
where startingState :: RenderState a
startingState = RenderState :: forall a.
[a] -> Text -> Bool -> Maybe Int -> Int -> Int -> RenderState a
RenderState{
output :: [a]
output = [a]
forall a. Monoid a => a
mempty
, prefix :: Text
prefix = Text
forall a. Monoid a => a
mempty
, usePrefix :: Bool
usePrefix = Bool
True
, lineLength :: Maybe Int
lineLength = Maybe Int
linelen
, column :: Int
column = Int
0
, newlines :: Int
newlines = Int
2 }
renderDoc :: HasChars a => Doc a -> DocState a
renderDoc :: Doc a -> DocState a
renderDoc = [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList ([Doc a] -> DocState a)
-> (Doc a -> [Doc a]) -> Doc a -> DocState a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize ([Doc a] -> [Doc a]) -> (Doc a -> [Doc a]) -> Doc a -> [Doc a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a]
forall a. Doc a -> [Doc a]
unfoldD
normalize :: HasChars a => [Doc a] -> [Doc a]
normalize :: [Doc a] -> [Doc a]
normalize [] = []
normalize (Concat{} : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize [Doc a]
xs
normalize (Doc a
Empty : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize [Doc a]
xs
normalize [Doc a
NewLine] = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize [Doc a
forall a. Doc a
CarriageReturn]
normalize [BlankLines Int
_] = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize [Doc a
forall a. Doc a
CarriageReturn]
normalize [Doc a
BreakingSpace] = []
normalize (BlankLines Int
m : BlankLines Int
n : [Doc a]
xs) =
[Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
m Int
n) Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (BlankLines Int
num : Doc a
BreakingSpace : [Doc a]
xs) =
[Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
num Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (BlankLines Int
m : Doc a
CarriageReturn : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
m Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (BlankLines Int
m : Doc a
NewLine : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
m Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
NewLine : BlankLines Int
m : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
m Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
NewLine : Doc a
BreakingSpace : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
NewLine Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
NewLine : Doc a
CarriageReturn : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
NewLine Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
CarriageReturn : Doc a
CarriageReturn : [Doc a]
xs) =
[Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
CarriageReturn Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
CarriageReturn : BlankLines Int
m : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
m Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
CarriageReturn : Doc a
BreakingSpace : [Doc a]
xs) =
[Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
CarriageReturn Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
normalize (Doc a
BreakingSpace : Doc a
CarriageReturn : [Doc a]
xs) =
[Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
CarriageReturnDoc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
:[Doc a]
xs)
normalize (Doc a
BreakingSpace : Doc a
NewLine : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
NewLineDoc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
:[Doc a]
xs)
normalize (Doc a
BreakingSpace : BlankLines Int
n : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
nDoc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
:[Doc a]
xs)
normalize (Doc a
BreakingSpace : Doc a
BreakingSpace : [Doc a]
xs) = [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize (Doc a
forall a. Doc a
BreakingSpaceDoc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
:[Doc a]
xs)
normalize (Doc a
x:[Doc a]
xs) = Doc a
x Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a] -> [Doc a]
forall a. HasChars a => [Doc a] -> [Doc a]
normalize [Doc a]
xs
mergeBlocks :: HasChars a => Int -> (Int, [a]) -> (Int, [a]) -> (Int, [a])
mergeBlocks :: Int -> (Int, [a]) -> (Int, [a]) -> (Int, [a])
mergeBlocks Int
h (Int
w1,[a]
lns1) (Int
w2,[a]
lns2) =
(Int
w, (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\a
l1 a
l2 -> Int -> a -> a
forall a. HasChars a => Int -> a -> a
pad Int
w1 a
l1 a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
l2) [a]
lns1' [a]
lns2')
where
w :: Int
w = Int
w1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
w2
len1 :: Int
len1 = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> [a] -> Int
forall a b. (a -> b) -> a -> b
$ Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
h [a]
lns1
len2 :: Int
len2 = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> [a] -> Int
forall a b. (a -> b) -> a -> b
$ Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
h [a]
lns2
lns1' :: [a]
lns1' = if Int
len1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
h
then [a]
lns1 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len1) a
forall a. Monoid a => a
mempty
else Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
h [a]
lns1
lns2' :: [a]
lns2' = if Int
len2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
h
then [a]
lns2 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len2) a
forall a. Monoid a => a
mempty
else Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
h [a]
lns2
pad :: Int -> a -> a
pad Int
n a
s = a
s a -> a -> a
forall a. Semigroup a => a -> a -> a
<> Int -> Char -> a
forall a. HasChars a => Int -> Char -> a
replicateChar (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- a -> Int
forall a. HasChars a => a -> Int
realLength a
s) Char
' '
renderList :: HasChars a => [Doc a] -> DocState a
renderList :: [Doc a] -> DocState a
renderList [] = () -> DocState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
renderList (Text Int
off a
s : [Doc a]
xs) = do
Int -> a -> DocState a
forall a. HasChars a => Int -> a -> DocState a
outp Int
off a
s
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Prefixed Text
pref Doc a
d : [Doc a]
xs) = do
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let oldPref :: Text
oldPref = RenderState a -> Text
forall a. RenderState a -> Text
prefix RenderState a
st
RenderState a -> DocState a
forall s (m :: * -> *). MonadState s m => s -> m ()
put RenderState a
st{ prefix :: Text
prefix = RenderState a -> Text
forall a. RenderState a -> Text
prefix RenderState a
st Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pref }
Doc a -> DocState a
forall a. HasChars a => Doc a -> DocState a
renderDoc Doc a
d
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
s -> RenderState a
s{ prefix :: Text
prefix = Text
oldPref }
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Flush Doc a
d : [Doc a]
xs) = do
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let oldUsePrefix :: Bool
oldUsePrefix = RenderState a -> Bool
forall a. RenderState a -> Bool
usePrefix RenderState a
st
RenderState a -> DocState a
forall s (m :: * -> *). MonadState s m => s -> m ()
put RenderState a
st{ usePrefix :: Bool
usePrefix = Bool
False }
Doc a -> DocState a
forall a. HasChars a => Doc a -> DocState a
renderDoc Doc a
d
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
s -> RenderState a
s{ usePrefix :: Bool
usePrefix = Bool
oldUsePrefix }
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (BeforeNonBlank Doc a
d : [Doc a]
xs) =
case [Doc a]
xs of
(Doc a
x:[Doc a]
_) | Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
x -> [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
| Bool
otherwise -> Doc a -> DocState a
forall a. HasChars a => Doc a -> DocState a
renderDoc Doc a
d DocState a -> DocState a -> DocState a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
[] -> [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (BlankLines Int
num : [Doc a]
xs) = do
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
case RenderState a -> [a]
forall a. RenderState a -> [a]
output RenderState a
st of
[a]
_ | RenderState a -> Int
forall a. RenderState a -> Int
newlines RenderState a
st Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
num -> () -> DocState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise -> Int -> DocState a -> DocState a
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
num Int -> Int -> Int
forall a. Num a => a -> a -> a
- RenderState a -> Int
forall a. RenderState a -> Int
newlines RenderState a
st) DocState a
forall a. HasChars a => DocState a
newline
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Doc a
CarriageReturn : [Doc a]
xs) = do
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
if RenderState a -> Int
forall a. RenderState a -> Int
newlines RenderState a
st Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
else do
DocState a
forall a. HasChars a => DocState a
newline
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Doc a
NewLine : [Doc a]
xs) = do
DocState a
forall a. HasChars a => DocState a
newline
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Doc a
BreakingSpace : [Doc a]
xs) = do
let isBreakingSpace :: Doc a -> Bool
isBreakingSpace Doc a
BreakingSpace = Bool
True
isBreakingSpace Doc a
_ = Bool
False
let xs' :: [Doc a]
xs' = (Doc a -> Bool) -> [Doc a] -> [Doc a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Doc a -> Bool
forall a. Doc a -> Bool
isBreakingSpace [Doc a]
xs
let next :: [Doc a]
next = (Doc a -> Bool) -> [Doc a] -> [Doc a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Doc a -> Bool) -> Doc a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
isBreakable) [Doc a]
xs'
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let off :: Int
off = (Int -> Doc a -> Int) -> Int -> [Doc a] -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
tot Doc a
t -> Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Doc a -> Int
forall a. Doc a -> Int
offsetOf Doc a
t) Int
0 [Doc a]
next
case RenderState a -> Maybe Int
forall a. RenderState a -> Maybe Int
lineLength RenderState a
st of
Just Int
l | RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
l -> DocState a
forall a. HasChars a => DocState a
newline
Maybe Int
_ -> Bool -> DocState a -> DocState a
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (DocState a -> DocState a) -> DocState a -> DocState a
forall a b. (a -> b) -> a -> b
$ Int -> a -> DocState a
forall a. HasChars a => Int -> a -> DocState a
outp Int
1 a
" "
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs'
renderList (AfterBreak Text
t : [Doc a]
xs) = do
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
if RenderState a -> Int
forall a. RenderState a -> Int
newlines RenderState a
st Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList (String -> Doc a
forall a. IsString a => String -> a
fromString (Text -> String
T.unpack Text
t) Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
xs)
else [Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
xs
renderList (Doc a
b : [Doc a]
xs) | Doc a -> Bool
forall a. Doc a -> Bool
isBlock Doc a
b = do
let ([Doc a]
bs, [Doc a]
rest) = (Doc a -> Bool) -> [Doc a] -> ([Doc a], [Doc a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Doc a -> Bool
forall a. Doc a -> Bool
isBlock [Doc a]
xs
let heightOf :: Doc a -> Int
heightOf (Block Int
_ [a]
ls) = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ls
heightOf Doc a
_ = Int
1
let maxheight :: Int
maxheight = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (Doc a -> Int) -> [Doc a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> Int
forall a. Doc a -> Int
heightOf (Doc a
bDoc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
:[Doc a]
bs)
let toBlockSpec :: Doc a -> (Int, [a])
toBlockSpec (Block Int
w [a]
ls) = (Int
w, [a]
ls)
toBlockSpec (VFill Int
w a
t) = (Int
w, Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
maxheight ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ a -> [a]
forall a. a -> [a]
repeat a
t)
toBlockSpec Doc a
_ = (Int
0, [])
let (Int
_, [a]
lns') = ((Int, [a]) -> (Int, [a]) -> (Int, [a]))
-> (Int, [a]) -> [(Int, [a])] -> (Int, [a])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Int -> (Int, [a]) -> (Int, [a]) -> (Int, [a])
forall a.
HasChars a =>
Int -> (Int, [a]) -> (Int, [a]) -> (Int, [a])
mergeBlocks Int
maxheight) (Doc a -> (Int, [a])
forall a. Doc a -> (Int, [a])
toBlockSpec Doc a
b)
((Doc a -> (Int, [a])) -> [Doc a] -> [(Int, [a])]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> (Int, [a])
forall a. Doc a -> (Int, [a])
toBlockSpec [Doc a]
bs)
RenderState a
st <- StateT (RenderState a) Identity (RenderState a)
forall s (m :: * -> *). MonadState s m => m s
get
let oldPref :: Text
oldPref = RenderState a -> Text
forall a. RenderState a -> Text
prefix RenderState a
st
case RenderState a -> Int
forall a. RenderState a -> Int
column RenderState a
st Int -> Int -> Int
forall a. Num a => a -> a -> a
- Text -> Int
forall a. HasChars a => a -> Int
realLength Text
oldPref of
Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 -> (RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
s -> RenderState a
s{ prefix :: Text
prefix = Text
oldPref Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text -> Text
T.replicate Int
n Text
" " }
Int
_ -> () -> DocState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList ([Doc a] -> DocState a) -> [Doc a] -> DocState a
forall a b. (a -> b) -> a -> b
$ Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
intersperse Doc a
forall a. Doc a
CarriageReturn ((a -> Doc a) -> [a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc a
forall a. HasChars a => a -> Doc a
literal [a]
lns')
(RenderState a -> RenderState a) -> DocState a
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenderState a -> RenderState a) -> DocState a)
-> (RenderState a -> RenderState a) -> DocState a
forall a b. (a -> b) -> a -> b
$ \RenderState a
s -> RenderState a
s{ prefix :: Text
prefix = Text
oldPref }
[Doc a] -> DocState a
forall a. HasChars a => [Doc a] -> DocState a
renderList [Doc a]
rest
renderList (Doc a
x:[Doc a]
_) = String -> DocState a
forall a. HasCallStack => String -> a
error (String -> DocState a) -> String -> DocState a
forall a b. (a -> b) -> a -> b
$ String
"renderList encountered " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc a -> String
forall a. Show a => a -> String
show Doc a
x
isBreakable :: HasChars a => Doc a -> Bool
isBreakable :: Doc a -> Bool
isBreakable Doc a
BreakingSpace = Bool
True
isBreakable Doc a
CarriageReturn = Bool
True
isBreakable Doc a
NewLine = Bool
True
isBreakable (BlankLines Int
_) = Bool
True
isBreakable (Concat Doc a
Empty Doc a
y) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
isBreakable Doc a
y
isBreakable (Concat Doc a
x Doc a
_) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
isBreakable Doc a
x
isBreakable Doc a
_ = Bool
False
startsBlank' :: HasChars a => a -> Bool
startsBlank' :: a -> Bool
startsBlank' a
t = Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Maybe Bool -> Char -> Maybe Bool) -> Maybe Bool -> a -> Maybe Bool
forall a b. HasChars a => (b -> Char -> b) -> b -> a -> b
foldlChar Maybe Bool -> Char -> Maybe Bool
go Maybe Bool
forall a. Maybe a
Nothing a
t
where
go :: Maybe Bool -> Char -> Maybe Bool
go Maybe Bool
Nothing Char
c = Bool -> Maybe Bool
forall a. a -> Maybe a
Just (Char -> Bool
isSpace Char
c)
go (Just Bool
b) Char
_ = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
b
startsBlank :: HasChars a => Doc a -> Bool
startsBlank :: Doc a -> Bool
startsBlank (Text Int
_ a
t) = a -> Bool
forall a. HasChars a => a -> Bool
startsBlank' a
t
startsBlank (Block Int
n [a]
ls) = Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all a -> Bool
forall a. HasChars a => a -> Bool
startsBlank' [a]
ls
startsBlank (VFill Int
n a
t) = Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& a -> Bool
forall a. HasChars a => a -> Bool
startsBlank' a
t
startsBlank (BeforeNonBlank Doc a
x) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
x
startsBlank (Prefixed Text
_ Doc a
x) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
x
startsBlank (Flush Doc a
x) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
x
startsBlank Doc a
BreakingSpace = Bool
True
startsBlank (AfterBreak Text
t) = Doc Text -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank (Int -> Text -> Doc Text
forall a. Int -> a -> Doc a
Text Int
0 Text
t)
startsBlank Doc a
CarriageReturn = Bool
True
startsBlank Doc a
NewLine = Bool
True
startsBlank (BlankLines Int
_) = Bool
True
startsBlank (Concat Doc a
Empty Doc a
y) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
y
startsBlank (Concat Doc a
x Doc a
_) = Doc a -> Bool
forall a. HasChars a => Doc a -> Bool
startsBlank Doc a
x
startsBlank Doc a
Empty = Bool
True
isBlock :: Doc a -> Bool
isBlock :: Doc a -> Bool
isBlock Block{} = Bool
True
isBlock VFill{} = Bool
True
isBlock Doc a
_ = Bool
False
offsetOf :: Doc a -> Int
offsetOf :: Doc a -> Int
offsetOf (Text Int
o a
_) = Int
o
offsetOf (Block Int
w [a]
_) = Int
w
offsetOf (VFill Int
w a
_) = Int
w
offsetOf Doc a
BreakingSpace = Int
1
offsetOf Doc a
_ = Int
0
literal :: HasChars a => a -> Doc a
literal :: a -> Doc a
literal a
x =
[Doc a] -> Doc a
forall a. Monoid a => [a] -> a
mconcat ([Doc a] -> Doc a) -> [Doc a] -> Doc a
forall a b. (a -> b) -> a -> b
$
Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
intersperse Doc a
forall a. Doc a
NewLine ([Doc a] -> [Doc a]) -> [Doc a] -> [Doc a]
forall a b. (a -> b) -> a -> b
$
(a -> Doc a) -> [a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map (\a
s -> if a -> Bool
forall a. HasChars a => a -> Bool
isNull a
s
then Doc a
forall a. Doc a
Empty
else let !len :: Int
len = a -> Int
forall a. HasChars a => a -> Int
realLength a
s
in Int -> a -> Doc a
forall a. Int -> a -> Doc a
Text Int
len a
s) ([a] -> [Doc a]) -> [a] -> [Doc a]
forall a b. (a -> b) -> a -> b
$
a -> [a]
forall a. HasChars a => a -> [a]
splitLines a
x
{-# NOINLINE literal #-}
text :: HasChars a => String -> Doc a
text :: String -> Doc a
text = a -> Doc a
forall a. HasChars a => a -> Doc a
literal (a -> Doc a) -> (String -> a) -> String -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a
forall a. IsString a => String -> a
fromString
char :: HasChars a => Char -> Doc a
char :: Char -> Doc a
char Char
c = String -> Doc a
forall a. HasChars a => String -> Doc a
text (String -> Doc a) -> String -> Doc a
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. IsString a => String -> a
fromString [Char
c]
space :: Doc a
space :: Doc a
space = Doc a
forall a. Doc a
BreakingSpace
cr :: Doc a
cr :: Doc a
cr = Doc a
forall a. Doc a
CarriageReturn
blankline :: Doc a
blankline :: Doc a
blankline = Int -> Doc a
forall a. Int -> Doc a
BlankLines Int
1
blanklines :: Int -> Doc a
blanklines :: Int -> Doc a
blanklines = Int -> Doc a
forall a. Int -> Doc a
BlankLines
prefixed :: IsString a => String -> Doc a -> Doc a
prefixed :: String -> Doc a -> Doc a
prefixed String
pref Doc a
doc
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
doc = Doc a
forall a. Doc a
Empty
| Bool
otherwise = Text -> Doc a -> Doc a
forall a. Text -> Doc a -> Doc a
Prefixed (String -> Text
forall a. IsString a => String -> a
fromString String
pref) Doc a
doc
flush :: Doc a -> Doc a
flush :: Doc a -> Doc a
flush Doc a
doc
| Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
doc = Doc a
forall a. Doc a
Empty
| Bool
otherwise = Doc a -> Doc a
forall a. Doc a -> Doc a
Flush Doc a
doc
nest :: IsString a => Int -> Doc a -> Doc a
nest :: Int -> Doc a -> Doc a
nest Int
ind = String -> Doc a -> Doc a
forall a. IsString a => String -> Doc a -> Doc a
prefixed (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
ind Char
' ')
hang :: IsString a => Int -> Doc a -> Doc a -> Doc a
hang :: Int -> Doc a -> Doc a -> Doc a
hang Int
ind Doc a
start Doc a
doc = Doc a
start Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Int -> Doc a -> Doc a
forall a. IsString a => Int -> Doc a -> Doc a
nest Int
ind Doc a
doc
beforeNonBlank :: Doc a -> Doc a
beforeNonBlank :: Doc a -> Doc a
beforeNonBlank = Doc a -> Doc a
forall a. Doc a -> Doc a
BeforeNonBlank
nowrap :: IsString a => Doc a -> Doc a
nowrap :: Doc a -> Doc a
nowrap = [Doc a] -> Doc a
forall a. Monoid a => [a] -> a
mconcat ([Doc a] -> Doc a) -> (Doc a -> [Doc a]) -> Doc a -> Doc a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc a -> Doc a) -> [Doc a] -> [Doc a]
forall a b. (a -> b) -> [a] -> [b]
map Doc a -> Doc a
forall a. IsString a => Doc a -> Doc a
replaceSpace ([Doc a] -> [Doc a]) -> (Doc a -> [Doc a]) -> Doc a -> [Doc a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc a -> [Doc a]
forall a. Doc a -> [Doc a]
unfoldD
where replaceSpace :: Doc a -> Doc a
replaceSpace Doc a
BreakingSpace = Int -> a -> Doc a
forall a. Int -> a -> Doc a
Text Int
1 (a -> Doc a) -> a -> Doc a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. IsString a => String -> a
fromString String
" "
replaceSpace Doc a
x = Doc a
x
afterBreak :: Text -> Doc a
afterBreak :: Text -> Doc a
afterBreak = Text -> Doc a
forall a. Text -> Doc a
AfterBreak
offset :: (IsString a, HasChars a) => Doc a -> Int
offset :: Doc a -> Int
offset = (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Int
forall a. Ord a => a -> a -> a
max ((Int, Int) -> Int) -> (Doc a -> (Int, Int)) -> Doc a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset (Bool -> Int -> Bool
forall a b. a -> b -> a
const Bool
False) (Int
0, Int
0)
minOffset :: HasChars a => Doc a -> Int
minOffset :: Doc a -> Int
minOffset = (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Int
forall a. Ord a => a -> a -> a
max ((Int, Int) -> Int) -> (Doc a -> (Int, Int)) -> Doc a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (Int
0,Int
0)
getOffset :: (IsString a, HasChars a)
=> (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset :: (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (!Int
l, !Int
c) Doc a
x =
case Doc a
x of
Text Int
n a
_ -> (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
Block Int
n [a]
_ -> (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
VFill Int
n a
_ -> (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
Doc a
Empty -> (Int
l, Int
c)
Doc a
CarriageReturn -> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
l Int
c, Int
0)
Doc a
NewLine -> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
l Int
c, Int
0)
BlankLines Int
_ -> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
l Int
c, Int
0)
Prefixed Text
t Doc a
d ->
let (Int
l',Int
c') = (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
0, Int
0) Doc a
d
in (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
l (Int
l' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
forall a. HasChars a => a -> Int
realLength Text
t), Int
c' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
forall a. HasChars a => a -> Int
realLength Text
t)
BeforeNonBlank Doc a
_ -> (Int
l, Int
c)
Flush Doc a
d -> (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l, Int
c) Doc a
d
Doc a
BreakingSpace
| Int -> Bool
breakWhen Int
c -> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
l Int
c, Int
0)
| Bool
otherwise -> (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
AfterBreak Text
t -> if Int
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Text -> Int
forall a. HasChars a => a -> Int
realLength Text
t)
else (Int
l, Int
c)
Concat (Concat Doc a
d Doc a
y) Doc a
z ->
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l, Int
c) (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
d (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
y Doc a
z))
Concat (BeforeNonBlank Doc a
d) Doc a
y ->
if Doc a -> Bool
forall a. Doc a -> Bool
isNonBlank Doc a
y
then (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l, Int
c) (Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a
Concat Doc a
d Doc a
y)
else (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l, Int
c) Doc a
y
Concat Doc a
d Doc a
y ->
let (Int
l', Int
c') = (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l, Int
c) Doc a
d
in (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset Int -> Bool
breakWhen (Int
l', Int
c') Doc a
y
isNonBlank :: Doc a -> Bool
isNonBlank :: Doc a -> Bool
isNonBlank (Text Int
_ a
_) = Bool
True
isNonBlank (BeforeNonBlank Doc a
d) = Doc a -> Bool
forall a. Doc a -> Bool
isNonBlank Doc a
d
isNonBlank (Flush Doc a
d) = Doc a -> Bool
forall a. Doc a -> Bool
isNonBlank Doc a
d
isNonBlank (Concat Doc a
d Doc a
_) = Doc a -> Bool
forall a. Doc a -> Bool
isNonBlank Doc a
d
isNonBlank Doc a
_ = Bool
False
updateColumn :: HasChars a => Doc a -> Int -> Int
updateColumn :: Doc a -> Int -> Int
updateColumn Doc a
d Int
k = (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> (Doc a -> (Int, Int)) -> Doc a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
forall a.
(IsString a, HasChars a) =>
(Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)
getOffset (Bool -> Int -> Bool
forall a b. a -> b -> a
const Bool
False) (Int
0,Int
k) (Doc a -> Int) -> Doc a -> Int
forall a b. (a -> b) -> a -> b
$ Doc a
d
lblock :: HasChars a => Int -> Doc a -> Doc a
lblock :: Int -> Doc a -> Doc a
lblock = (a -> a) -> Int -> Doc a -> Doc a
forall a. HasChars a => (a -> a) -> Int -> Doc a -> Doc a
block a -> a
forall a. a -> a
id
rblock :: HasChars a => Int -> Doc a -> Doc a
rblock :: Int -> Doc a -> Doc a
rblock Int
w = (a -> a) -> Int -> Doc a -> Doc a
forall a. HasChars a => (a -> a) -> Int -> Doc a -> Doc a
block (\a
s -> Int -> Char -> a
forall a. HasChars a => Int -> Char -> a
replicateChar (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- a -> Int
forall a. HasChars a => a -> Int
realLength a
s) Char
' ' a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
s) Int
w
cblock :: HasChars a => Int -> Doc a -> Doc a
cblock :: Int -> Doc a -> Doc a
cblock Int
w = (a -> a) -> Int -> Doc a -> Doc a
forall a. HasChars a => (a -> a) -> Int -> Doc a -> Doc a
block (\a
s -> Int -> Char -> a
forall a. HasChars a => Int -> Char -> a
replicateChar ((Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- a -> Int
forall a. HasChars a => a -> Int
realLength a
s) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) Char
' ' a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
s) Int
w
height :: HasChars a => Doc a -> Int
height :: Doc a -> Int
height = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> (Doc a -> [a]) -> Doc a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [a]
forall a. HasChars a => a -> [a]
splitLines (a -> [a]) -> (Doc a -> a) -> Doc a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> Doc a -> a
forall a. HasChars a => Maybe Int -> Doc a -> a
render Maybe Int
forall a. Maybe a
Nothing
block :: HasChars a => (a -> a) -> Int -> Doc a -> Doc a
block :: (a -> a) -> Int -> Doc a -> Doc a
block a -> a
filler Int
width Doc a
d
| Int
width Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 Bool -> Bool -> Bool
&& Bool -> Bool
not (Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
d) = (a -> a) -> Int -> Doc a -> Doc a
forall a. HasChars a => (a -> a) -> Int -> Doc a -> Doc a
block a -> a
filler Int
1 Doc a
d
| Bool
otherwise = Int -> [a] -> Doc a
forall a. Int -> [a] -> Doc a
Block Int
width [a]
ls
where
ls :: [a]
ls = (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
filler ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> a -> [a]
forall a. HasChars a => Int -> a -> [a]
chop Int
width (a -> [a]) -> a -> [a]
forall a b. (a -> b) -> a -> b
$ Maybe Int -> Doc a -> a
forall a. HasChars a => Maybe Int -> Doc a -> a
render (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
width) Doc a
d
vfill :: HasChars a => a -> Doc a
vfill :: a -> Doc a
vfill a
t = Int -> a -> Doc a
forall a. Int -> a -> Doc a
VFill (a -> Int
forall a. HasChars a => a -> Int
realLength a
t) a
t
chop :: HasChars a => Int -> a -> [a]
chop :: Int -> a -> [a]
chop Int
n =
((Int, a) -> [a]) -> [(Int, a)] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Int, a) -> [a]
forall a. HasChars a => (Int, a) -> [a]
chopLine ([(Int, a)] -> [a]) -> (a -> [(Int, a)]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, a)] -> [(Int, a)]
forall a b. (Eq a, Num a) => [(a, b)] -> [(a, b)]
removeFinalEmpty ([(Int, a)] -> [(Int, a)]) -> (a -> [(Int, a)]) -> a -> [(Int, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (Int, a)) -> [a] -> [(Int, a)]
forall a b. (a -> b) -> [a] -> [b]
map a -> (Int, a)
forall b. HasChars b => b -> (Int, b)
addRealLength ([a] -> [(Int, a)]) -> (a -> [a]) -> a -> [(Int, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [a]
forall a. HasChars a => a -> [a]
splitLines
where
removeFinalEmpty :: [(a, b)] -> [(a, b)]
removeFinalEmpty [(a, b)]
xs = case [(a, b)] -> Maybe (a, b)
forall a. [a] -> Maybe a
lastMay [(a, b)]
xs of
Just (a
0, b
_) -> [(a, b)] -> [(a, b)]
forall a. [a] -> [a]
initSafe [(a, b)]
xs
Maybe (a, b)
_ -> [(a, b)]
xs
addRealLength :: b -> (Int, b)
addRealLength b
l = (b -> Int
forall a. HasChars a => a -> Int
realLength b
l, b
l)
chopLine :: (Int, a) -> [a]
chopLine (Int
len, a
l)
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n = [a
l]
| Bool
otherwise = ((Int, a) -> a) -> [(Int, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (Int, a) -> a
forall a b. (a, b) -> b
snd ([(Int, a)] -> [a]) -> [(Int, a)] -> [a]
forall a b. (a -> b) -> a -> b
$
(Char -> [(Int, a)] -> [(Int, a)]) -> [(Int, a)] -> a -> [(Int, a)]
forall a b. HasChars a => (Char -> b -> b) -> b -> a -> b
foldrChar
(\Char
c [(Int, a)]
ls ->
let clen :: Int
clen = Char -> Int
charWidth Char
c
cs :: a
cs = Int -> Char -> a
forall a. HasChars a => Int -> Char -> a
replicateChar Int
1 Char
c
in case [(Int, a)]
ls of
(Int
len', a
l'):[(Int, a)]
rest
| Int
len' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
clen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n ->
(Int
clen, a
cs)(Int, a) -> [(Int, a)] -> [(Int, a)]
forall a. a -> [a] -> [a]
:(Int
len', a
l')(Int, a) -> [(Int, a)] -> [(Int, a)]
forall a. a -> [a] -> [a]
:[(Int, a)]
rest
| Bool
otherwise ->
(Int
len' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
clen, a
cs a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
l')(Int, a) -> [(Int, a)] -> [(Int, a)]
forall a. a -> [a] -> [a]
:[(Int, a)]
rest
[] -> [(Int
clen, a
cs)]) [] a
l
inside :: Doc a -> Doc a -> Doc a -> Doc a
inside :: Doc a -> Doc a -> Doc a -> Doc a
inside Doc a
start Doc a
end Doc a
contents =
Doc a
start Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
contents Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
end
braces :: HasChars a => Doc a -> Doc a
braces :: Doc a -> Doc a
braces = Doc a -> Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a -> Doc a
inside (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'{') (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'}')
brackets :: HasChars a => Doc a -> Doc a
brackets :: Doc a -> Doc a
brackets = Doc a -> Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a -> Doc a
inside (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'[') (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
']')
parens :: HasChars a => Doc a -> Doc a
parens :: Doc a -> Doc a
parens = Doc a -> Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a -> Doc a
inside (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'(') (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
')')
quotes :: HasChars a => Doc a -> Doc a
quotes :: Doc a -> Doc a
quotes = Doc a -> Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a -> Doc a
inside (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'\'') (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'\'')
doubleQuotes :: HasChars a => Doc a -> Doc a
doubleQuotes :: Doc a -> Doc a
doubleQuotes = Doc a -> Doc a -> Doc a -> Doc a
forall a. Doc a -> Doc a -> Doc a -> Doc a
inside (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'"') (Char -> Doc a
forall a. HasChars a => Char -> Doc a
char Char
'"')
charWidth :: Char -> Int
charWidth :: Char -> Int
charWidth = MatchState -> Int
extractLength (MatchState -> Int) -> (Char -> MatchState) -> Char -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MatchState -> Char -> MatchState
updateMatchStateNarrow (Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False Int
0 Char
' ' Int
0)
realLength :: HasChars a => a -> Int
realLength :: a -> Int
realLength = a -> Int
forall a. HasChars a => a -> Int
realLengthNarrowContext
realLengthNarrowContext :: HasChars a => a -> Int
realLengthNarrowContext :: a -> Int
realLengthNarrowContext = (MatchState -> Char -> MatchState) -> a -> Int
forall a.
HasChars a =>
(MatchState -> Char -> MatchState) -> a -> Int
realLengthWith MatchState -> Char -> MatchState
updateMatchStateNarrow
realLengthWideContext :: HasChars a => a -> Int
realLengthWideContext :: a -> Int
realLengthWideContext = (MatchState -> Char -> MatchState) -> a -> Int
forall a.
HasChars a =>
(MatchState -> Char -> MatchState) -> a -> Int
realLengthWith MatchState -> Char -> MatchState
updateMatchStateWide
realLengthNarrowContextNoShortcut :: HasChars a => a -> Int
realLengthNarrowContextNoShortcut :: a -> Int
realLengthNarrowContextNoShortcut = (MatchState -> Char -> MatchState) -> a -> Int
forall a.
HasChars a =>
(MatchState -> Char -> MatchState) -> a -> Int
realLengthWith MatchState -> Char -> MatchState
updateMatchStateNoShortcut
realLengthWideContextNoShortcut :: HasChars a => a -> Int
realLengthWideContextNoShortcut :: a -> Int
realLengthWideContextNoShortcut = (MatchState -> Char -> MatchState) -> a -> Int
forall a.
HasChars a =>
(MatchState -> Char -> MatchState) -> a -> Int
realLengthWith MatchState -> Char -> MatchState
updateMatchStateNoShortcutWide
realLengthWith :: HasChars a => (MatchState -> Char -> MatchState) -> a -> Int
realLengthWith :: (MatchState -> Char -> MatchState) -> a -> Int
realLengthWith MatchState -> Char -> MatchState
f = MatchState -> Int
extractLength (MatchState -> Int) -> (a -> MatchState) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MatchState -> Char -> MatchState) -> MatchState -> a -> MatchState
forall a b. HasChars a => (b -> Char -> b) -> b -> a -> b
foldlChar MatchState -> Char -> MatchState
f (Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
True Int
0 Char
' ' Int
0)
updateMatchStateNarrow :: MatchState -> Char -> MatchState
updateMatchStateNarrow :: MatchState -> Char -> MatchState
updateMatchStateNarrow (MatchState Bool
firstChar Int
tot Char
_ Int
tentative) !Char
c
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x001F' = MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x007E' = MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x009F' = MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x00AD' = MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x02FF' = MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x036F' = MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x3250' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\xA4CF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x4DBF' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x4DFF' -> MatchState
narrowState
| Bool
otherwise -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0600' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06FF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0605' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x060F' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x061A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x061B' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x061C' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x064A' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x065F' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0670' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06D5' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06DC' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06DD' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06DE' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06E4' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06E6' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06E9' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06ED' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0900' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x097F' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0902' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0939' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x093A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x093C' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0940' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0948' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x094D' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0950' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0957' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0962' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0963' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0980' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0A02' =
if | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0981' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09BC' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09C0' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09C4' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09CD' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09E1' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09E3' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09E2' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09E3' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09FD' -> MatchState
narrowState
| Bool
otherwise -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0370' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x058F' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0482' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0489' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x2E80' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x324F' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3029' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x302D' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x303F' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3096' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x309A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3247' -> MatchState
wideState
| Bool
otherwise -> MatchState
ambiguousState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\xAC00' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\xD7A3' = MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0C00' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C80' =
if | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C00' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C04' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C39' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C3D' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C40' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C44' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C56' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C62' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C63' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0B80' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0BFF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0B82' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0BC0' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0BCD' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0BCC' -> MatchState
narrowState
| Bool
otherwise -> MatchState
narrowState
where
narrowState :: MatchState
narrowState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
1
wideState :: MatchState
wideState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
2
combiningState :: MatchState
combiningState = let w :: Int
w = if Bool
firstChar then Int
1 else Int
0 in Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
w
controlState :: MatchState
controlState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
0
ambiguousState :: MatchState
ambiguousState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
1
updateMatchStateNarrow MatchState
s Char
c = MatchState -> Char -> MatchState
updateMatchStateNoShortcut MatchState
s Char
c
updateMatchStateWide :: MatchState -> Char -> MatchState
updateMatchStateWide :: MatchState -> Char -> MatchState
updateMatchStateWide (MatchState Bool
firstChar Int
tot Char
_ Int
tentative) !Char
c
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x001F' = MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x007E' = MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x3250' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\xA4CF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x4DBF' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x4DFF' -> MatchState
narrowState
| Bool
otherwise -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x2E80' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x324F' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3029' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x302D' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x303F' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3096' -> MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x309A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x3247' -> MatchState
wideState
| Bool
otherwise -> MatchState
ambiguousState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\xAC00' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\xD7A3' = MatchState
wideState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0300' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x036F' = MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0600' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06FF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0605' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x060F' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x061A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x061B' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x061C' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x064A' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x065F' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0670' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06D5' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06DC' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06DD' -> MatchState
controlState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06DE' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06E4' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06E6' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x06E9' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x06ED' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0900' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x097F' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0902' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0939' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x093A' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x093C' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0940' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0948' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x094D' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0950' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0957' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0962' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0963' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0980' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0A02' =
if | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0981' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09BC' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09C0' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09C4' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09CD' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09E1' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09E3' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09E2' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x09E3' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x09FD' -> MatchState
narrowState
| Bool
otherwise -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0C00' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C80' =
if | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C00' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C04' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C39' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C3D' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C40' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C44' -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0C56' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C62' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0C63' -> MatchState
combiningState
| Bool
otherwise -> MatchState
narrowState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x0B80' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0BFF' =
if | Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0B82' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0BC0' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x0BCD' -> MatchState
combiningState
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x0BCC' -> MatchState
narrowState
| Bool
otherwise -> MatchState
narrowState
where
narrowState :: MatchState
narrowState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
1
wideState :: MatchState
wideState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
2
combiningState :: MatchState
combiningState = let w :: Int
w = if Bool
firstChar then Int
1 else Int
0 in Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
w
controlState :: MatchState
controlState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
0
ambiguousState :: MatchState
ambiguousState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
2
updateMatchStateWide MatchState
s Char
c = MatchState -> Char -> MatchState
updateMatchStateNoShortcutWide MatchState
s Char
c
updateMatchStateNoShortcut :: MatchState -> Char -> MatchState
updateMatchStateNoShortcut :: MatchState -> Char -> MatchState
updateMatchStateNoShortcut MatchState
match Char
c = MatchState -> Char -> UnicodeWidth -> MatchState
resolveWidth MatchState
match Char
c (UnicodeWidth -> MatchState) -> UnicodeWidth -> MatchState
forall a b. (a -> b) -> a -> b
$ UnicodeMap -> Char -> UnicodeWidth
unicodeWidth (UnicodeWidth -> UnicodeMap
unicodeRangeMap UnicodeWidth
Narrow) Char
c
updateMatchStateNoShortcutWide :: MatchState -> Char -> MatchState
updateMatchStateNoShortcutWide :: MatchState -> Char -> MatchState
updateMatchStateNoShortcutWide MatchState
match Char
c = MatchState -> Char -> UnicodeWidth -> MatchState
resolveWidth MatchState
match Char
c (UnicodeWidth -> MatchState) -> UnicodeWidth -> MatchState
forall a b. (a -> b) -> a -> b
$ UnicodeMap -> Char -> UnicodeWidth
unicodeWidth (UnicodeWidth -> UnicodeMap
unicodeRangeMap UnicodeWidth
Wide) Char
c
resolveWidth :: MatchState -> Char -> UnicodeWidth -> MatchState
resolveWidth :: MatchState -> Char -> UnicodeWidth -> MatchState
resolveWidth (MatchState Bool
firstChar Int
tot Char
lastChar Int
tentative) !Char
c = \case
UnicodeWidth
Narrow -> MatchState
narrowState
UnicodeWidth
Wide -> MatchState
wideState
UnicodeWidth
Combining -> MatchState
combiningState
UnicodeWidth
Control -> MatchState
controlState
UnicodeWidth
Ambiguous -> MatchState
ambiguousState
UnicodeWidth
ZWJ | Bool
isLastCharEmojiLike -> Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) Char
c Int
2
UnicodeWidth
ZWJ -> MatchState
controlState
UnicodeWidth
EmojiPresentationMod | Just (EmojiInfo Bool
True Bool
_) <- Maybe EmojiInfo
lastCharEmoji
-> Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False Int
tot Char
c Int
2
UnicodeWidth
EmojiPresentationMod -> MatchState
controlState
UnicodeWidth
EmojiSkinToneMod | Just (EmojiInfo Bool
_ Bool
True) <- Maybe EmojiInfo
lastCharEmoji
-> Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False Int
tot Char
c Int
2
UnicodeWidth
EmojiSkinToneMod -> MatchState
wideState
where
narrowState :: MatchState
narrowState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
1
wideState :: MatchState
wideState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
2
combiningState :: MatchState
combiningState = let w :: Int
w = if Bool
firstChar then Int
1 else Int
0 in Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
w
controlState :: MatchState
controlState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
0
ambiguousState :: MatchState
ambiguousState = Bool -> Int -> Char -> Int -> MatchState
MatchState Bool
False (Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative) Char
c Int
1
lastCharEmoji :: Maybe EmojiInfo
lastCharEmoji = Int -> IntMap EmojiInfo -> Maybe EmojiInfo
forall a. Int -> IntMap a -> Maybe a
IM.lookup (Char -> Int
ord Char
lastChar) IntMap EmojiInfo
emojiMap
isLastCharEmojiLike :: Bool
isLastCharEmojiLike = Maybe EmojiInfo -> Bool
forall a. Maybe a -> Bool
isJust Maybe EmojiInfo
lastCharEmoji Bool -> Bool -> Bool
|| Char
lastChar Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\xFE0F' Bool -> Bool -> Bool
|| Char -> Bool
isSkinToneModifier Char
lastChar
data MatchState = MatchState
{ MatchState -> Bool
matchIsFirst :: !Bool
, MatchState -> Int
matchTotal :: !Int
, MatchState -> Char
matchLastChar :: !Char
, MatchState -> Int
matchTentative :: !Int
}
deriving (Int -> MatchState -> String -> String
[MatchState] -> String -> String
MatchState -> String
(Int -> MatchState -> String -> String)
-> (MatchState -> String)
-> ([MatchState] -> String -> String)
-> Show MatchState
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [MatchState] -> String -> String
$cshowList :: [MatchState] -> String -> String
show :: MatchState -> String
$cshow :: MatchState -> String
showsPrec :: Int -> MatchState -> String -> String
$cshowsPrec :: Int -> MatchState -> String -> String
Show)
extractLength :: MatchState -> Int
(MatchState Bool
_ Int
tot Char
_ Int
tentative) = Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
tentative
data UnicodeWidth = Narrow | Wide | Combining | Control | Ambiguous
| ZWJ | EmojiPresentationMod | EmojiSkinToneMod
deriving (Int -> UnicodeWidth -> String -> String
[UnicodeWidth] -> String -> String
UnicodeWidth -> String
(Int -> UnicodeWidth -> String -> String)
-> (UnicodeWidth -> String)
-> ([UnicodeWidth] -> String -> String)
-> Show UnicodeWidth
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [UnicodeWidth] -> String -> String
$cshowList :: [UnicodeWidth] -> String -> String
show :: UnicodeWidth -> String
$cshow :: UnicodeWidth -> String
showsPrec :: Int -> UnicodeWidth -> String -> String
$cshowsPrec :: Int -> UnicodeWidth -> String -> String
Show, UnicodeWidth -> UnicodeWidth -> Bool
(UnicodeWidth -> UnicodeWidth -> Bool)
-> (UnicodeWidth -> UnicodeWidth -> Bool) -> Eq UnicodeWidth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnicodeWidth -> UnicodeWidth -> Bool
$c/= :: UnicodeWidth -> UnicodeWidth -> Bool
== :: UnicodeWidth -> UnicodeWidth -> Bool
$c== :: UnicodeWidth -> UnicodeWidth -> Bool
Eq)
isSkinToneModifier :: Char -> Bool
isSkinToneModifier :: Char -> Bool
isSkinToneModifier Char
c = Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\x1F3FB' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\x1F3FF'
isEmojiVariation :: Char -> Bool
isEmojiVariation :: Char -> Bool
isEmojiVariation Char
c = Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'\xFE0E' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\xFE0F'
isZWJ :: Char -> Bool
isZWJ :: Char -> Bool
isZWJ Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\x200D'
data EmojiInfo = EmojiInfo
{ EmojiInfo -> Bool
acceptsVariation :: !Bool
, EmojiInfo -> Bool
acceptsSkinTones :: !Bool
} deriving (EmojiInfo -> EmojiInfo -> Bool
(EmojiInfo -> EmojiInfo -> Bool)
-> (EmojiInfo -> EmojiInfo -> Bool) -> Eq EmojiInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EmojiInfo -> EmojiInfo -> Bool
$c/= :: EmojiInfo -> EmojiInfo -> Bool
== :: EmojiInfo -> EmojiInfo -> Bool
$c== :: EmojiInfo -> EmojiInfo -> Bool
Eq, Int -> EmojiInfo -> String -> String
[EmojiInfo] -> String -> String
EmojiInfo -> String
(Int -> EmojiInfo -> String -> String)
-> (EmojiInfo -> String)
-> ([EmojiInfo] -> String -> String)
-> Show EmojiInfo
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [EmojiInfo] -> String -> String
$cshowList :: [EmojiInfo] -> String -> String
show :: EmojiInfo -> String
$cshow :: EmojiInfo -> String
showsPrec :: Int -> EmojiInfo -> String -> String
$cshowsPrec :: Int -> EmojiInfo -> String -> String
Show)
instance Semigroup EmojiInfo where
EmojiInfo Bool
v1 Bool
s1 <> :: EmojiInfo -> EmojiInfo -> EmojiInfo
<> EmojiInfo Bool
v2 Bool
s2 = Bool -> Bool -> EmojiInfo
EmojiInfo (Bool
v1 Bool -> Bool -> Bool
|| Bool
v2) (Bool
s1 Bool -> Bool -> Bool
|| Bool
s2)
variationState :: Char -> EmojiInfo
variationState :: Char -> EmojiInfo
variationState Char
y = Bool -> Bool -> EmojiInfo
EmojiInfo (Char -> Bool
isEmojiVariation Char
y) (Char -> Bool
isSkinToneModifier Char
y)
emojiMap :: IM.IntMap EmojiInfo
emojiMap :: IntMap EmojiInfo
emojiMap = (IntMap EmojiInfo -> (Char, Text) -> IntMap EmojiInfo)
-> IntMap EmojiInfo -> [(Char, Text)] -> IntMap EmojiInfo
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (((Char, Text) -> IntMap EmojiInfo -> IntMap EmojiInfo)
-> IntMap EmojiInfo -> (Char, Text) -> IntMap EmojiInfo
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Char, Text) -> IntMap EmojiInfo -> IntMap EmojiInfo
addEmoji) IntMap EmojiInfo
forall a. Monoid a => a
mempty ([(Char, Text)] -> IntMap EmojiInfo)
-> [(Char, Text)] -> IntMap EmojiInfo
forall a b. (a -> b) -> a -> b
$ (Text -> Maybe (Char, Text)) -> [Text] -> [(Char, Text)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Text -> Maybe (Char, Text)
T.uncons [Text]
baseEmojis
where
addEmoji :: (Char, Text) -> IntMap EmojiInfo -> IntMap EmojiInfo
addEmoji (Char
x, Text
xs) = (EmojiInfo -> EmojiInfo -> EmojiInfo)
-> Int -> EmojiInfo -> IntMap EmojiInfo -> IntMap EmojiInfo
forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IM.insertWith EmojiInfo -> EmojiInfo -> EmojiInfo
forall a. Semigroup a => a -> a -> a
(<>) (Char -> Int
ord Char
x) (Text -> EmojiInfo
emojiInfo Text
xs)
emojiInfo :: Text -> EmojiInfo
emojiInfo = EmojiInfo
-> ((Char, Text) -> EmojiInfo) -> Maybe (Char, Text) -> EmojiInfo
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Bool -> Bool -> EmojiInfo
EmojiInfo Bool
False Bool
False) (Char -> EmojiInfo
variationState (Char -> EmojiInfo)
-> ((Char, Text) -> Char) -> (Char, Text) -> EmojiInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char, Text) -> Char
forall a b. (a, b) -> a
fst) (Maybe (Char, Text) -> EmojiInfo)
-> (Text -> Maybe (Char, Text)) -> Text -> EmojiInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe (Char, Text)
T.uncons
unicodeRangeMap :: UnicodeWidth -> UnicodeMap
unicodeRangeMap :: UnicodeWidth -> UnicodeMap
unicodeRangeMap UnicodeWidth
ambiguous =
Map Char UnicodeWidth -> UnicodeMap
repack (Map Char UnicodeWidth -> UnicodeMap)
-> ([(Char, UnicodeWidth)] -> Map Char UnicodeWidth)
-> [(Char, UnicodeWidth)]
-> UnicodeMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Char UnicodeWidth -> Map Char UnicodeWidth
addEmojiClasses (Map Char UnicodeWidth -> Map Char UnicodeWidth)
-> ([(Char, UnicodeWidth)] -> Map Char UnicodeWidth)
-> [(Char, UnicodeWidth)]
-> Map Char UnicodeWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Char, UnicodeWidth)] -> Map Char UnicodeWidth
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Char, UnicodeWidth)] -> Map Char UnicodeWidth)
-> ([(Char, UnicodeWidth)] -> [(Char, UnicodeWidth)])
-> [(Char, UnicodeWidth)]
-> Map Char UnicodeWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Char, UnicodeWidth)] -> [(Char, UnicodeWidth)]
forall b a. Eq b => [(a, b)] -> [(a, b)]
mergeRanges ([(Char, UnicodeWidth)] -> UnicodeMap)
-> [(Char, UnicodeWidth)] -> UnicodeMap
forall a b. (a -> b) -> a -> b
$
((Char, UnicodeWidth) -> (Char, UnicodeWidth))
-> [(Char, UnicodeWidth)] -> [(Char, UnicodeWidth)]
forall a b. (a -> b) -> [a] -> [b]
map ((UnicodeWidth -> UnicodeWidth)
-> (Char, UnicodeWidth) -> (Char, UnicodeWidth)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second UnicodeWidth -> UnicodeWidth
resolve) [(Char, UnicodeWidth)]
unicodeSpec
where
resolve :: UnicodeWidth -> UnicodeWidth
resolve UnicodeWidth
Ambiguous = UnicodeWidth
ambiguous
resolve UnicodeWidth
x = UnicodeWidth
x
addEmojiClasses :: M.Map Char UnicodeWidth -> M.Map Char UnicodeWidth
addEmojiClasses :: Map Char UnicodeWidth -> Map Char UnicodeWidth
addEmojiClasses =
Char
-> Char
-> UnicodeWidth
-> Map Char UnicodeWidth
-> Map Char UnicodeWidth
forall k a. (Ord k, Enum k) => k -> k -> a -> Map k a -> Map k a
addAndRestoreBoundary Char
'\x200D' Char
'\x200D' UnicodeWidth
ZWJ
(Map Char UnicodeWidth -> Map Char UnicodeWidth)
-> (Map Char UnicodeWidth -> Map Char UnicodeWidth)
-> Map Char UnicodeWidth
-> Map Char UnicodeWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char
-> Char
-> UnicodeWidth
-> Map Char UnicodeWidth
-> Map Char UnicodeWidth
forall k a. (Ord k, Enum k) => k -> k -> a -> Map k a -> Map k a
addAndRestoreBoundary Char
'\xFE0F' Char
'\xFE0F' UnicodeWidth
EmojiPresentationMod
(Map Char UnicodeWidth -> Map Char UnicodeWidth)
-> (Map Char UnicodeWidth -> Map Char UnicodeWidth)
-> Map Char UnicodeWidth
-> Map Char UnicodeWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char
-> Char
-> UnicodeWidth
-> Map Char UnicodeWidth
-> Map Char UnicodeWidth
forall k a. (Ord k, Enum k) => k -> k -> a -> Map k a -> Map k a
addAndRestoreBoundary Char
'\x1F3FB' Char
'\x1F3FF' UnicodeWidth
EmojiSkinToneMod
where
addAndRestoreBoundary :: k -> k -> a -> Map k a -> Map k a
addAndRestoreBoundary k
k1 k
k2 a
v Map k a
m = Map k a -> Map k a
insertAfter (Map k a -> Map k a) -> Map k a -> Map k a
forall a b. (a -> b) -> a -> b
$ k -> a -> Map k a -> Map k a
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert k
k1 a
v Map k a
m
where
insertAfter :: Map k a -> Map k a
insertAfter = case k -> Map k a -> Maybe (k, a)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupLE k
k1 Map k a
m of
Just (k
_, a
prev) -> (a -> a -> a) -> k -> a -> Map k a -> Map k a
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith (\a
_ a
old -> a
old) (k -> k
forall a. Enum a => a -> a
succ k
k2) a
prev
Maybe (k, a)
Nothing -> Map k a -> Map k a
forall a. a -> a
id
mergeRanges :: Eq b => [(a, b)] -> [(a, b)]
mergeRanges :: [(a, b)] -> [(a, b)]
mergeRanges [] = []
mergeRanges [(a, b)
x] = [(a, b)
x]
mergeRanges (x :: (a, b)
x@(a
_,b
xw):y :: (a, b)
y@(a
_,b
yw):[(a, b)]
xs)
| b
xw b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
yw = [(a, b)] -> [(a, b)]
forall b a. Eq b => [(a, b)] -> [(a, b)]
mergeRanges ((a, b)
x(a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:[(a, b)]
xs)
| Bool
otherwise = (a, b)
x (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [(a, b)] -> [(a, b)]
forall b a. Eq b => [(a, b)] -> [(a, b)]
mergeRanges ((a, b)
y(a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:[(a, b)]
xs)
data UnicodeMap
= Bin {-# UNPACK #-} !Char !UnicodeWidth !UnicodeMap !UnicodeMap
| Tip
unicodeWidth :: UnicodeMap -> Char -> UnicodeWidth
unicodeWidth :: UnicodeMap -> Char -> UnicodeWidth
unicodeWidth = UnicodeMap -> Char -> UnicodeWidth
goNothing
where
goNothing :: UnicodeMap -> Char -> UnicodeWidth
goNothing UnicodeMap
Tip !Char
_ = UnicodeWidth
Control
goNothing (Bin Char
kx UnicodeWidth
x UnicodeMap
l UnicodeMap
r) Char
k = case Char -> Char -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Char
k Char
kx of
Ordering
LT -> UnicodeMap -> Char -> UnicodeWidth
goNothing UnicodeMap
l Char
k
Ordering
EQ -> UnicodeWidth
x
Ordering
GT -> UnicodeMap -> Char -> Char -> UnicodeWidth -> UnicodeWidth
goJust UnicodeMap
r Char
k Char
kx UnicodeWidth
x
goJust :: UnicodeMap -> Char -> Char -> UnicodeWidth -> UnicodeWidth
goJust UnicodeMap
Tip !Char
_ !Char
_ UnicodeWidth
x' = UnicodeWidth
x'
goJust (Bin Char
kx UnicodeWidth
x UnicodeMap
l UnicodeMap
r) Char
k Char
kx' UnicodeWidth
x' = case Char -> Char -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Char
k Char
kx of
Ordering
LT -> UnicodeMap -> Char -> Char -> UnicodeWidth -> UnicodeWidth
goJust UnicodeMap
l Char
k Char
kx' UnicodeWidth
x'
Ordering
EQ -> UnicodeWidth
x
Ordering
GT -> UnicodeMap -> Char -> Char -> UnicodeWidth -> UnicodeWidth
goJust UnicodeMap
r Char
k Char
kx UnicodeWidth
x
{-# INLINABLE unicodeWidth #-}
repack :: M.Map Char UnicodeWidth -> UnicodeMap
repack :: Map Char UnicodeWidth -> UnicodeMap
repack Map Char UnicodeWidth
MInt.Tip = UnicodeMap
Tip
repack (MInt.Bin Int
_ Char
k UnicodeWidth
v Map Char UnicodeWidth
l Map Char UnicodeWidth
r) = Char -> UnicodeWidth -> UnicodeMap -> UnicodeMap -> UnicodeMap
Bin Char
k UnicodeWidth
v (Map Char UnicodeWidth -> UnicodeMap
repack Map Char UnicodeWidth
l) (Map Char UnicodeWidth -> UnicodeMap
repack Map Char UnicodeWidth
r)
unicodeSpec :: [(Char, UnicodeWidth)]
#include "unicodeWidth.inc"