Blame src/Text/Pandoc/Readers/Org/ParserState.hs

Packit Service d2f85f
{-# LANGUAGE FlexibleInstances     #-}
Packit Service d2f85f
{-# LANGUAGE MultiParamTypeClasses #-}
Packit Service d2f85f
{-
Packit Service d2f85f
Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
Packit Service d2f85f
Packit Service d2f85f
This program is free software; you can redistribute it and/or modify
Packit Service d2f85f
it under the terms of the GNU General Public License as published by
Packit Service d2f85f
the Free Software Foundation; either version 2 of the License, or
Packit Service d2f85f
(at your option) any later version.
Packit Service d2f85f
Packit Service d2f85f
This program is distributed in the hope that it will be useful,
Packit Service d2f85f
but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d2f85f
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d2f85f
GNU General Public License for more details.
Packit Service d2f85f
Packit Service d2f85f
You should have received a copy of the GNU General Public License
Packit Service d2f85f
along with this program; if not, write to the Free Software
Packit Service d2f85f
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service d2f85f
-}
Packit Service d2f85f
Packit Service d2f85f
{- |
Packit Service d2f85f
   Module      : Text.Pandoc.Readers.Org.ParserState
Packit Service d2f85f
   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
Packit Service d2f85f
   License     : GNU GPL, version 2 or above
Packit Service d2f85f
Packit Service d2f85f
   Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
Packit Service d2f85f
Packit Service d2f85f
Define the Org-mode parser state.
Packit Service d2f85f
-}
Packit Service d2f85f
module Text.Pandoc.Readers.Org.ParserState
Packit Service d2f85f
  ( OrgParserState (..)
Packit Service d2f85f
  , OrgParserLocal (..)
Packit Service d2f85f
  , OrgNoteRecord
Packit Service d2f85f
  , HasReaderOptions (..)
Packit Service d2f85f
  , HasQuoteContext (..)
Packit Service d2f85f
  , HasMacros (..)
Packit Service d2f85f
  , TodoMarker (..)
Packit Service d2f85f
  , TodoSequence
Packit Service d2f85f
  , TodoState (..)
Packit Service d2f85f
  , activeTodoMarkers
Packit Service d2f85f
  , registerTodoSequence
Packit Service d2f85f
  , MacroExpander
Packit Service d2f85f
  , lookupMacro
Packit Service d2f85f
  , registerMacro
Packit Service d2f85f
  , F
Packit Service d2f85f
  , askF
Packit Service d2f85f
  , asksF
Packit Service d2f85f
  , trimInlinesF
Packit Service d2f85f
  , runF
Packit Service d2f85f
  , returnF
Packit Service d2f85f
  , ExportSettings (..)
Packit Service d2f85f
  , ArchivedTreesOption (..)
Packit Service d2f85f
  , optionsToParserState
Packit Service d2f85f
  ) where
Packit Service d2f85f
Packit Service d2f85f
import Control.Monad.Reader (ReaderT, asks, local)
Packit Service d2f85f
Packit Service d2f85f
import Data.Default (Default (..))
Packit Service d2f85f
import qualified Data.Map as M
Packit Service d2f85f
import qualified Data.Set as Set
Packit Service d2f85f
import Data.Text (Text)
Packit Service d2f85f
Packit Service d2f85f
import Text.Pandoc.Builder (Blocks, Inlines)
Packit Service d2f85f
import Text.Pandoc.Definition (Meta (..), nullMeta)
Packit Service d2f85f
import Text.Pandoc.Logging
Packit Service d2f85f
import Text.Pandoc.Options (ReaderOptions (..))
Packit Service d2f85f
import Text.Pandoc.Parsing (Future, HasHeaderMap (..), HasIdentifierList (..),
Packit Service d2f85f
                            HasIncludeFiles (..), HasLastStrPosition (..),
Packit Service d2f85f
                            HasLogMessages (..), HasMacros (..),
Packit Service d2f85f
                            HasQuoteContext (..), HasReaderOptions (..),
Packit Service d2f85f
                            ParserContext (..), QuoteContext (..), SourcePos,
Packit Service d2f85f
                            askF, asksF, returnF, runF, trimInlinesF)
Packit Service d2f85f
import Text.Pandoc.Readers.LaTeX.Types (Macro)
Packit Service d2f85f
Packit Service d2f85f
-- | This is used to delay evaluation until all relevant information has been
Packit Service d2f85f
-- parsed and made available in the parser state.
Packit Service d2f85f
type F = Future OrgParserState
Packit Service d2f85f
Packit Service d2f85f
-- | An inline note / footnote containing the note key and its (inline) value.
Packit Service d2f85f
type OrgNoteRecord = (String, F Blocks)
Packit Service d2f85f
-- | Table of footnotes
Packit Service d2f85f
type OrgNoteTable = [OrgNoteRecord]
Packit Service d2f85f
-- | Map of functions for link transformations.  The map key is refers to the
Packit Service d2f85f
-- link-type, the corresponding function transforms the given link string.
Packit Service d2f85f
type OrgLinkFormatters = M.Map String (String -> String)
Packit Service d2f85f
-- | Macro expander function
Packit Service d2f85f
type MacroExpander = [String] -> String
Packit Service d2f85f
Packit Service d2f85f
-- | The states in which a todo item can be
Packit Service d2f85f
data TodoState = Todo | Done
Packit Service d2f85f
  deriving (Eq, Ord, Show)
Packit Service d2f85f
Packit Service d2f85f
-- | A ToDo keyword like @TODO@ or @DONE@.
Packit Service d2f85f
data TodoMarker = TodoMarker
Packit Service d2f85f
  { todoMarkerState :: TodoState
Packit Service d2f85f
  , todoMarkerName  :: String
Packit Service d2f85f
  }
Packit Service d2f85f
  deriving (Show, Eq)
Packit Service d2f85f
Packit Service d2f85f
-- | Collection of todo markers in the order in which items should progress
Packit Service d2f85f
type TodoSequence = [TodoMarker]
Packit Service d2f85f
Packit Service d2f85f
-- | Org-mode parser state
Packit Service d2f85f
data OrgParserState = OrgParserState
Packit Service d2f85f
  { orgStateAnchorIds            :: [String]
Packit Service d2f85f
  , orgStateEmphasisCharStack    :: [Char]
Packit Service d2f85f
  , orgStateEmphasisNewlines     :: Maybe Int
Packit Service d2f85f
  , orgStateExportSettings       :: ExportSettings
Packit Service d2f85f
  , orgStateHeaderMap            :: M.Map Inlines String
Packit Service d2f85f
  , orgStateIdentifiers          :: Set.Set String
Packit Service d2f85f
  , orgStateIncludeFiles         :: [String]
Packit Service d2f85f
  , orgStateLastForbiddenCharPos :: Maybe SourcePos
Packit Service d2f85f
  , orgStateLastPreCharPos       :: Maybe SourcePos
Packit Service d2f85f
  , orgStateLastStrPos           :: Maybe SourcePos
Packit Service d2f85f
  , orgStateLinkFormatters       :: OrgLinkFormatters
Packit Service d2f85f
  , orgStateMacros               :: M.Map String MacroExpander
Packit Service d2f85f
  , orgStateMacroDepth           :: Int
Packit Service d2f85f
  , orgStateMeta                 :: F Meta
Packit Service d2f85f
  , orgStateNotes'               :: OrgNoteTable
Packit Service d2f85f
  , orgStateOptions              :: ReaderOptions
Packit Service d2f85f
  , orgStateParserContext        :: ParserContext
Packit Service d2f85f
  , orgStateTodoSequences        :: [TodoSequence]
Packit Service d2f85f
  , orgLogMessages               :: [LogMessage]
Packit Service d2f85f
  , orgMacros                    :: M.Map Text Macro
Packit Service d2f85f
  }
Packit Service d2f85f
Packit Service d2f85f
data OrgParserLocal = OrgParserLocal { orgLocalQuoteContext :: QuoteContext }
Packit Service d2f85f
Packit Service d2f85f
instance Default OrgParserLocal where
Packit Service d2f85f
  def = OrgParserLocal NoQuote
Packit Service d2f85f
Packit Service d2f85f
instance HasReaderOptions OrgParserState where
Packit Service d2f85f
  extractReaderOptions = orgStateOptions
Packit Service d2f85f
Packit Service d2f85f
instance HasLastStrPosition OrgParserState where
Packit Service d2f85f
  getLastStrPos = orgStateLastStrPos
Packit Service d2f85f
  setLastStrPos pos st = st{ orgStateLastStrPos = Just pos }
Packit Service d2f85f
Packit Service d2f85f
instance Monad m => HasQuoteContext st (ReaderT OrgParserLocal m) where
Packit Service d2f85f
  getQuoteContext = asks orgLocalQuoteContext
Packit Service d2f85f
  withQuoteContext q = local (\s -> s{orgLocalQuoteContext = q})
Packit Service d2f85f
Packit Service d2f85f
instance HasIdentifierList OrgParserState where
Packit Service d2f85f
  extractIdentifierList = orgStateIdentifiers
Packit Service d2f85f
  updateIdentifierList f s = s{ orgStateIdentifiers = f (orgStateIdentifiers s) }
Packit Service d2f85f
Packit Service d2f85f
instance HasHeaderMap OrgParserState where
Packit Service d2f85f
  extractHeaderMap = orgStateHeaderMap
Packit Service d2f85f
  updateHeaderMap  f s = s{ orgStateHeaderMap = f (orgStateHeaderMap s) }
Packit Service d2f85f
Packit Service d2f85f
instance HasLogMessages OrgParserState where
Packit Service d2f85f
  addLogMessage msg st = st{ orgLogMessages = msg : orgLogMessages st }
Packit Service d2f85f
  getLogMessages st = reverse $ orgLogMessages st
Packit Service d2f85f
Packit Service d2f85f
instance HasMacros OrgParserState where
Packit Service d2f85f
  extractMacros st = orgMacros st
Packit Service d2f85f
  updateMacros f st = st{ orgMacros = f (orgMacros st) }
Packit Service d2f85f
Packit Service d2f85f
instance HasIncludeFiles OrgParserState where
Packit Service d2f85f
  getIncludeFiles = orgStateIncludeFiles
Packit Service d2f85f
  addIncludeFile f st = st { orgStateIncludeFiles = f : orgStateIncludeFiles st }
Packit Service d2f85f
  dropLatestIncludeFile st =
Packit Service d2f85f
    st { orgStateIncludeFiles = drop 1 $ orgStateIncludeFiles st }
Packit Service d2f85f
Packit Service d2f85f
instance Default OrgParserState where
Packit Service d2f85f
  def = defaultOrgParserState
Packit Service d2f85f
Packit Service d2f85f
defaultOrgParserState :: OrgParserState
Packit Service d2f85f
defaultOrgParserState = OrgParserState
Packit Service d2f85f
  { orgStateAnchorIds = []
Packit Service d2f85f
  , orgStateEmphasisCharStack = []
Packit Service d2f85f
  , orgStateEmphasisNewlines = Nothing
Packit Service d2f85f
  , orgStateExportSettings = def
Packit Service d2f85f
  , orgStateHeaderMap = M.empty
Packit Service d2f85f
  , orgStateIdentifiers = Set.empty
Packit Service d2f85f
  , orgStateIncludeFiles = []
Packit Service d2f85f
  , orgStateLastForbiddenCharPos = Nothing
Packit Service d2f85f
  , orgStateLastPreCharPos = Nothing
Packit Service d2f85f
  , orgStateLastStrPos = Nothing
Packit Service d2f85f
  , orgStateLinkFormatters = M.empty
Packit Service d2f85f
  , orgStateMacros = M.empty
Packit Service d2f85f
  , orgStateMacroDepth = 0
Packit Service d2f85f
  , orgStateMeta = return nullMeta
Packit Service d2f85f
  , orgStateNotes' = []
Packit Service d2f85f
  , orgStateOptions = def
Packit Service d2f85f
  , orgStateParserContext = NullState
Packit Service d2f85f
  , orgStateTodoSequences = []
Packit Service d2f85f
  , orgLogMessages = []
Packit Service d2f85f
  , orgMacros = M.empty
Packit Service d2f85f
  }
Packit Service d2f85f
Packit Service d2f85f
optionsToParserState :: ReaderOptions -> OrgParserState
Packit Service d2f85f
optionsToParserState opts =
Packit Service d2f85f
  def { orgStateOptions = opts }
Packit Service d2f85f
Packit Service d2f85f
registerTodoSequence :: TodoSequence -> OrgParserState -> OrgParserState
Packit Service d2f85f
registerTodoSequence todoSeq st =
Packit Service d2f85f
  let curSeqs = orgStateTodoSequences st
Packit Service d2f85f
  in st{ orgStateTodoSequences = todoSeq : curSeqs }
Packit Service d2f85f
Packit Service d2f85f
-- | Get the current todo/done sequences. If no custom todo sequences have been
Packit Service d2f85f
-- defined, return a list containing just the default todo/done sequence.
Packit Service d2f85f
activeTodoSequences :: OrgParserState -> [TodoSequence]
Packit Service d2f85f
activeTodoSequences st =
Packit Service d2f85f
  let curSeqs = orgStateTodoSequences st
Packit Service d2f85f
  in if null curSeqs
Packit Service d2f85f
     then [[ TodoMarker Todo "TODO" , TodoMarker Done "DONE" ]]
Packit Service d2f85f
     else curSeqs
Packit Service d2f85f
Packit Service d2f85f
activeTodoMarkers :: OrgParserState -> TodoSequence
Packit Service d2f85f
activeTodoMarkers = concat . activeTodoSequences
Packit Service d2f85f
Packit Service d2f85f
lookupMacro :: String -> OrgParserState -> Maybe MacroExpander
Packit Service d2f85f
lookupMacro macroName = M.lookup macroName . orgStateMacros
Packit Service d2f85f
Packit Service d2f85f
registerMacro :: (String, MacroExpander) -> OrgParserState -> OrgParserState
Packit Service d2f85f
registerMacro (name, expander) st =
Packit Service d2f85f
  let curMacros = orgStateMacros st
Packit Service d2f85f
  in st{ orgStateMacros = M.insert name expander curMacros }
Packit Service d2f85f
Packit Service d2f85f
Packit Service d2f85f
Packit Service d2f85f
--
Packit Service d2f85f
-- Export Settings
Packit Service d2f85f
--
Packit Service d2f85f
Packit Service d2f85f
-- | Options for the way archived trees are handled.
Packit Service d2f85f
data ArchivedTreesOption =
Packit Service d2f85f
    ArchivedTreesExport       -- ^ Export the complete tree
Packit Service d2f85f
  | ArchivedTreesNoExport     -- ^ Exclude archived trees from exporting
Packit Service d2f85f
  | ArchivedTreesHeadlineOnly -- ^ Export only the headline, discard the contents
Packit Service d2f85f
Packit Service d2f85f
-- | Export settings <http://orgmode.org/manual/Export-settings.html>
Packit Service d2f85f
-- These settings can be changed via OPTIONS statements.
Packit Service d2f85f
data ExportSettings = ExportSettings
Packit Service d2f85f
  { exportArchivedTrees    :: ArchivedTreesOption -- ^ How to treat archived trees
Packit Service d2f85f
  , exportDrawers          :: Either [String] [String]
Packit Service d2f85f
  -- ^ Specify drawer names which should be exported.  @Left@ names are
Packit Service d2f85f
  -- explicitly excluded from the resulting output while @Right@ means that
Packit Service d2f85f
  -- only the listed drawer names should be included.
Packit Service d2f85f
  , exportEmphasizedText   :: Bool -- ^ Parse emphasized text
Packit Service d2f85f
  , exportHeadlineLevels   :: Int
Packit Service d2f85f
  -- ^ Maximum depth of headlines, deeper headlines are convert to list
Packit Service d2f85f
  , exportPreserveBreaks   :: Bool -- ^ Whether to preserve linebreaks
Packit Service d2f85f
  , exportSmartQuotes      :: Bool -- ^ Parse quotes smartly
Packit Service d2f85f
  , exportSpecialStrings   :: Bool -- ^ Parse ellipses and dashes smartly
Packit Service d2f85f
  , exportSubSuperscripts  :: Bool -- ^ TeX-like syntax for sub- and superscripts
Packit Service d2f85f
  , exportWithAuthor       :: Bool -- ^ Include author in final meta-data
Packit Service d2f85f
  , exportWithCreator      :: Bool -- ^ Include creator in final meta-data
Packit Service d2f85f
  , exportWithEmail        :: Bool -- ^ Include email in final meta-data
Packit Service d2f85f
  , exportWithTags         :: Bool -- ^ Keep tags as part of headlines
Packit Service d2f85f
  , exportWithTodoKeywords :: Bool -- ^ Keep TODO keywords in headers
Packit Service d2f85f
  }
Packit Service d2f85f
Packit Service d2f85f
instance Default ExportSettings where
Packit Service d2f85f
  def = defaultExportSettings
Packit Service d2f85f
Packit Service d2f85f
defaultExportSettings :: ExportSettings
Packit Service d2f85f
defaultExportSettings = ExportSettings
Packit Service d2f85f
  { exportArchivedTrees = ArchivedTreesHeadlineOnly
Packit Service d2f85f
  , exportDrawers = Left ["LOGBOOK"]
Packit Service d2f85f
  , exportEmphasizedText = True
Packit Service d2f85f
  , exportHeadlineLevels = 3
Packit Service d2f85f
  , exportPreserveBreaks = False
Packit Service d2f85f
  , exportSmartQuotes = False
Packit Service d2f85f
  , exportSpecialStrings = True
Packit Service d2f85f
  , exportSubSuperscripts = True
Packit Service d2f85f
  , exportWithAuthor = True
Packit Service d2f85f
  , exportWithCreator = True
Packit Service d2f85f
  , exportWithEmail = True
Packit Service d2f85f
  , exportWithTags = True
Packit Service d2f85f
  , exportWithTodoKeywords = True
Packit Service d2f85f
  }