{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK hide #-}

-- This is an Internal module, hidden from Haddock
module Core.Text.Parsing
  ( calculatePositionEnd,
  )
where

import Core.Text.Rope
import Data.Foldable (foldl')
import qualified Data.Text.Short as S (ShortText, foldl')

{- |
Calculate the line number and column number of a Rope (interpreting it as if
is a block of text in a file). By the convention observed by all leading
brands of text editor, lines and columns are @1@ origin, so an empty Rope is
position @(1,1)@.
-}
-- Of course, if Rope itself cached position information in the FingerTree
-- monoid this would be trivial.
calculatePositionEnd :: Rope -> (Int, Int)
calculatePositionEnd :: Rope -> (Int, Int)
calculatePositionEnd Rope
text =
  let x :: FingerTree Width ShortText
x = Rope -> FingerTree Width ShortText
unRope Rope
text
      (Int
l, Int
c) = ((Int, Int) -> ShortText -> (Int, Int))
-> (Int, Int) -> FingerTree Width ShortText -> (Int, Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Int, Int) -> ShortText -> (Int, Int)
calculateChunk (Int
1, Int
1) FingerTree Width ShortText
x
   in (Int
l, Int
c)

calculateChunk :: (Int, Int) -> S.ShortText -> (Int, Int)
calculateChunk :: (Int, Int) -> ShortText -> (Int, Int)
calculateChunk (Int, Int)
loc ShortText
piece =
  ((Int, Int) -> Char -> (Int, Int))
-> (Int, Int) -> ShortText -> (Int, Int)
forall a. (a -> Char -> a) -> a -> ShortText -> a
S.foldl' (Int, Int) -> Char -> (Int, Int)
f (Int, Int)
loc ShortText
piece
  where
    f :: (Int, Int) -> Char -> (Int, Int)
    f :: (Int, Int) -> Char -> (Int, Int)
f !(!Int
l, !Int
c) Char
ch =
      if Char
ch Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n'
        then (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
1)
        else (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)