<commit_before>{- |
Module      :  Text.HTML.TagSoup.Position

Maintainer  :  <EMAIL>
Stability   :  provisional
Portability :  portable

Position in a file.

Cf. to Text.ParserCombinators.Parsec.Pos
-}

module Text.HTML.TagSoup.Position (
    Position, FileName, Row, Column,
    new, initialize,
    setRow, setColumn, setFileName,
    getRow, getColumn, getFileName,
    incRow, incColumn,
    updateOnChar, updateOnString,
    toReportText,
   ) where

import Data.List (foldl')

type FileName = String
type Row      = Int
type Column   = Int

{- |
Position in a file consisting of file name, row and column coordinates.
Upper left is (0,0), but show routines can display this with different offsets.
-}
data Position =
   Position {
      fileName :: FileName,
      row      :: !Row,
      column   :: !Column
   } deriving (Eq,Ord)


new :: FileName -> Row -> Column -> Position
new = Position

initialize :: FileName -> Position
initialize fn = new fn 0 0


-- * access functions

getFileName :: Position -> FileName
getFileName = fileName

getRow :: Position -> Row
getRow = row

getColumn :: Position -> Column
getColumn = column

incRow :: Row -> Position -> Position
incRow n p = p{row = getRow p + n}

incColumn :: Column -> Position -> Position
incColumn n p = p{column = getColumn p + n}

setFileName :: FileName -> Position -> Position
setFileName fn p = p{fileName = fn}

setRow :: Row -> Position -> Position
setRow n p = p{row = n}

setColumn :: Column -> Position -> Position
setColumn n p = p{column = n}


-- * update position according to read characters

updateOnString :: Position -> String -> Position
updateOnString pos string =
   foldl' (flip updateOnChar) pos string

updateOnChar   :: Char -> Position -> Position
updateOnChar char pos@(Position _ r c) =
   let (newRow, newColumn) =
          case char of
            '\n' -> (succ r, 0)
            '\t' -> (r, c + 8 - mod c 8)
            _    -> (r, succ c)
   in  setRow newRow $ setColumn newColumn pos


-- * update position according to read characters

{- |
Convert the file position to a format
that development environments can understand.
-}<commit_msg>Flip the order of updateOnChar to match updateOnString<commit_after>{- |
Module      :  Text.HTML.TagSoup.Position

Maintainer  :  <EMAIL>
Stability   :  provisional
Portability :  portable

Position in a file.

Cf. to Text.ParserCombinators.Parsec.Pos
-}

module Text.HTML.TagSoup.Position (
    Position(..), FileName, Row, Column,
    new, initialize,
    setRow, setColumn, setFileName,
    getRow, getColumn, getFileName,
    incRow, incColumn,
    updateOnChar, updateOnString,
    toReportText,
   ) where

import Data.List (foldl')

type FileName = String
type Row      = Int
type Column   = Int

{- |
Position in a file consisting of file name, row and column coordinates.
Upper left is (0,0), but show routines can display this with different offsets.
-}
data Position =
   Position {
      fileName :: FileName,
      row      :: !Row,
      column   :: !Column
   } deriving (Eq,Ord)


new :: FileName -> Row -> Column -> Position
new = Position

initialize :: FileName -> Position
initialize fn = new fn 0 0


-- * access functions

getFileName :: Position -> FileName
getFileName = fileName

getRow :: Position -> Row
getRow = row

getColumn :: Position -> Column
getColumn = column

incRow :: Row -> Position -> Position
incRow n p = p{row = getRow p + n}

incColumn :: Column -> Position -> Position
incColumn n p = p{column = getColumn p + n}

setFileName :: FileName -> Position -> Position
setFileName fn p = p{fileName = fn}

setRow :: Row -> Position -> Position
setRow n p = p{row = n}

setColumn :: Column -> Position -> Position
setColumn n p = p{column = n}


-- * update position according to read characters

updateOnString :: Position -> String -> Position
updateOnString pos string =
   foldl' updateOnChar pos string

updateOnChar   :: Position -> Char -> Position
updateOnChar pos@(Position _ r c) char =
   let (newRow, newColumn) =
          case char of
            '\n' -> (succ r, 0)
            '\t' -> (r, c + 8 - mod c 8)
            _    -> (r, succ c)
   in  setRow newRow $ setColumn newColumn pos


-- * update position according to read characters

{- |
Convert the file position to a format
that development environments can understand.
-}
{'fraction_non_alphanumeric': 0.10346420323325635, 'fraction_numerical': 0.003233256351039261, 'mean_word_length': 2.912375790424571, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '492766', 'n_tokens_mistral': 1305, 'n_tokens_neox': 1284, 'n_words': 480}