git.iko.soy/typeable/pandoc
on master help sign in
Org reader: refactor comment tree handling

Comment trees were handled after parsing, as pattern matching on lists is easier than matching on sequences. The new method of reading documents as trees allows for more elegant subtree removal.

commit1ebaf6de117d74145a58d63a41a4c69b87aaa771 authorAlbert Krewinkel <albert@zeitkraut.de> dateFri 1 Jul 2016, 21:17 (10 years ago) parent17484ed
2 files changed+21−39
src/Text/Pandoc/Readers/Org.hs+1−38 src/Text/Pandoc/Readers/Org/Blocks.hs+20−1
src/Text/Pandoc/Readers/Org.hs+1−38
@@ -52,41 +52,4 @@ parseOrg :: OrgParser Pandoc
5252parseOrg = do
5353 blocks' <- blockList
5454 meta' <- meta
55− return . Pandoc meta' $ removeUnwantedBlocks blocks'
56− where
57− removeUnwantedBlocks :: [Block] -> [Block]
58− removeUnwantedBlocks = dropCommentTrees . filter (/= Null)
59−
60−-- | Drop COMMENT headers and the document tree below those headers.
61−dropCommentTrees :: [Block] -> [Block]
62−dropCommentTrees [] = []
63−dropCommentTrees (b:bs) =
64− maybe (b:dropCommentTrees bs)
65− (dropCommentTrees . flip dropUntilHeaderAboveLevel bs)
66− (commentHeaderLevel b)
67−
68−-- | Return the level of a header starting a comment or :noexport: tree and
69−-- Nothing otherwise.
70−commentHeaderLevel :: Block -> Maybe Int
71−commentHeaderLevel blk =
72− case blk of
73− (Header level _ ((Str "COMMENT"):_)) -> Just level
74− (Header level _ title) | hasNoExportTag title -> Just level
75− _ -> Nothing
76− where
77− hasNoExportTag :: [Inline] -> Bool
78− hasNoExportTag = any isNoExportTag
79−
80− isNoExportTag :: Inline -> Bool
81− isNoExportTag (Span ("", ["tag"], [("data-tag-name", "noexport")]) []) = True
82− isNoExportTag _ = False
83−
84−-- | Drop blocks until a header on or above the given level is seen
85−dropUntilHeaderAboveLevel :: Int -> [Block] -> [Block]
86−dropUntilHeaderAboveLevel n = dropWhile (not . isHeaderLevelLowerEq n)
87−
88−isHeaderLevelLowerEq :: Int -> Block -> Bool
89−isHeaderLevelLowerEq n blk =
90− case blk of
91− (Header level _ _) -> n >= level
92− _ -> False
55+ return $ Pandoc meta' blocks'
src/Text/Pandoc/Readers/Org/Blocks.hs+20−1
@@ -1,5 +1,6 @@
11{-# LANGUAGE FlexibleContexts #-}
22{-# LANGUAGE RecordWildCards #-}
3+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}
34{-
45Copyright (C) 2014-2016 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
56
@@ -52,6 +53,7 @@ import Data.Char ( isSpace, toLower, toUpper)
5253import Data.List ( foldl', intersperse, isPrefixOf )
5354import qualified Data.Map as M
5455import Data.Maybe ( fromMaybe, isNothing )
56+import qualified Data.Sequence as S
5557import Network.HTTP ( urlEncode )
5658
5759--
@@ -132,7 +134,24 @@ headline lvl = try $ do
132134
133135-- | Convert an Org mode headline (i.e. a document tree) into pandoc's Blocks
134136headlineToBlocks :: Headline -> OrgParser Blocks
135−headlineToBlocks (Headline {..}) = do
137+headlineToBlocks hdln@(Headline {..}) =
138+ case () of
139+ _ | any isNoExportTag headlineTags -> return mempty
140+ _ | isCommentTitle headlineText -> return mempty
141+ _ -> headlineToHeader hdln
142+
143+isNoExportTag :: Tag -> Bool
144+isNoExportTag = (== toTag "noexport")
145+
146+-- | Check if the title starts with COMMENT.
147+-- FIXME: This accesses builder internals not intended for use in situations
148+-- as these. Replace once keyword parsing is supported.
149+isCommentTitle :: Inlines -> Bool
150+isCommentTitle xs = (B.Many . S.take 1 . B.unMany) xs == B.str "COMMENT"
151+isCommentTitle _ = False
152+
153+headlineToHeader :: Headline -> OrgParser Blocks
154+headlineToHeader (Headline {..}) = do
136155 let text = tagTitle headlineText headlineTags
137156 let propAttr = propertiesToAttr headlineProperties
138157 attr <- registerHeader propAttr headlineText