aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANUAL.txt19
-rw-r--r--src/Text/Pandoc/App.hs3
-rw-r--r--src/Text/Pandoc/App/CommandLineOptions.hs17
-rw-r--r--src/Text/Pandoc/App/Opt.hs2
-rw-r--r--src/Text/Pandoc/Shared.hs21
-rw-r--r--test/command/shift-heading-level-by.md33
6 files changed, 88 insertions, 7 deletions
diff --git a/MANUAL.txt b/MANUAL.txt
index f337e0808..28030ae46 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -479,9 +479,26 @@ General options {.options}
Reader options {.options}
--------------
+`--shift-heading-level-by=`*NUMBER*
+
+ Shift heading levels by a positive or negative integer.
+ For example, with `--shift-heading-level-by=-1`, level 2
+ headings become level 1 headings, and level 3 headings
+ become level 2 headings. Headings cannot have a level
+ less than 1, so a heading that would be shifted below level 1
+ becomes a regular paragraph. Exception: with a shift of -1,
+ a level-1 heading at the beginning of the document
+ replaces the metadata title. Conversely, with a shift
+ of +1, a nonempty metadata title becomes a level-1 heading at
+ the beginning of the document. `--shift-heading-level-by=-1`
+ is a good choice when converting HTML or Markdown documents that
+ use an initial level-1 heading for the document title and
+ level-2+ headings for sections.
+
`--base-header-level=`*NUMBER*
-: Specify the base level for headings (defaults to 1).
+: *Deprecated. Use `--shift-heading-level-by` instead.*
+ Specify the base level for headings (defaults to 1).
`--strip-empty-paragraphs`
diff --git a/src/Text/Pandoc/App.hs b/src/Text/Pandoc/App.hs
index 49b20f9dc..12f5de537 100644
--- a/src/Text/Pandoc/App.hs
+++ b/src/Text/Pandoc/App.hs
@@ -241,6 +241,9 @@ convertWithOpts opts = do
let transforms = (case optBaseHeaderLevel opts of
x | x > 1 -> (headerShift (x - 1) :)
| otherwise -> id) .
+ (case optShiftHeadingLevel opts of
+ 0 -> id
+ x -> (headerShift x :)) .
(if optStripEmptyParagraphs opts
then (stripEmptyParagraphs :)
else id) .
diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs
index ae12ba42c..cffe69eca 100644
--- a/src/Text/Pandoc/App/CommandLineOptions.hs
+++ b/src/Text/Pandoc/App/CommandLineOptions.hs
@@ -436,10 +436,23 @@ options =
"SCRIPTPATH")
"" -- "Lua filter"
- , Option "" ["base-header-level"]
+ , Option "" ["shift-heading-level-by"]
(ReqArg
(\arg opt ->
case safeRead arg of
+ Just t ->
+ return opt{ optShiftHeadingLevel = t }
+ _ -> E.throwIO $ PandocOptionError
+ "shift-heading-level-by takes an integer argument")
+ "NUMBER")
+ "" -- "Shift heading level"
+
+ , Option "" ["base-header-level"]
+ (ReqArg
+ (\arg opt -> do
+ deprecatedOption "--base-header-level"
+ "Use --shift-heading-level-by instead."
+ case safeRead arg of
Just t | t > 0 && t < 6 ->
return opt{ optBaseHeaderLevel = t }
_ -> E.throwIO $ PandocOptionError
@@ -450,7 +463,7 @@ options =
, Option "" ["strip-empty-paragraphs"]
(NoArg
(\opt -> do
- deprecatedOption "--stripEmptyParagraphs"
+ deprecatedOption "--strip-empty-paragraphs"
"Use +empty_paragraphs extension."
return opt{ optStripEmptyParagraphs = True }))
"" -- "Strip empty paragraphs"
diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs
index 0b7bb7f2c..1111a5457 100644
--- a/src/Text/Pandoc/App/Opt.hs
+++ b/src/Text/Pandoc/App/Opt.hs
@@ -50,6 +50,7 @@ data Opt = Opt
, optReader :: Maybe String -- ^ Reader format
, optWriter :: Maybe String -- ^ Writer format
, optTableOfContents :: Bool -- ^ Include table of contents
+ , optShiftHeadingLevel :: Int -- ^ Shift heading level by
, optBaseHeaderLevel :: Int -- ^ Base header level
, optTemplate :: Maybe FilePath -- ^ Custom template
, optVariables :: [(String,String)] -- ^ Template variables to set
@@ -124,6 +125,7 @@ defaultOpts = Opt
, optReader = Nothing
, optWriter = Nothing
, optTableOfContents = False
+ , optShiftHeadingLevel = 0
, optBaseHeaderLevel = 1
, optTemplate = Nothing
, optVariables = []
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs
index 06715145e..e169ccb82 100644
--- a/src/Text/Pandoc/Shared.hs
+++ b/src/Text/Pandoc/Shared.hs
@@ -565,10 +565,23 @@ isHeaderBlock _ = False
-- | Shift header levels up or down.
headerShift :: Int -> Pandoc -> Pandoc
-headerShift n = walk shift
- where shift :: Block -> Block
- shift (Header level attr inner) = Header (level + n) attr inner
- shift x = x
+headerShift n (Pandoc meta (Header m _ ils : bs))
+ | n < 0
+ , m + n == 0 = headerShift n $
+ B.setTitle (B.fromList ils) $ Pandoc meta bs
+headerShift n (Pandoc meta bs)
+ | n > 0
+ , not (null (docTitle meta))
+ = Pandoc meta' (Header n nullAttr (docTitle meta) : bs')
+ where
+ Pandoc meta' bs' = headerShift n $ B.deleteMeta "title" $ Pandoc meta bs
+headerShift n (Pandoc meta bs) = Pandoc meta (walk shift bs)
+ where
+ shift :: Block -> Block
+ shift (Header level attr inner)
+ | level + n > 0 = Header (level + n) attr inner
+ | otherwise = Para inner
+ shift x = x
-- | Remove empty paragraphs.
stripEmptyParagraphs :: Pandoc -> Pandoc
diff --git a/test/command/shift-heading-level-by.md b/test/command/shift-heading-level-by.md
new file mode 100644
index 000000000..1d8b8bdd0
--- /dev/null
+++ b/test/command/shift-heading-level-by.md
@@ -0,0 +1,33 @@
+```
+% pandoc --shift-heading-level-by 1 -t native -s
+---
+title: My title
+...
+
+# First heading
+
+## Second
+^D
+Pandoc (Meta {unMeta = fromList []})
+[Header 1 ("",[],[]) [Str "My",Space,Str "title"]
+,Header 2 ("first-heading",[],[]) [Str "First",Space,Str "heading"]
+,Header 3 ("second",[],[]) [Str "Second"]]
+```
+
+```
+% pandoc --shift-heading-level-by -1 -t native -s
+---
+title: Old title
+...
+
+# First heading
+
+## Second
+
+# Another top-level heading
+^D
+Pandoc (Meta {unMeta = fromList [("title",MetaInlines [Str "First",Space,Str "heading"])]})
+[Header 1 ("second",[],[]) [Str "Second"]
+,Para [Str "Another",Space,Str "top-level",Space,Str "heading"]]
+```
+