git.iko.soy/typeable/pandoc
on master help sign in
Org reader: support headline levels export setting

The depths of headlines can be modified using the `H` option. Deeper headlines will be converted to lists.

commit5ffa4abf727779cee317aab81c143e3e2d3cb7d6 authorAlbert Krewinkel <albert@zeitkraut.de> dateSat 2 Jul 2016, 10:52 (10 years ago) parentc1f6bd2
4 files changed+52−8
src/Text/Pandoc/Readers/Org/Blocks.hs+27−6 src/Text/Pandoc/Readers/Org/ExportSettings.hs+10−2 src/Text/Pandoc/Readers/Org/ParserState.hs+3 tests/Tests/Readers/Org.hs+12
src/Text/Pandoc/Readers/Org/Blocks.hs+27−6
@@ -111,7 +111,7 @@ headline lvl = try $ do
111111 newline
112112 properties <- option mempty propertiesDrawer
113113 contents <- blocks
114− children <- many (headline (lvl + 1))
114+ children <- many (headline (level + 1))
115115 return $ do
116116 title' <- title
117117 contents' <- contents
@@ -135,12 +135,14 @@ headline lvl = try $ do
135135
136136-- | Convert an Org mode headline (i.e. a document tree) into pandoc's Blocks
137137headlineToBlocks :: Headline -> OrgParser Blocks
138−headlineToBlocks hdln@(Headline {..}) =
138+headlineToBlocks hdln@(Headline {..}) = do
139+ maxHeadlineLevels <- getExportSetting exportHeadlineLevels
139140 case () of
140− _ | any isNoExportTag headlineTags -> return mempty
141− _ | any isArchiveTag headlineTags -> archivedHeadlineToBlocks hdln
142− _ | isCommentTitle headlineText -> return mempty
143− _ -> headlineToHeaderWithContents hdln
141+ _ | any isNoExportTag headlineTags -> return mempty
142+ _ | any isArchiveTag headlineTags -> archivedHeadlineToBlocks hdln
143+ _ | isCommentTitle headlineText -> return mempty
144+ _ | headlineLevel >= maxHeadlineLevels -> headlineToHeaderWithList hdln
145+ _ -> headlineToHeaderWithContents hdln
144146
145147isNoExportTag :: Tag -> Bool
146148isNoExportTag = (== toTag "noexport")
@@ -163,6 +165,25 @@ archivedHeadlineToBlocks hdln = do
163165 ArchivedTreesExport -> headlineToHeaderWithContents hdln
164166 ArchivedTreesHeadlineOnly -> headlineToHeader hdln
165167
168+headlineToHeaderWithList :: Headline -> OrgParser Blocks
169+headlineToHeaderWithList hdln@(Headline {..}) = do
170+ maxHeadlineLevels <- getExportSetting exportHeadlineLevels
171+ header <- headlineToHeader hdln
172+ listElements <- sequence (map headlineToBlocks headlineChildren)
173+ let listBlock = if null listElements
174+ then mempty
175+ else B.orderedList listElements
176+ let headerText = if maxHeadlineLevels == headlineLevel
177+ then header
178+ else flattenHeader header
179+ return $ headerText <> headlineContents <> listBlock
180+ where
181+ flattenHeader :: Blocks -> Blocks
182+ flattenHeader blks =
183+ case B.toList blks of
184+ (Header _ _ inlns:_) -> B.para (B.fromList inlns)
185+ _ -> mempty
186+
166187headlineToHeaderWithContents :: Headline -> OrgParser Blocks
167188headlineToHeaderWithContents hdln@(Headline {..}) = do
168189 header <- headlineToHeader hdln
src/Text/Pandoc/Readers/Org/ExportSettings.hs+10−2
@@ -32,8 +32,9 @@ module Text.Pandoc.Readers.Org.ExportSettings
3232import Text.Pandoc.Readers.Org.ParserState
3333import Text.Pandoc.Readers.Org.Parsing
3434
35−import Control.Monad ( void )
35+import Control.Monad ( mzero, void )
3636import Data.Char ( toLower )
37+import Data.Maybe ( listToMaybe )
3738
3839-- | Read and handle space separated org-mode export settings.
3940exportSettings :: OrgParser ()
@@ -61,7 +62,7 @@ exportSetting = choice
6162 , ignoredSetting "e"
6263 , ignoredSetting "email"
6364 , ignoredSetting "f"
64− , ignoredSetting "H"
65+ , integerSetting "H" (\val es -> es { exportHeadlineLevels = val })
6566 , ignoredSetting "inline"
6667 , ignoredSetting "num"
6768 , ignoredSetting "p"
@@ -94,6 +95,13 @@ genericExportSetting optionParser settingIdentifier setter = try $ do
9495booleanSetting :: String -> ExportSettingSetter Bool -> OrgParser ()
9596booleanSetting = genericExportSetting elispBoolean
9697
98+-- | An integer-valued option.
99+integerSetting :: String -> ExportSettingSetter Int -> OrgParser ()
100+integerSetting = genericExportSetting parseInt
101+ where
102+ parseInt = try $
103+ many1 digit >>= maybe mzero (return . fst) . listToMaybe . reads
104+
97105-- | Either the string "headline" or an elisp boolean and treated as an
98106-- @ArchivedTreesOption@.
99107archivedTreeSetting :: String
src/Text/Pandoc/Readers/Org/ParserState.hs+3
@@ -158,6 +158,8 @@ data ExportSettings = ExportSettings
158158 -- explicitly excluded from the resulting output while @Right@ means that
159159 -- only the listed drawer names should be included.
160160 , exportEmphasizedText :: Bool -- ^ Parse emphasized text
161+ , exportHeadlineLevels :: Int
162+ -- ^ Maximum depth of headlines, deeper headlines are convert to list
161163 , exportSmartQuotes :: Bool -- ^ Parse quotes smartly
162164 , exportSpecialStrings :: Bool -- ^ Parse ellipses and dashes smartly
163165 , exportSubSuperscripts :: Bool -- ^ TeX-like syntax for sub- and superscripts
@@ -171,6 +173,7 @@ defaultExportSettings = ExportSettings
171173 { exportArchivedTrees = ArchivedTreesHeadlineOnly
172174 , exportDrawers = Left ["LOGBOOK"]
173175 , exportEmphasizedText = True
176+ , exportHeadlineLevels = 3
174177 , exportSmartQuotes = True
175178 , exportSpecialStrings = True
176179 , exportSubSuperscripts = True
tests/Tests/Readers/Org.hs+12
@@ -611,6 +611,18 @@ tests =
611611 ] =?>
612612 let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
613613 in headerWith ("old", [], mempty) 1 ("old" <> tagSpan "ARCHIVE")
614+
615+ , "Export option: limit headline depth" =:
616+ unlines [ "#+OPTIONS: H:2"
617+ , "* section"
618+ , "** subsection"
619+ , "*** list item 1"
620+ , "*** list item 2"
621+ ] =?>
622+ mconcat [ headerWith ("section", [], []) 1 "section"
623+ , headerWith ("subsection", [], []) 2 "subsection"
624+ , orderedList [ para "list item 1", para "list item 2" ]
625+ ]
614626 ]
615627
616628 , testGroup "Basic Blocks" $