Data.Text.Utf8.Rope

text-rope-0.3: Text lines and ropes

License | BSD3
Maintainer | Andrew Lelechenko <andrew.lelechenko@gmail.com>
Safe Haskell | None
Language | Haskell2010

Data.Text.Utf8.Rope

Contents

- Lines
- UTF-8 code units

Description

Since: 0.3

Synopsis

- data Rope
- fromText :: Text -> Rope
- fromTextLines :: TextLines -> Rope
- toText :: Rope -> Text
- toTextLines :: Rope -> TextLines
- null :: Rope -> Bool
- lines :: Rope -> [Text]
- lengthInLines :: Rope -> Word
- splitAtLine :: Word -> Rope -> (Rope, Rope)
- getLine :: Word -> Rope -> Rope
- length :: Rope -> Word
- splitAt :: Word -> Rope -> Maybe (Rope, Rope)
- data Position = Position {
  - posLine :: !Word
  - posColumn :: !Word
  }
- lengthAsPosition :: Rope -> Position
- splitAtPosition :: Position -> Rope -> Maybe (Rope, Rope)

# Documentation

data Rope #

Rope of `Text` chunks with logarithmic concatenation. This rope offers an interface, based on UTF-8 code units. Use Data.Text.Rope, if you need code points, or Data.Text.Mixed.Rope, if you need both interfaces.

#### Instances

Instances details

NFData Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods rnf :: Rope -> () #
Monoid Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods mempty :: Rope # mappend :: Rope -> Rope -> Rope # mconcat :: [Rope] -> Rope #
Semigroup Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods (<>) :: Rope -> Rope -> Rope # sconcat :: NonEmpty Rope -> Rope # stimes :: Integral b => b -> Rope -> Rope #
IsString Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods fromString :: String -> Rope #
Show Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods showsPrec :: Int -> Rope -> ShowS # show :: Rope -> String # showList :: [Rope] -> ShowS #
Eq Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods (==) :: Rope -> Rope -> Bool # (/=) :: Rope -> Rope -> Bool #
Ord Rope # |
Instance details Defined in Data.Text.Utf8.Rope Methods compare :: Rope -> Rope -> Ordering # (<) :: Rope -> Rope -> Bool # (<=) :: Rope -> Rope -> Bool # (>) :: Rope -> Rope -> Bool # (>=) :: Rope -> Rope -> Bool # max :: Rope -> Rope -> Rope # min :: Rope -> Rope -> Rope #

fromText :: Text -> Rope #

Create from `Text`, linear time.

fromTextLines :: TextLines -> Rope #

Create from `TextLines`, linear time.

toText :: Rope -> Text #

Glue chunks into `Text`, linear time.

toTextLines :: Rope -> TextLines #

Glue chunks into `TextLines`, linear time.

null :: Rope -> Bool #

Check whether a rope is empty, O(1).

# Lines

lines :: Rope -> [Text] #

Split into lines by `\n`, similar to `Data.Text.` `lines`. Each line is produced in O(1).

    >>> :set -XOverloadedStrings
    >>> lines ""
    []
    >>> lines "foo"
    ["foo"]
    >>> lines "foo\n"
    ["foo"]
    >>> lines "foo\n\n"
    ["foo",""]
    >>> lines "foo\nbar"
    ["foo","bar"]

lengthInLines :: Rope -> Word #

Equivalent to `length` . `lines`, but in logarithmic time.

    >>> :set -XOverloadedStrings
    >>> lengthInLines ""
    0
    >>> lengthInLines "foo"
    1
    >>> lengthInLines "foo\n"
    1
    >>> lengthInLines "foo\n\n"
    2
    >>> lengthInLines "foo\nbar"
    2

If you do not care about ignoring the last newline character, you can use `posLine` . `lengthAsPosition` instead, which works in O(1).

splitAtLine :: Word -> Rope -> (Rope, Rope) #

Split at given line, logarithmic time.

    >>> :set -XOverloadedStrings
    >>> map (\l -> splitAtLine l "foo\nbar") [0..3]
    [("","foo\nbar"),("foo\n","bar"),("foo\nbar",""),("foo\nbar","")]

getLine :: Word -> Rope -> Rope #

Get a line by its 0-based index. Returns `mempty` if the index is out of bounds. The result doesn't contain `\n` characters.

    >>> :set -XOverloadedStrings
    >>> map (\l -> getLine l "foo\nbar\n😊😊\n\n") [0..3]
    ["foo","bar","😊😊",""]

Since: 0.3

# UTF-8 code units

length :: Rope -> Word #

Length in UTF-8 code units aka bytes, O(1).

    >>> :set -XOverloadedStrings
    >>> length "fя𐀀"
    7
    >>> Data.Text.Rope.length "fя𐀀"
    3

splitAt :: Word -> Rope -> Maybe (Rope, Rope) #

Split at given UTF-8 code unit aka byte. If requested number of code units splits a code point in half, return `Nothing`. Takes linear time.

    >>> :set -XOverloadedStrings
    >>> map (\c -> splitAt c "fя𐀀") [0..7]
    [Just ("","fя𐀀"),Just ("f","я𐀀"),Nothing,Just ("fя","𐀀"),Nothing,Nothing,Nothing,Just ("fя𐀀","")]

data Position #

Represent a position in a text.

Constructors

Position |
Fields posLine :: !Word Line. posColumn :: !Word Column in UTF-8 code units aka bytes.

#### Instances

Instances details

NFData Position # |
Instance details Defined in Data.Text.Utf8.Lines Methods rnf :: Position -> () #
Monoid Position # |
Instance details Defined in Data.Text.Utf8.Lines Methods mempty :: Position # mappend :: Position -> Position -> Position # mconcat :: [Position] -> Position #
Semigroup Position # | Associativity does not hold when `posLine` overflows.
Instance details Defined in Data.Text.Utf8.Lines Methods (<>) :: Position -> Position -> Position # sconcat :: NonEmpty Position -> Position # stimes :: Integral b => b -> Position -> Position #
Show Position # |
Instance details Defined in Data.Text.Utf8.Lines Methods showsPrec :: Int -> Position -> ShowS # show :: Position -> String # showList :: [Position] -> ShowS #
Eq Position # |
Instance details Defined in Data.Text.Utf8.Lines Methods (==) :: Position -> Position -> Bool # (/=) :: Position -> Position -> Bool #
Ord Position # |
Instance details Defined in Data.Text.Utf8.Lines Methods compare :: Position -> Position -> Ordering # (<) :: Position -> Position -> Bool # (<=) :: Position -> Position -> Bool # (>) :: Position -> Position -> Bool # (>=) :: Position -> Position -> Bool # max :: Position -> Position -> Position # min :: Position -> Position -> Position #

lengthAsPosition :: Rope -> Position #

Measure text length as an amount of lines and columns. Time is linear in the length of the last line.

    >>> :set -XOverloadedStrings
    >>> lengthAsPosition "f𐀀"
    Position {posLine = 0, posColumn = 5}
    >>> lengthAsPosition "f\n𐀀"
    Position {posLine = 1, posColumn = 4}
    >>> lengthAsPosition "f\n𐀀\n"
    Position {posLine = 2, posColumn = 0}

splitAtPosition :: Position -> Rope -> Maybe (Rope, Rope) #

Combination of `splitAtLine` and subsequent `splitAt`. Time is linear in `posColumn` and logarithmic in `posLine`.

    >>> :set -XOverloadedStrings
    >>> splitAtPosition (Position 1 0) "f\n𐀀я"
    Just ("f\n","𐀀я")
    >>> splitAtPosition (Position 1 1) "f\n𐀀я"
    Nothing
    >>> splitAtPosition (Position 1 4) "f\n𐀀я"
    Just ("f\n𐀀","я")
    >>> splitAtPosition (Position 0 2) "f\n𐀀я"
    Just ("f\n","𐀀я")
    >>> splitAtPosition (Position 0 3) "f\n𐀀я"
    Nothing
    >>> splitAtPosition (Position 0 6) "f\n𐀀я"
    Just ("f\n𐀀","я")