text-rope-0.3: Text lines and ropes

Copyright | (c) 2021-2022 Andrew Lelechenko
License | BSD3
Maintainer | Andrew Lelechenko <andrew.lelechenko@gmail.com>
Safe Haskell | None
Language | Haskell2010

Data.Text.Lines

Contents

- Lines
- Code points

Description

Synopsis

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

# Documentation

data TextLines #

A wrapper around `Text` for fast line/column navigation. Concatenation takes linear time.

This is a building block for `Rope`, which provides logarithmic concatenation.

#### Instances

Instances details

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

fromText :: Text -> TextLines #

Create from `Text`, linear time.

toText :: TextLines -> Text #

Extract `Text`, O(1).

null :: TextLines -> Bool #

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

# Lines

getLine :: Word -> TextLines -> TextLines #

Get line with given 0-based index, O(1). The result does not contain `\n` characters.. Returns `mempty` if the line index is out of bounds.

    >>> :set -XOverloadedStrings
    >>> map (\l -> getLine l "fя𐀀\n☺bar\n\n") [0..3]
    ["fя𐀀","☺bar","",""]

Since: 0.3

lines :: TextLines -> [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 :: TextLines -> Word #

Equivalent to `length` . `lines`, but in O(1).

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

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

Split at given line, O(1).

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

# Code points

length :: TextLines -> Word #

Length in code points, similar to `Data.Text.``length`. Takes linear time.

    >>> :set -XOverloadedStrings
    >>> length "fя𐀀"
    3
    >>> Data.Text.Utf16.Lines.length "fя𐀀"
    4

span :: (Char -> Bool) -> TextLines -> (TextLines, TextLines) #

Span by a predicate, similar to `Data.Text.``span`. Takes linear (by length of the prefix satisfying the predicate) time.

splitAt :: Word -> TextLines -> (TextLines, TextLines) #

Split at given code point, similar to `Data.Text.``splitAt`. Takes linear time.

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

data Position #

Represent a position in a text.

Constructors

Position |

Fields

- posLine :: !Word

  Line.

- posColumn :: !Word

  Column in code points.

#### Instances

Instances details

NFData Position # |
Instance details Defined in Data.Text.Lines.Internal Methods rnf :: Position -> () #
Monoid Position # |
Instance details Defined in Data.Text.Lines.Internal 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.Lines.Internal Methods (<>) :: Position -> Position -> Position # sconcat :: NonEmpty Position -> Position # stimes :: Integral b => b -> Position -> Position #
Show Position # |
Instance details Defined in Data.Text.Lines.Internal Methods showsPrec :: Int -> Position -> ShowS # show :: Position -> String # showList :: [Position] -> ShowS #
Eq Position # |
Instance details Defined in Data.Text.Lines.Internal Methods (==) :: Position -> Position -> Bool # (/=) :: Position -> Position -> Bool #
Ord Position # |
Instance details Defined in Data.Text.Lines.Internal 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 :: TextLines -> Position #

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

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

splitAtPosition :: Position -> TextLines -> (TextLines, TextLines) #

Combination of `splitAtLine` and subsequent `splitAt`. Time is linear in `posColumn`, but does not depend on `posLine`.

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