packages feed

musicScroll-0.1.0.0: src/MusicScroll/TagParsing.hs

{-# language OverloadedStrings #-}
module MusicScroll.TagParsing (extractLyricsFromPage) where

import qualified Data.Char as C
import           Data.Text (Text)
import           Data.Text as T hiding (filter, tail, map)
import           Text.HTML.TagSoup

extractLyricsFromPage :: Text -> [Text]
extractLyricsFromPage page =
  let stream = parseTags page
      pass1  = flip filter stream
        (\t -> (not (isScript t)) && noEmptyText t && validTags t)
      stream2 = zip3 pass1 (tail pass1) (tail (tail pass1))
      pass2   = map (\(t, _, _) -> t) $ filter isStrophe stream2
  in cleanOut pass2

-- Pass 1
validTags, noEmptyText :: Tag Text -> Bool
validTags t = isTagOpenName "br" t   || isTagCloseName "div" t
            || isTagOpenName "div" t || isTagCloseName "div" t
            || isTagText t

noEmptyText =
  let invalidChars c = C.isSpace c || c == '\\' || c == 'n'
                       || c == 'r' || c == 't'
  in maybe True (not . T.all invalidChars) . maybeTagText

-- Pass 2
isScript :: Tag Text -> Bool
isScript = let invalidChars c = c == '>' || c == '{'
           in maybe False (T.any invalidChars) . maybeTagText

-- Pass 3
isStrophe :: (Tag Text, Tag Text, Tag Text) -> Bool
isStrophe (TagText _, TagOpen "br" _, TagText _) = True
isStrophe (TagText _, TagOpen "br" _, TagOpen "br" _) = True
isStrophe (TagOpen "br" _, TagOpen "br" _, _) = True -- breakline
isStrophe _ = False

-- Cleaning output
cleanOut :: [Tag Text] -> [Text]
cleanOut =   map (T.strip . T.replace "\\n" "")
           . map (maybe "\n" id . maybeTagText)