git.iko.soy/typeable/pandoc
on master help sign in
Org reader: respect drawer export setting

The `d` export option can be used to control which drawers are exported and which are discarded. Basic support for this option is added here.

commita4717c2fc5d82bc4740b21927ca7db3115a8b1af authorAlbert Krewinkel <albert@zeitkraut.de> dateSun 22 May 2016, 22:26 (10 years ago) parentf3d27e4
3 files changed+103−13
src/Text/Pandoc/Readers/Org.hs+65−11 src/Text/Pandoc/Readers/Org/ParserState.hs+14−1 tests/Tests/Readers/Org.hs+24−1
src/Text/Pandoc/Readers/Org.hs+65−11
@@ -138,7 +138,7 @@ exportSetting = choice
138138 , ignoredSetting "author"
139139 , ignoredSetting "c"
140140 , ignoredSetting "creator"
141− , ignoredSetting "d"
141+ , complementableListSetting "d" setExportDrawers
142142 , ignoredSetting "date"
143143 , ignoredSetting "e"
144144 , ignoredSetting "email"
@@ -164,15 +164,53 @@ booleanSetting :: String -> ExportSettingSetter Bool -> OrgParser ()
164164booleanSetting settingIdentifier setter = try $ do
165165 string settingIdentifier
166166 char ':'
167− value <- many nonspaceChar
168− let boolValue = case value of
169− "nil" -> False
170− "{}" -> False
171− _ -> True
172− updateState $ modifyExportSettings setter boolValue
167+ value <- elispBoolean
168+ updateState $ modifyExportSettings setter value
169+
170+-- | Read an elisp boolean. Only NIL is treated as false, non-NIL values are
171+-- interpreted as true.
172+elispBoolean :: OrgParser Bool
173+elispBoolean = try $ do
174+ value <- many1 nonspaceChar
175+ return $ case map toLower value of
176+ "nil" -> False
177+ "{}" -> False
178+ "()" -> False
179+ _ -> True
180+
181+-- | A list or a complement list (i.e. a list starting with `not`).
182+complementableListSetting :: String
183+ -> ExportSettingSetter (Either [String] [String])
184+ -> OrgParser ()
185+complementableListSetting settingIdentifier setter = try $ do
186+ _ <- string settingIdentifier <* char ':'
187+ value <- choice [ Left <$> complementStringList
188+ , Right <$> stringList
189+ , (\b -> if b then Left [] else Right []) <$> elispBoolean
190+ ]
191+ updateState $ modifyExportSettings setter value
192+ where
193+ -- Read a plain list of strings.
194+ stringList :: OrgParser [String]
195+ stringList = try $
196+ char '('
197+ *> sepBy elispString spaces
198+ <* char ')'
199+
200+ -- Read an emacs lisp list specifying a complement set.
201+ complementStringList :: OrgParser [String]
202+ complementStringList = try $
203+ string "(not "
204+ *> sepBy elispString spaces
205+ <* char ')'
206+
207+ elispString :: OrgParser String
208+ elispString = try $
209+ char '"'
210+ *> manyTill alphaNum (char '"')
173211
174212ignoredSetting :: String -> OrgParser ()
175−ignoredSetting s = try (() <$ string s <* char ':' <* many nonspaceChar)
213+ignoredSetting s = try (() <$ string s <* char ':' <* many1 nonspaceChar)
176214
177215--
178216-- Parser
@@ -588,11 +626,27 @@ exampleLine = try $ skipSpaces *> string ": " *> anyLine
588626--
589627
590628-- | A generic drawer which has no special meaning for org-mode.
629+-- Whether or not this drawer is included in the output depends on the drawers
630+-- export setting.
591631genericDrawer :: OrgParser (F Blocks)
592632genericDrawer = try $ do
593− drawerStart
594− manyTill drawerLine (try drawerEnd)
595− return mempty
633+ name <- map toUpper <$> drawerStart
634+ content <- manyTill drawerLine (try drawerEnd)
635+ state <- getState
636+ -- Include drawer if it is explicitly included in or not explicitly excluded
637+ -- from the list of drawers that should be exported. PROPERTIES drawers are
638+ -- never exported.
639+ case (exportDrawers . orgStateExportSettings $ state) of
640+ _ | name == "PROPERTIES" -> return mempty
641+ Left names | name `elem` names -> return mempty
642+ Right names | name `notElem` names -> return mempty
643+ _ -> drawerDiv name <$> parseLines content
644+ where
645+ parseLines :: [String] -> OrgParser (F Blocks)
646+ parseLines = parseFromString parseBlocks . (++ "\n") . unlines
647+
648+ drawerDiv :: String -> F Blocks -> F Blocks
649+ drawerDiv drawerName = fmap $ B.divWith (mempty, [drawerName, "drawer"], mempty)
596650
597651drawerStart :: OrgParser String
598652drawerStart = try $
src/Text/Pandoc/Readers/Org/ParserState.hs+14−1
@@ -39,8 +39,9 @@ module Text.Pandoc.Readers.Org.ParserState
3939 , runF
4040 , returnF
4141 , ExportSettingSetter
42− , exportSubSuperscripts
42+ , ExportSettings (..)
4343 , setExportSubSuperscripts
44+ , setExportDrawers
4445 , modifyExportSettings
4546 ) where
4647
@@ -76,6 +77,10 @@ type OrgLinkFormatters = M.Map String (String -> String)
7677-- These settings can be changed via OPTIONS statements.
7778data ExportSettings = ExportSettings
7879 { exportSubSuperscripts :: Bool -- ^ TeX-like syntax for sub- and superscripts
80+ , exportDrawers :: Either [String] [String]
81+ -- ^ Specify drawer names which should be exported. @Left@ names are
82+ -- explicitly excluded from the resulting output while @Right@ means that
83+ -- only the listed drawer names should be included.
7984 }
8085
8186-- | Org-mode parser state
@@ -155,6 +160,7 @@ defaultOrgParserState = OrgParserState
155160defaultExportSettings :: ExportSettings
156161defaultExportSettings = ExportSettings
157162 { exportSubSuperscripts = True
163+ , exportDrawers = Left ["LOGBOOK"]
158164 }
159165
160166
@@ -163,9 +169,16 @@ defaultExportSettings = ExportSettings
163169--
164170type ExportSettingSetter a = a -> ExportSettings -> ExportSettings
165171
172+-- | Set export options for sub/superscript parsing. The short syntax will
173+-- not be parsed if this is set set to @False@.
166174setExportSubSuperscripts :: ExportSettingSetter Bool
167175setExportSubSuperscripts val es = es { exportSubSuperscripts = val }
168176
177+-- | Set export options for drawers. See the @exportDrawers@ in ADT
178+-- @ExportSettings@ for details.
179+setExportDrawers :: ExportSettingSetter (Either [String] [String])
180+setExportDrawers val es = es { exportDrawers = val }
181+
169182-- | Modify a parser state
170183modifyExportSettings :: ExportSettingSetter a -> a -> OrgParserState -> OrgParserState
171184modifyExportSettings setter val state =
tests/Tests/Readers/Org.hs+24−1
@@ -420,9 +420,10 @@ tests =
420420
421421 , "Drawers can be arbitrary" =:
422422 unlines [ ":FOO:"
423+ , "/bar/"
423424 , ":END:"
424425 ] =?>
425− (mempty::Blocks)
426+ divWith (mempty, ["FOO", "drawer"], mempty) (para $ emph "bar")
426427
427428 , "Anchor reference" =:
428429 unlines [ "<<link-here>> Target."
@@ -475,6 +476,28 @@ tests =
475476 , "a^b"
476477 ] =?>
477478 para "a^b"
479+
480+ , "Export option: directly select drawers to be exported" =:
481+ unlines [ "#+OPTIONS: d:(\"IMPORTANT\")"
482+ , ":IMPORTANT:"
483+ , "23"
484+ , ":END:"
485+ , ":BORING:"
486+ , "very boring"
487+ , ":END:"
488+ ] =?>
489+ divWith (mempty, ["IMPORTANT", "drawer"], mempty) (para "23")
490+
491+ , "Export option: exclude drawers from being exported" =:
492+ unlines [ "#+OPTIONS: d:(not \"BORING\")"
493+ , ":IMPORTANT:"
494+ , "5"
495+ , ":END:"
496+ , ":BORING:"
497+ , "very boring"
498+ , ":END:"
499+ ] =?>
500+ divWith (mempty, ["IMPORTANT", "drawer"], mempty) (para "5")
478501 ]
479502
480503 , testGroup "Basic Blocks" $