git.iko.soy/typeable/pandoc
on master help sign in
Refactor top-level division selection (#3261)

The "default" option is no longer represented as `Nothing` but via a new type constructor, making the `Maybe` wrapper superfluous. The default behavior of using heuristics can now be enabled explicitly by setting `--top-level-division=default`. API change (`Text.Pandoc.Options`): The `Division` type was renamed to `TopLevelDivision`. The `Section`, `Chapter`, and `Part` constructors were renamed to `TopLevelSection`, `TopLevelChapter`, and `TopLevelPart`, respectively. An additional `TopLevelDefault` constructor was added, which is now also the new default value of the `writerTopLevelDivision` field in `WriterOptions`.

commit1fc07ff4dae5b3673ac2090d0a52f69afc1f078e authorAlbert Krewinkel <albert+github@zeitkraut.de> dateSun 27 Nov 2016, 20:31 (10 years ago) parent08bf8f2
9 files changed+111−64
MANUAL.txt+8−7 pandoc.hs+9−6 src/Text/Pandoc/Options.hs+9−7 src/Text/Pandoc/Writers/ConTeXt.hs+9−8 src/Text/Pandoc/Writers/Docbook.hs+7−7 src/Text/Pandoc/Writers/LaTeX.hs+12−9 src/Text/Pandoc/Writers/TEI.hs+5−5 tests/Tests/Writers/Docbook.hs+23−5 tests/Tests/Writers/LaTeX.hs+29−10
MANUAL.txt+8−7
@@ -684,17 +684,18 @@ Options affecting specific writers
684684
685685: Deprecated synonym for `--top-level-division=chapter`.
686686
687−`--top-level-division=[section|chapter|part]`
687+`--top-level-division=[default|section|chapter|part]`
688688
689689: Treat top-level headers as the given division type in LaTeX, ConTeXt,
690690 DocBook, and TEI output. The hierarchy order is part, chapter, then section;
691691 all headers are shifted such that the top-level header becomes the specified
692− type. The default is `section`. When the LaTeX document class is set to
693− `report`, `book`, or `memoir` (unless the `article` option is specified),
694− `chapter` is implied as the setting for this option. If `beamer` is the
695− output format, specifying either `chapter` or `part` will cause top-level
696− headers to become `\part{..}`, while second-level headers remain as their
697− default type.
692+ type. The default behavior is to determine the best division type via
693+ heuristics: unless other conditions apply, `section` is chosen. When the
694+ LaTeX document class is set to `report`, `book`, or `memoir` (unless the
695+ `article` option is specified), `chapter` is implied as the setting for this
696+ option. If `beamer` is the output format, specifying either `chapter` or
697+ `part` will cause top-level headers to become `\part{..}`, while
698+ second-level headers remain as their default type.
698699
699700`-N`, `--number-sections`
700701
pandoc.hs+9−6
@@ -181,7 +181,7 @@ data Opt = Opt
181181 , optHtmlQTags :: Bool -- ^ Use <q> tags in HTML
182182 , optHighlight :: Bool -- ^ Highlight source code
183183 , optHighlightStyle :: Style -- ^ Style to use for highlighted code
184− , optTopLevelDivision :: Maybe Division -- ^ Type of the top-level divisions
184+ , optTopLevelDivision :: TopLevelDivision -- ^ Type of the top-level divisions
185185 , optHTMLMathMethod :: HTMLMathMethod -- ^ Method to print HTML math
186186 , optReferenceODT :: Maybe FilePath -- ^ Path of reference.odt
187187 , optReferenceDocx :: Maybe FilePath -- ^ Path of reference.docx
@@ -246,7 +246,7 @@ defaultOpts = Opt
246246 , optHtmlQTags = False
247247 , optHighlight = True
248248 , optHighlightStyle = pygments
249− , optTopLevelDivision = Nothing
249+ , optTopLevelDivision = TopLevelDefault
250250 , optHTMLMathMethod = PlainMath
251251 , optReferenceODT = Nothing
252252 , optReferenceDocx = Nothing
@@ -598,14 +598,17 @@ options =
598598 (NoArg
599599 (\opt -> do warn $ "--chapters is deprecated. " ++
600600 "Use --top-level-division=chapter instead."
601− return opt { optTopLevelDivision = Just Chapter }))
601+ return opt { optTopLevelDivision = TopLevelChapter }))
602602 "" -- "Use chapter for top-level sections in LaTeX, DocBook"
603603
604604 , Option "" ["top-level-division"]
605605 (ReqArg
606− (\arg opt -> case safeRead (uppercaseFirstLetter arg) of
607− Just dvsn -> return opt { optTopLevelDivision = Just dvsn }
608− _ -> err 76 "Top-level division must be section, chapter, or part")
606+ (\arg opt -> do
607+ let tldName = "TopLevel" ++ uppercaseFirstLetter arg
608+ case safeRead tldName of
609+ Just tlDiv -> return opt { optTopLevelDivision = tlDiv }
610+ _ -> err 76 ("Top-level division must be " ++
611+ "section, chapter, part, or default"))
609612 "[section|chapter|part]")
610613 "" -- "Use top-level division type in LaTeX, ConTeXt, DocBook"
611614
src/Text/Pandoc/Options.hs+9−7
@@ -43,7 +43,7 @@ module Text.Pandoc.Options ( Extension(..)
4343 , HTMLSlideVariant (..)
4444 , EPUBVersion (..)
4545 , WrapOption (..)
46− , Division (..)
46+ , TopLevelDivision (..)
4747 , WriterOptions (..)
4848 , TrackChanges (..)
4949 , ReferenceLocation (..)
@@ -341,10 +341,12 @@ data WrapOption = WrapAuto -- ^ Automatically wrap to width
341341 deriving (Show, Read, Eq, Data, Typeable, Generic)
342342
343343-- | Options defining the type of top-level headers.
344−data Division = Part -- ^ Top-level headers become parts
345− | Chapter -- ^ Top-level headers become chapters
346− | Section -- ^ Top-level headers become sections
347− deriving (Show, Read, Eq, Ord, Data, Typeable, Generic)
344+data TopLevelDivision = TopLevelPart -- ^ Top-level headers become parts
345+ | TopLevelChapter -- ^ Top-level headers become chapters
346+ | TopLevelSection -- ^ Top-level headers become sections
347+ | TopLevelDefault -- ^ Top-level type is determined via
348+ -- heuristics
349+ deriving (Show, Read, Eq, Data, Typeable, Generic)
348350
349351-- | Locations for footnotes and references in markdown output
350352data ReferenceLocation = EndOfBlock -- ^ End of block
@@ -382,7 +384,7 @@ data WriterOptions = WriterOptions
382384 , writerHtmlQTags :: Bool -- ^ Use @<q>@ tags for quotes in HTML
383385 , writerBeamer :: Bool -- ^ Produce beamer LaTeX slide show
384386 , writerSlideLevel :: Maybe Int -- ^ Force header level of slides
385− , writerTopLevelDivision :: Maybe Division -- ^ Type of top-level divisions
387+ , writerTopLevelDivision :: TopLevelDivision -- ^ Type of top-level divisions
386388 , writerListings :: Bool -- ^ Use listings package for code
387389 , writerHighlight :: Bool -- ^ Highlight source code
388390 , writerHighlightStyle :: Style -- ^ Style to use for highlighting
@@ -430,7 +432,7 @@ instance Default WriterOptions where
430432 , writerHtmlQTags = False
431433 , writerBeamer = False
432434 , writerSlideLevel = Nothing
433− , writerTopLevelDivision = Nothing
435+ , writerTopLevelDivision = TopLevelDefault
434436 , writerListings = False
435437 , writerHighlight = False
436438 , writerHighlightStyle = pygments
src/Text/Pandoc/Writers/ConTeXt.hs+9−8
@@ -37,7 +37,7 @@ import Text.Pandoc.Walk (query)
3737import Text.Printf ( printf )
3838import Data.List ( intercalate, intersperse )
3939import Data.Char ( ord )
40−import Data.Maybe ( catMaybes, fromMaybe )
40+import Data.Maybe ( catMaybes )
4141import Control.Monad.State
4242import Text.Pandoc.Pretty
4343import Text.Pandoc.ImageSize
@@ -85,9 +85,9 @@ pandocToConTeXt options (Pandoc meta blocks) = do
8585 $ defField "placelist" (intercalate ("," :: String) $
8686 take (writerTOCDepth options +
8787 case writerTopLevelDivision options of
88− Just Part -> 0
89− Just Chapter -> 0
90− _ -> 1)
88+ TopLevelPart -> 0
89+ TopLevelChapter -> 0
90+ _ -> 1)
9191 ["chapter","section","subsection","subsubsection",
9292 "subsubsubsection","subsubsubsubsection"])
9393 $ defField "body" main
@@ -423,10 +423,11 @@ sectionHeader (ident,classes,_) hdrLevel lst = do
423423 contents <- inlineListToConTeXt lst
424424 st <- get
425425 let opts = stOptions st
426− let level' = case fromMaybe Section (writerTopLevelDivision opts) of
427− Part -> hdrLevel - 2
428− Chapter -> hdrLevel - 1
429− Section -> hdrLevel
426+ let level' = case writerTopLevelDivision opts of
427+ TopLevelPart -> hdrLevel - 2
428+ TopLevelChapter -> hdrLevel - 1
429+ TopLevelSection -> hdrLevel
430+ TopLevelDefault -> hdrLevel
430431 let ident' = toLabel ident
431432 let (section, chapter) = if "unnumbered" `elem` classes
432433 then (text "subject", text "title")
src/Text/Pandoc/Writers/Docbook.hs+7−7
@@ -39,7 +39,6 @@ import Text.Pandoc.Templates (renderTemplate')
3939import Text.Pandoc.Readers.TeXMath
4040import Data.List ( stripPrefix, isPrefixOf, intercalate, isSuffixOf )
4141import Data.Char ( toLower )
42−import Data.Maybe ( fromMaybe, isNothing )
4342import Data.Monoid ( Any(..) )
4443import Text.Pandoc.Highlighting ( languages, languagesByExtension )
4544import Text.Pandoc.Pretty
@@ -82,14 +81,15 @@ writeDocbook opts (Pandoc meta blocks) =
8281 else Nothing
8382 render' = render colwidth
8483 opts' = if ("/book>" `isSuffixOf` (trimr $ writerTemplate opts) &&
85− isNothing (writerTopLevelDivision opts))
86− then opts{ writerTopLevelDivision = Just Chapter }
84+ TopLevelDefault == writerTopLevelDivision opts)
85+ then opts{ writerTopLevelDivision = TopLevelChapter }
8786 else opts
8887 -- The numbering here follows LaTeX's internal numbering
89− startLvl = case fromMaybe Section (writerTopLevelDivision opts') of
90− Part -> -1
91− Chapter -> 0
92− Section -> 1
88+ startLvl = case writerTopLevelDivision opts' of
89+ TopLevelPart -> -1
90+ TopLevelChapter -> 0
91+ TopLevelSection -> 1
92+ TopLevelDefault -> 1
9393 auths' = map (authorToDocbook opts) $ docAuthors meta
9494 meta' = B.setMeta "author" auths' meta
9595 Just metadata = metaToJSON opts
src/Text/Pandoc/Writers/LaTeX.hs+12−9
@@ -89,9 +89,9 @@ writeLaTeX options document =
8989 stUrl = False, stGraphics = False,
9090 stLHS = False,
9191 stBook = (case writerTopLevelDivision options of
92− Just Part -> True
93− Just Chapter -> True
94− _ -> False),
92+ TopLevelPart -> True
93+ TopLevelChapter -> True
94+ _ -> False),
9595 stCsquotes = False, stHighlighting = False,
9696 stIncremental = writerIncremental options,
9797 stInternalLinks = [], stUsesEuro = False }
@@ -763,15 +763,18 @@ sectionHeader unnumbered ident level lst = do
763763 <> braces (text plain))
764764 book <- gets stBook
765765 opts <- gets stOptions
766− let topLevelDivision = fromMaybe (if book then Chapter else Section)
767− (writerTopLevelDivision opts)
768− let level' = if writerBeamer opts && topLevelDivision < Section
766+ let topLevelDivision = if book && writerTopLevelDivision opts == TopLevelDefault
767+ then TopLevelChapter
768+ else writerTopLevelDivision opts
769+ let level' = if writerBeamer opts &&
770+ topLevelDivision `elem` [TopLevelPart, TopLevelChapter]
769771 -- beamer has parts but no chapters
770772 then if level == 1 then -1 else level - 1
771773 else case topLevelDivision of
772− Part -> level - 2
773− Chapter -> level - 1
774− Section -> level
774+ TopLevelPart -> level - 2
775+ TopLevelChapter -> level - 1
776+ TopLevelSection -> level
777+ TopLevelDefault -> level
775778 let sectionType = case level' of
776779 -1 -> "part"
777780 0 -> "chapter"
src/Text/Pandoc/Writers/TEI.hs+5−5
@@ -36,7 +36,6 @@ import Text.Pandoc.Writers.Shared
3636import Text.Pandoc.Options
3737import Text.Pandoc.Templates (renderTemplate')
3838import Data.List ( stripPrefix, isPrefixOf )
39−import Data.Maybe ( fromMaybe )
4039import Data.Char ( toLower )
4140import Text.Pandoc.Highlighting ( languages, languagesByExtension )
4241import Text.Pandoc.Pretty
@@ -61,10 +60,11 @@ writeTEI opts (Pandoc meta blocks) =
6160 then Just $ writerColumns opts
6261 else Nothing
6362 render' = render colwidth
64− startLvl = case fromMaybe Section (writerTopLevelDivision opts) of
65− Part -> -1
66− Chapter -> 0
67− Section -> 1
63+ startLvl = case writerTopLevelDivision opts of
64+ TopLevelPart -> -1
65+ TopLevelChapter -> 0
66+ TopLevelSection -> 1
67+ TopLevelDefault -> 1
6868 auths' = map (authorToTEI opts) $ docAuthors meta
6969 meta' = B.setMeta "author" auths' meta
7070 Just metadata = metaToJSON opts
tests/Tests/Writers/Docbook.hs+23−5
@@ -236,11 +236,13 @@ tests = [ testGroup "line blocks"
236236 <> header 2 (text "header2")
237237 <> header 3 (text "header3")
238238
239− docbookTopLevelDiv :: (ToPandoc a) => Division -> a -> String
239+ docbookTopLevelDiv :: (ToPandoc a)
240+ => TopLevelDivision -> a -> String
240241 docbookTopLevelDiv division =
241− docbookWithOpts def{ writerTopLevelDivision = Just division }
242+ docbookWithOpts def{ writerTopLevelDivision = division }
242243 in
243− [ test (docbookTopLevelDiv Section) "sections as top-level" $ headers =?>
244+ [ test (docbookTopLevelDiv TopLevelSection) "sections as top-level" $
245+ headers =?>
244246 unlines [ "<sect1>"
245247 , " <title>header1</title>"
246248 , " <sect2>"
@@ -253,7 +255,8 @@ tests = [ testGroup "line blocks"
253255 , " </sect2>"
254256 , "</sect1>"
255257 ]
256− , test (docbookTopLevelDiv Chapter) "chapters as top-level" $ headers =?>
258+ , test (docbookTopLevelDiv TopLevelChapter) "chapters as top-level" $
259+ headers =?>
257260 unlines [ "<chapter>"
258261 , " <title>header1</title>"
259262 , " <sect1>"
@@ -266,7 +269,8 @@ tests = [ testGroup "line blocks"
266269 , " </sect1>"
267270 , "</chapter>"
268271 ]
269− , test (docbookTopLevelDiv Part) "parts as top-level" $ headers =?>
272+ , test (docbookTopLevelDiv TopLevelPart) "parts as top-level" $
273+ headers =?>
270274 unlines [ "<part>"
271275 , " <title>header1</title>"
272276 , " <chapter>"
@@ -279,6 +283,20 @@ tests = [ testGroup "line blocks"
279283 , " </chapter>"
280284 , "</part>"
281285 ]
286+ , test (docbookTopLevelDiv TopLevelDefault) "default top-level" $
287+ headers =?>
288+ unlines [ "<sect1>"
289+ , " <title>header1</title>"
290+ , " <sect2>"
291+ , " <title>header2</title>"
292+ , " <sect3>"
293+ , " <title>header3</title>"
294+ , " <para>"
295+ , " </para>"
296+ , " </sect3>"
297+ , " </sect2>"
298+ , "</sect1>"
299+ ]
282300 ]
283301 ]
284302 ]
tests/Tests/Writers/LaTeX.hs+29−10
@@ -88,45 +88,64 @@ tests = [ testGroup "code blocks"
8888 <> header 2 (text "header2")
8989 <> header 3 (text "header3")
9090
91− latexTopLevelDiv :: (ToPandoc a) => Division -> a -> String
91+ latexTopLevelDiv :: (ToPandoc a) => TopLevelDivision -> a -> String
9292 latexTopLevelDiv division =
93− latexWithOpts def{ writerTopLevelDivision = Just division }
93+ latexWithOpts def{ writerTopLevelDivision = division }
9494
95− beamerTopLevelDiv :: (ToPandoc a) => Division -> a -> String
95+ beamerTopLevelDiv :: (ToPandoc a)
96+ => TopLevelDivision -> a -> String
9697 beamerTopLevelDiv division =
97− latexWithOpts def { writerTopLevelDivision = Just division
98+ latexWithOpts def { writerTopLevelDivision = division
9899 , writerBeamer = True }
99100 in
100− [ test (latexTopLevelDiv Section) "sections as top-level" $ headers =?>
101+ [ test (latexTopLevelDiv TopLevelSection)
102+ "sections as top-level" $ headers =?>
101103 unlines [ "\\section{header1}\n"
102104 , "\\subsection{header2}\n"
103105 , "\\subsubsection{header3}"
104106 ]
105− , test (latexTopLevelDiv Chapter) "chapters as top-level" $ headers =?>
107+ , test (latexTopLevelDiv TopLevelChapter)
108+ "chapters as top-level" $ headers =?>
106109 unlines [ "\\chapter{header1}\n"
107110 , "\\section{header2}\n"
108111 , "\\subsection{header3}"
109112 ]
110− , test (latexTopLevelDiv Part) "parts as top-level" $ headers =?>
113+ , test (latexTopLevelDiv TopLevelPart)
114+ "parts as top-level" $ headers =?>
111115 unlines [ "\\part{header1}\n"
112116 , "\\chapter{header2}\n"
113117 , "\\section{header3}"
114118 ]
115− , test (beamerTopLevelDiv Section) "sections as top-level in beamer" $ headers =?>
119+ , test (latexTopLevelDiv TopLevelDefault)
120+ "default top-level" $ headers =?>
116121 unlines [ "\\section{header1}\n"
117122 , "\\subsection{header2}\n"
118123 , "\\subsubsection{header3}"
119124 ]
120− , test (beamerTopLevelDiv Chapter) "chapters are as part in beamer" $ headers =?>
125+ , test (beamerTopLevelDiv TopLevelSection)
126+ "sections as top-level in beamer" $ headers =?>
127+ unlines [ "\\section{header1}\n"
128+ , "\\subsection{header2}\n"
129+ , "\\subsubsection{header3}"
130+ ]
131+ , test (beamerTopLevelDiv TopLevelChapter)
132+ "chapters are as part in beamer" $ headers =?>
121133 unlines [ "\\part{header1}\n"
122134 , "\\section{header2}\n"
123135 , "\\subsection{header3}"
124136 ]
125− , test (beamerTopLevelDiv Part) "parts as top-level in beamer" $ headers =?>
137+ , test (beamerTopLevelDiv TopLevelPart)
138+ "parts as top-level in beamer" $ headers =?>
126139 unlines [ "\\part{header1}\n"
127140 , "\\section{header2}\n"
128141 , "\\subsection{header3}"
129142 ]
143+ , test (beamerTopLevelDiv TopLevelDefault)
144+ "default top-level in beamer" $ headers =?>
145+ unlines [ "\\section{header1}\n"
146+ , "\\subsection{header2}\n"
147+ , "\\subsubsection{header3}"
148+ ]
130149 ]
131150 ]
132151 ]