Org reader: subject full doc tree to headline transformations

Emacs parses org documents into a tree structure, which is then
post-processed during exporting. The reader is changed to do the same,
turning the document into a single tree of headlines starting at
level 0.

Fixes: #3695
This commit is contained in:
Albert Krewinkel
2017-05-27 15:38:08 +02:00
parent 8ec03cfc87
commit bf93c07267
3 changed files with 53 additions and 8 deletions
+5 -5
View File
@@ -33,7 +33,7 @@ module Text.Pandoc.Readers.Org.Blocks
) where
import Text.Pandoc.Readers.Org.BlockStarts
import Text.Pandoc.Readers.Org.DocumentTree (headline, headlineToBlocks)
import Text.Pandoc.Readers.Org.DocumentTree (documentTree, headlineToBlocks)
import Text.Pandoc.Readers.Org.Inlines
import Text.Pandoc.Readers.Org.Meta (metaExport, metaKey, metaLine)
import Text.Pandoc.Readers.Org.ParserState
@@ -62,11 +62,11 @@ import Data.Monoid ((<>))
-- | Get a list of blocks.
blockList :: PandocMonad m => OrgParser m [Block]
blockList = do
initialBlocks <- blocks
headlines <- sequence <$> manyTill (headline blocks inline 1) eof
headlines <- documentTree blocks inline
st <- getState
headlineBlocks <- fmap mconcat . mapM headlineToBlocks $ runF headlines st
return . B.toList $ (runF initialBlocks st) <> headlineBlocks
headlineBlocks <- headlineToBlocks $ runF headlines st
-- ignore first headline, it's the document's title
return . drop 1 . B.toList $ headlineBlocks
-- | Get the meta information saved in the state.
meta :: Monad m => OrgParser m Meta
+32 -1
View File
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Parsers for org-mode headlines and document subtrees
-}
module Text.Pandoc.Readers.Org.DocumentTree
( headline
( documentTree
, headlineToBlocks
) where
@@ -43,11 +43,42 @@ import Text.Pandoc.Readers.Org.BlockStarts
import Text.Pandoc.Readers.Org.Parsing
import Text.Pandoc.Readers.Org.ParserState
import qualified Data.Map as Map
import qualified Text.Pandoc.Builder as B
--
-- Org headers
--
-- | Parse input as org document tree.
documentTree :: PandocMonad m
=> OrgParser m (F Blocks)
-> OrgParser m (F Inlines)
-> OrgParser m (F Headline)
documentTree blocks inline = do
initialBlocks <- blocks
headlines <- sequence <$> manyTill (headline blocks inline 1) eof
title <- fmap (getTitle . unMeta) . orgStateMeta <$> getState
return $ do
headlines' <- headlines
initialBlocks' <- initialBlocks
title' <- title
return Headline
{ headlineLevel = 0
, headlineTodoMarker = Nothing
, headlineText = B.fromList title'
, headlineTags = mempty
, headlineProperties = mempty
, headlineContents = initialBlocks'
, headlineChildren = headlines'
}
where
getTitle :: Map.Map String MetaValue -> [Inline]
getTitle metamap =
case Map.lookup "title" metamap of
Just (MetaInlines inlns) -> inlns
_ -> []
newtype Tag = Tag { fromTag :: String }
deriving (Show, Eq)
+16 -2
View File
@@ -708,16 +708,30 @@ tests =
, "limit headline depth" =:
unlines [ "#+OPTIONS: H:2"
, "* section"
, "* top-level section"
, "** subsection"
, "*** list item 1"
, "*** list item 2"
] =?>
mconcat [ headerWith ("section", [], []) 1 "section"
mconcat [ headerWith ("top-level-section", [], []) 1 "top-level section"
, headerWith ("subsection", [], []) 2 "subsection"
, orderedList [ para "list item 1", para "list item 2" ]
]
, "turn all headlines into lists" =:
unlines [ "#+OPTIONS: H:0"
, "first block"
, "* top-level section 1"
, "** subsection"
, "* top-level section 2"
] =?>
mconcat [ para "first block"
, orderedList
[ (para "top-level section 1" <>
orderedList [ para "subsection" ])
, para "top-level section 2" ]
]
, "disable author export" =:
unlines [ "#+OPTIONS: author:nil"
, "#+AUTHOR: ShyGuy"