{-# LANGUAGE NoImplicitPrelude #-}
module Text.Pandoc.Readers.Org.ExportSettings
( exportSettings
) where
import Prelude
import Text.Pandoc.Class (PandocMonad, report)
import Text.Pandoc.Logging (LogMessage (UnknownOrgExportOption))
import Text.Pandoc.Readers.Org.ParserState
import Text.Pandoc.Readers.Org.Parsing
import Control.Monad (mzero, void)
import Data.Char (toLower)
import Data.Maybe (listToMaybe)
exportSettings :: PandocMonad m => OrgParser m ()
exportSettings = void $ sepBy skipSpaces exportSetting
type ExportSettingSetter a = a -> ExportSettings -> ExportSettings
exportSetting :: PandocMonad m => OrgParser m ()
exportSetting = choice
[ booleanSetting "^" (\val es -> es { exportSubSuperscripts = val })
, booleanSetting "'" (\val es -> es { exportSmartQuotes = val })
, booleanSetting "*" (\val es -> es { exportEmphasizedText = val })
, booleanSetting "-" (\val es -> es { exportSpecialStrings = val })
, ignoredSetting ":"
, ignoredSetting "<"
, booleanSetting "\\n" (\val es -> es { exportPreserveBreaks = val })
, archivedTreeSetting "arch" (\val es -> es { exportArchivedTrees = val })
, booleanSetting "author" (\val es -> es { exportWithAuthor = val })
, ignoredSetting "c"
, booleanSetting "creator" (\val es -> es { exportWithCreator = val })
, complementableListSetting "d" (\val es -> es { exportDrawers = val })
, ignoredSetting "date"
, ignoredSetting "e"
, booleanSetting "email" (\val es -> es { exportWithEmail = val })
, ignoredSetting "f"
, integerSetting "H" (\val es -> es { exportHeadlineLevels = val })
, ignoredSetting "inline"
, ignoredSetting "num"
, booleanSetting "p" (\val es -> es { exportWithPlanning = val })
, ignoredSetting "pri"
, ignoredSetting "prop"
, ignoredSetting "stat"
, booleanSetting "tags" (\val es -> es { exportWithTags = val })
, ignoredSetting "tasks"
, ignoredSetting "tex"
, ignoredSetting "timestamp"
, ignoredSetting "title"
, ignoredSetting "toc"
, booleanSetting "todo" (\val es -> es { exportWithTodoKeywords = val })
, ignoredSetting "|"
, ignoreAndWarn
] <?> "export setting"
genericExportSetting :: Monad m
=> OrgParser m a
-> String
-> ExportSettingSetter a
-> OrgParser m ()
genericExportSetting optionParser settingIdentifier setter = try $ do
_ <- string settingIdentifier *> char ':'
value <- optionParser
updateState $ modifyExportSettings value
where
modifyExportSettings val st =
st { orgStateExportSettings = setter val . orgStateExportSettings $ st }
booleanSetting :: Monad m => String -> ExportSettingSetter Bool -> OrgParser m ()
booleanSetting = genericExportSetting elispBoolean
integerSetting :: Monad m => String -> ExportSettingSetter Int -> OrgParser m ()
integerSetting = genericExportSetting parseInt
where
parseInt = try $
many1 digit >>= maybe mzero (return . fst) . listToMaybe . reads
archivedTreeSetting :: Monad m
=> String
-> ExportSettingSetter ArchivedTreesOption
-> OrgParser m ()
archivedTreeSetting =
genericExportSetting $ archivedTreesHeadlineSetting <|> archivedTreesBoolean
where
archivedTreesHeadlineSetting = try $ do
_ <- string "headline"
lookAhead (newline <|> spaceChar)
return ArchivedTreesHeadlineOnly
archivedTreesBoolean = try $ do
exportBool <- elispBoolean
return $
if exportBool
then ArchivedTreesExport
else ArchivedTreesNoExport
complementableListSetting :: Monad m
=> String
-> ExportSettingSetter (Either [String] [String])
-> OrgParser m ()
complementableListSetting = genericExportSetting $ choice
[ Left <$> complementStringList
, Right <$> stringList
, (\b -> if b then Left [] else Right []) <$> elispBoolean
]
where
stringList :: Monad m => OrgParser m [String]
stringList = try $
char '('
*> sepBy elispString spaces
<* char ')'
complementStringList :: Monad m => OrgParser m [String]
complementStringList = try $
string "(not "
*> sepBy elispString spaces
<* char ')'
elispString :: Monad m => OrgParser m String
elispString = try $
char '"'
*> manyTill alphaNum (char '"')
ignoredSetting :: Monad m => String -> OrgParser m ()
ignoredSetting s = try (() <$ string s <* char ':' <* many1 nonspaceChar)
ignoreAndWarn :: PandocMonad m => OrgParser m ()
ignoreAndWarn = try $ do
opt <- many1 nonspaceChar
report (UnknownOrgExportOption opt)
return ()
elispBoolean :: Monad m => OrgParser m Bool
elispBoolean = try $ do
value <- many1 nonspaceChar
return $ case map toLower value of
"nil" -> False
"{}" -> False
"()" -> False
_ -> True