packages feed

kb-text-layout-0.1.0.0: src/KB/Text/Layout/Segmentation.hs

module KB.Text.Layout.Segmentation
  ( -- * Break opportunities in character offsets
    softBreaks
  , wordBreaks
  , boundaries

    -- * Grapheme clusters
  , clusters
  ) where

import Data.IntMap.Strict qualified as IntMap
import Data.List (scanl')
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Internal.Encoding.Utf8 (utf8Length)

import KB.Text.Shape.Segmentation (clusters)
import KB.Text.Shape.Segmentation qualified as Segmentation

softBreaks :: Text -> [Int]
softBreaks t = charOffsets t (Segmentation.softBreaks t)

wordBreaks :: Text -> [Int]
wordBreaks t = charOffsets t (Segmentation.wordBreaks t)

boundaries :: Text -> [Int]
boundaries t = charOffsets t (Segmentation.boundaries t)

charOffsets :: Text -> [Int] -> [Int]
charOffsets t = map toChar
  where
    starts = IntMap.fromDistinctAscList (zip byteStarts [0 ..])
    byteStarts = scanl' (\off c -> off + utf8Length c) 0 (Text.unpack t)
    toChar o = maybe 0 snd (IntMap.lookupLE o starts)