hascard-0.6.0.2: src/Export.hs
{-# LANGUAGE TemplateHaskell #-}
module Export where
import Lens.Micro.Platform
import qualified Data.List.NonEmpty as NE
import Types
import Data.Either.Extra (mapRight)
import Data.List.Extra (replace)
import Data.List (intercalate, stripPrefix, tails, isPrefixOf)
data ExportOpts = ExportOpts
{ _optExportInput :: String
, _optExportOutput :: String
, _optCardDelimiter :: String
, _optQuestionDelimiter :: String
}
makeLenses ''ExportOpts
exportCards :: ExportOpts -> [Card] -> Either String String
exportCards opts = mapRight (intercalate (opts ^. optCardDelimiter))
. mapM (exportCard opts)
exportCard :: ExportOpts -> Card -> Either String String
exportCard opts (Definition {question=q, definition=d}) = Right $
escape opts q <> (opts ^. optQuestionDelimiter) <> escape opts d
exportCard opts (OpenQuestion {question=q, perforated=p}) = Right $
escape opts q <> (opts ^. optQuestionDelimiter) <> escape opts (fillPerforated p)
exportCard _ _ = Left "Only definition and open question cards can be exported."
fillPerforated :: Perforated -> String
fillPerforated = foldSentence id fSent . perforatedToSentence
where fSent pre gaps post = pre <> concat (NE.intersperse "/" gaps) <> post
escape :: ExportOpts -> String -> String
escape opts s = if s `contains` (opts ^. optCardDelimiter) || s `contains` (opts ^. optQuestionDelimiter)
then "\"" <> replace "\"" "\"\"" s <> "\""
else s
contains :: Eq a => [a] -> [a] -> Bool
contains str substr = any (isPrefixOf substr) (tails str)