Skip to content

Commit 03bb426

Browse files
committed
Shared: makeSections behavior changes.
+ When the optional base level parameter is provided, we no longer ensure that the sequence of heading levels is gapless [behavior change]. Instead, we set the lowest heading level to the specified base level, and adjust the others accordingly. If an author wants to skip a level, e.g. from level 1 to level 3, they can do that. In general, the heading levels specified in the source document are preserved; `makeSections` only puts them into a hierarchical structure. Closes #9398. + Section numbers are now assigned so that the top level gets `1`, no matter what heading level is used. So, even if the top heading level is 2, numbers will be `1`, `2`, etc. rather than `0.1`, `0.2`, as in the past. Closes #5071. + We revert to the old behavior when the `--number-offset` option is used. So, for example, if a document begins with a level-3 heading, and `--number-offset=1,2` is used, the top-level section numbers will be `1.2.1`, `1.2.2`, etc. This is mainly for backwards-compatibility.
1 parent 6fc8a80 commit 03bb426

File tree

4 files changed

+96
-20
lines changed

4 files changed

+96
-20
lines changed

pandoc-lua-engine/test/lua/module/pandoc-structure.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ return {
4848
assert.are_equal('Div', hblks[1].t)
4949
assert.are_equal('Header', hblks[1].content[1].t)
5050
assert.are_equal('1', hblks[1].content[1].attributes['number'])
51-
assert.are_equal('1.1', hblks[1].content[3].attributes['number'])
51+
assert.are_equal('1.0.1', hblks[1].content[3].attributes['number'])
5252
end)
5353
},
5454

src/Text/Pandoc/Shared.hs

+16-13
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ import Data.Char (isAlpha, isLower, isSpace, isUpper, toLower, isAlphaNum,
9696
import Data.List (find, foldl', groupBy, intercalate, intersperse,
9797
union, sortOn)
9898
import qualified Data.Map as M
99-
import Data.Maybe (mapMaybe, fromMaybe)
100-
import Data.Monoid (Any (..))
99+
import Data.Maybe (mapMaybe)
100+
import Data.Monoid (Any (..) )
101+
import Data.Semigroup (Min (..))
101102
import Data.Sequence (ViewL (..), ViewR (..), viewl, viewr)
102103
import qualified Data.Set as Set
103104
import qualified Data.Text as T
@@ -507,26 +508,28 @@ textToIdentifier exts =
507508
-- element a Header). If the 'numbering' parameter is True, Header
508509
-- numbers are added via the number attribute on the header.
509510
-- If the baseLevel parameter is Just n, Header levels are
510-
-- adjusted to be gapless starting at level n.
511+
-- adjusted so that the lowest header level is n.
512+
-- (There may still be gaps in header level if the author leaves them.)
511513
makeSections :: Bool -> Maybe Int -> [Block] -> [Block]
512514
makeSections numbering mbBaseLevel bs =
513-
S.evalState (go bs) (mbBaseLevel, [])
515+
S.evalState (go bs) []
514516
where
515-
go :: [Block] -> S.State (Maybe Int, [Int]) [Block]
517+
getLevel (Header level _ _) = Min level
518+
getLevel _ = Min 99
519+
minLevel = getMin $ query getLevel bs
520+
go :: [Block] -> S.State [Int] [Block]
516521
go (Header level (ident,classes,kvs) title':xs) = do
517-
(mbLevel, lastnum) <- S.get
518-
let level' = fromMaybe level mbLevel
522+
lastnum <- S.get
523+
let level' = maybe level (\n -> n + level - minLevel) mbBaseLevel
519524
let adjustNum lev numComponent
520-
| lev < level' = numComponent
521-
| lev == level' = numComponent + 1
525+
| lev < level = numComponent
526+
| lev == level = numComponent + 1
522527
| otherwise = 0
523-
let newnum = zipWith adjustNum [(fromMaybe 1 mbBaseLevel)..level']
528+
let newnum = zipWith adjustNum [minLevel..level]
524529
(lastnum ++ repeat 0)
525-
unless (null newnum) $ S.modify $ \(mbl, _) -> (mbl, newnum)
530+
unless (null newnum) $ S.put newnum
526531
let (sectionContents, rest) = break (headerLtEq level) xs
527-
S.modify $ \(_, ln) -> (fmap (+ 1) mbLevel, ln)
528532
sectionContents' <- go sectionContents
529-
S.modify $ \(_, ln) -> (mbLevel, ln)
530533
rest' <- go rest
531534
let kvs' = -- don't touch number if already present
532535
case lookup "number" kvs of

src/Text/Pandoc/Writers/HTML.hs

+11-6
Original file line numberDiff line numberDiff line change
@@ -721,17 +721,22 @@ adjustNumbers opts doc =
721721
then doc
722722
else walk go doc
723723
where
724-
go (Div (ident,"section":classes,kvs) lst) =
725-
Div (ident,"section":classes,map fixnum kvs) lst
724+
go (Div (ident,"section":classes,kvs) lst@(Header level _ _ : _)) =
725+
Div (ident,"section":classes,map (fixnum level) kvs) lst
726726
go (Header level (ident,classes,kvs) lst) =
727-
Header level (ident,classes,map fixnum kvs) lst
727+
Header level (ident,classes,map (fixnum level) kvs) lst
728728
go x = x
729-
fixnum ("number",num) = ("number",
729+
fixnum level ("number",num) = ("number",
730730
showSecNum $ zipWith (+)
731731
(writerNumberOffset opts ++ repeat 0)
732-
(map (fromMaybe 0 . safeRead) $
732+
(padTo level $
733+
map (fromMaybe 0 . safeRead) $
733734
T.split (=='.') num))
734-
fixnum x = x
735+
fixnum _ x = x
736+
padTo n xs =
737+
case n - length xs of
738+
x | x > 0 -> replicate x 0 ++ xs
739+
| otherwise -> xs
735740
showSecNum = T.intercalate "." . map tshow
736741

737742
blockToHtmlInner :: PandocMonad m => WriterOptions -> Block -> StateT WriterState m Html

test/command/5071.md

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
```
2+
% pandoc -f markdown -t html --number-sections
3+
## First section
4+
5+
### Subhead
6+
7+
##### Subhead with gap
8+
9+
## Second section
10+
^D
11+
<h2 data-number="1" id="first-section"><span
12+
class="header-section-number">1</span> First section</h2>
13+
<h3 data-number="1.1" id="subhead"><span
14+
class="header-section-number">1.1</span> Subhead</h3>
15+
<h5 data-number="1.1.0.1" id="subhead-with-gap"><span
16+
class="header-section-number">1.1.0.1</span> Subhead with gap</h5>
17+
<h2 data-number="2" id="second-section"><span
18+
class="header-section-number">2</span> Second section</h2>
19+
20+
```
21+
22+
```
23+
% pandoc -f markdown -t html --number-sections
24+
## First section
25+
26+
### Subhead
27+
28+
# Higher-level section
29+
30+
## Sub
31+
^D
32+
<h2 data-number="0.1" id="first-section"><span
33+
class="header-section-number">0.1</span> First section</h2>
34+
<h3 data-number="0.1.1" id="subhead"><span
35+
class="header-section-number">0.1.1</span> Subhead</h3>
36+
<h1 data-number="1" id="higher-level-section"><span
37+
class="header-section-number">1</span> Higher-level section</h1>
38+
<h2 data-number="1.1" id="sub"><span
39+
class="header-section-number">1.1</span> Sub</h2>
40+
```
41+
42+
For backwards compatibility, we want it to work the old way,
43+
giving numbers like 0.1, when `--number-offset` is used:
44+
```
45+
% pandoc -f markdown -t html --number-sections --number-offset=2,2,2
46+
## First section
47+
48+
### Subhead
49+
^D
50+
<h2 data-number="2.3" id="first-section"><span
51+
class="header-section-number">2.3</span> First section</h2>
52+
<h3 data-number="2.3.3" id="subhead"><span
53+
class="header-section-number">2.3.3</span> Subhead</h3>
54+
55+
```
56+
57+
```
58+
% pandoc -f markdown -t html --number-sections --number-offset=0,2,2
59+
## First section
60+
61+
### Subhead
62+
^D
63+
<h2 data-number="0.3" id="first-section"><span
64+
class="header-section-number">0.3</span> First section</h2>
65+
<h3 data-number="0.3.3" id="subhead"><span
66+
class="header-section-number">0.3.3</span> Subhead</h3>
67+
68+
```

0 commit comments

Comments
 (0)