packages feed

srt-attoparsec-0.1.0.0: src/Media/Subtitles/SRT/Attoparsec.hs

{-# LANGUAGE OverloadedStrings #-}

module Media.Subtitles.SRT.Attoparsec
  ( parseLine,
    parseSRT,
    parseDialog,
  )
where

import Control.Applicative
import Control.Monad.State
import Data.Attoparsec.Text
import Data.Text as T
import Media.Subtitles.SRT
import Media.Timestamp
import Media.Timestamp.Attoparsec

-- | Parse a single line.
--
-- @since 0.1.0.0
parseLine :: Parser Line
parseLine =
  Line <$> parseIndex <*> parseRangeA parseTimec <* endOfLine <*> parseDialog

parseIndex :: Parser Int
parseIndex = decimal <* endOfLine

-- | Parse a dialogue section
--
-- @since 0.1.0.0
parseDialog :: Parser Text
parseDialog = fmap (T.intercalate "\n") $ execStateT f []
  where
    f = do
      line <- lift $ takeWhile1 (not . isEndOfLine) <* endOfLine
      modify
        (<> [line])
      (lift endOfInput *> pure ())
        <|> (lift endOfLine *> pure ())
        <|> f

-- | Parse a whole subtitles file.
--
-- @since 0.1.0.0
parseSRT :: Parser SRT
parseSRT = SRT <$> many1 parseLine