git.iko.soy/typeable/pandoc
on master help sign in
Org reader: support archived trees export options

Handling of archived trees can be modified using the `arch` option. Archived trees are either dropped, exported completely, or collapsed to include just the header when the `arch` option is nil, non-nil, or `headline`, respectively.

commitc4cf6d237f1017d36eeafad162570754506a6093 authorAlbert Krewinkel <albert@zeitkraut.de> dateFri 1 Jul 2016, 22:44 (10 years ago) parent1ebaf6d
3 files changed+86−8
src/Text/Pandoc/Readers/Org/Blocks.hs+43−6 src/Text/Pandoc/Readers/Org/ParserState.hs+19−2 tests/Tests/Readers/Org.hs+24
src/Text/Pandoc/Readers/Org/Blocks.hs+43−6
@@ -137,27 +137,43 @@ headlineToBlocks :: Headline -> OrgParser Blocks
137137headlineToBlocks hdln@(Headline {..}) =
138138 case () of
139139 _ | any isNoExportTag headlineTags -> return mempty
140+ _ | any isArchiveTag headlineTags -> archivedHeadlineToBlocks hdln
140141 _ | isCommentTitle headlineText -> return mempty
141− _ -> headlineToHeader hdln
142+ _ -> headlineToHeaderWithContents hdln
142143
143144isNoExportTag :: Tag -> Bool
144145isNoExportTag = (== toTag "noexport")
145146
147+isArchiveTag :: Tag -> Bool
148+isArchiveTag = (== toTag "ARCHIVE")
149+
146150-- | Check if the title starts with COMMENT.
147151-- FIXME: This accesses builder internals not intended for use in situations
148−-- as these. Replace once keyword parsing is supported.
152+-- like these. Replace once keyword parsing is supported.
149153isCommentTitle :: Inlines -> Bool
150154isCommentTitle xs = (B.Many . S.take 1 . B.unMany) xs == B.str "COMMENT"
151155isCommentTitle _ = False
152156
157+archivedHeadlineToBlocks :: Headline -> OrgParser Blocks
158+archivedHeadlineToBlocks hdln = do
159+ archivedTreesOption <- getExportSetting exportArchivedTrees
160+ case archivedTreesOption of
161+ ArchivedTreesNoExport -> return mempty
162+ ArchivedTreesExport -> headlineToHeaderWithContents hdln
163+ ArchivedTreesHeadlineOnly -> headlineToHeader hdln
164+
165+headlineToHeaderWithContents :: Headline -> OrgParser Blocks
166+headlineToHeaderWithContents hdln@(Headline {..}) = do
167+ header <- headlineToHeader hdln
168+ childrenBlocks <- mconcat <$> sequence (map headlineToBlocks headlineChildren)
169+ return $ header <> headlineContents <> childrenBlocks
170+
153171headlineToHeader :: Headline -> OrgParser Blocks
154172headlineToHeader (Headline {..}) = do
155173 let text = tagTitle headlineText headlineTags
156174 let propAttr = propertiesToAttr headlineProperties
157175 attr <- registerHeader propAttr headlineText
158− let header = B.headerWith attr headlineLevel text
159− childrenBlocks <- mconcat <$> sequence (map headlineToBlocks headlineChildren)
160− return $ header <> headlineContents <> childrenBlocks
176+ return $ B.headerWith attr headlineLevel text
161177
162178propertiesToAttr :: Properties -> Attr
163179propertiesToAttr properties =
@@ -629,7 +645,7 @@ exportSetting = choice
629645 , ignoredSetting ":"
630646 , ignoredSetting "<"
631647 , ignoredSetting "\\n"
632− , ignoredSetting "arch"
648+ , archivedTreeSetting "arch" setExportArchivedTrees
633649 , ignoredSetting "author"
634650 , ignoredSetting "c"
635651 , ignoredSetting "creator"
@@ -673,6 +689,27 @@ elispBoolean = try $ do
673689 "()" -> False
674690 _ -> True
675691
692+archivedTreeSetting :: String
693+ -> ExportSettingSetter ArchivedTreesOption
694+ -> OrgParser ()
695+archivedTreeSetting settingIdentifier setter = try $ do
696+ string settingIdentifier
697+ char ':'
698+ value <- archivedTreesHeadlineSetting <|> archivedTreesBoolean
699+ updateState $ modifyExportSettings setter value
700+ where
701+ archivedTreesHeadlineSetting = try $ do
702+ string "headline"
703+ lookAhead (newline <|> spaceChar)
704+ return ArchivedTreesHeadlineOnly
705+
706+ archivedTreesBoolean = try $ do
707+ exportBool <- elispBoolean
708+ return $
709+ if exportBool
710+ then ArchivedTreesExport
711+ else ArchivedTreesNoExport
712+
676713-- | A list or a complement list (i.e. a list starting with `not`).
677714complementableListSetting :: String
678715 -> ExportSettingSetter (Either [String] [String])
src/Text/Pandoc/Readers/Org/ParserState.hs+19−2
@@ -42,6 +42,8 @@ module Text.Pandoc.Readers.Org.ParserState
4242 , returnF
4343 , ExportSettingSetter
4444 , ExportSettings (..)
45+ , ArchivedTreesOption (..)
46+ , setExportArchivedTrees
4547 , setExportDrawers
4648 , setExportEmphasizedText
4749 , setExportSmartQuotes
@@ -78,10 +80,17 @@ type OrgNoteTable = [OrgNoteRecord]
7880-- link-type, the corresponding function transforms the given link string.
7981type OrgLinkFormatters = M.Map String (String -> String)
8082
83+-- | Options for the way archived trees are handled.
84+data ArchivedTreesOption =
85+ ArchivedTreesExport -- ^ Export the complete tree
86+ | ArchivedTreesNoExport -- ^ Exclude archived trees from exporting
87+ | ArchivedTreesHeadlineOnly -- ^ Export only the headline, discard the contents
88+
8189-- | Export settings <http://orgmode.org/manual/Export-settings.html>
8290-- These settings can be changed via OPTIONS statements.
8391data ExportSettings = ExportSettings
84− { exportDrawers :: Either [String] [String]
92+ { exportArchivedTrees :: ArchivedTreesOption -- ^ How to treat archived trees
93+ , exportDrawers :: Either [String] [String]
8594 -- ^ Specify drawer names which should be exported. @Left@ names are
8695 -- explicitly excluded from the resulting output while @Right@ means that
8796 -- only the listed drawer names should be included.
@@ -159,7 +168,8 @@ defaultOrgParserState = OrgParserState
159168
160169defaultExportSettings :: ExportSettings
161170defaultExportSettings = ExportSettings
162− { exportDrawers = Left ["LOGBOOK"]
171+ { exportArchivedTrees = ArchivedTreesHeadlineOnly
172+ , exportDrawers = Left ["LOGBOOK"]
163173 , exportEmphasizedText = True
164174 , exportSmartQuotes = True
165175 , exportSpecialStrings = True
@@ -174,8 +184,15 @@ optionsToParserState opts =
174184--
175185-- Setter for exporting options
176186--
187+
188+-- This whole section could be scraped if we were using lenses.
189+
177190type ExportSettingSetter a = a -> ExportSettings -> ExportSettings
178191
192+-- | Set export options for archived trees.
193+setExportArchivedTrees :: ExportSettingSetter ArchivedTreesOption
194+setExportArchivedTrees val es = es { exportArchivedTrees = val }
195+
179196-- | Set export options for drawers. See the @exportDrawers@ in ADT
180197-- @ExportSettings@ for details.
181198setExportDrawers :: ExportSettingSetter (Either [String] [String])
tests/Tests/Readers/Org.hs+24
@@ -587,6 +587,30 @@ tests =
587587 , ":END:"
588588 ] =?>
589589 divWith (mempty, ["IMPORTANT", "drawer"], mempty) (para "5")
590+
591+ , "Export option: don't include archive trees" =:
592+ unlines [ "#+OPTIONS: arch:nil"
593+ , "* old :ARCHIVE:"
594+ ] =?>
595+ (mempty ::Blocks)
596+
597+ , "Export option: include complete archive trees" =:
598+ unlines [ "#+OPTIONS: arch:t"
599+ , "* old :ARCHIVE:"
600+ , " boring"
601+ ] =?>
602+ let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
603+ in mconcat [ headerWith ("old", [], mempty) 1 ("old" <> tagSpan "ARCHIVE")
604+ , para "boring"
605+ ]
606+
607+ , "Export option: include archive tree header only" =:
608+ unlines [ "#+OPTIONS: arch:headline"
609+ , "* old :ARCHIVE:"
610+ , " boring"
611+ ] =?>
612+ let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
613+ in headerWith ("old", [], mempty) 1 ("old" <> tagSpan "ARCHIVE")
590614 ]
591615
592616 , testGroup "Basic Blocks" $