diff options
author | Jesse Rosenthal <jrosenthal@jhu.edu> | 2019-05-21 11:31:38 -0400 |
---|---|---|
committer | Jesse Rosenthal <jrosenthal@jhu.edu> | 2019-05-21 12:19:59 -0400 |
commit | ed73bd28e511f72b17fc84126da85410e13b396b (patch) | |
tree | bd3a8351fa5015dddd24f82709ee3b7784a9bde4 /src/Text/Pandoc | |
parent | 6208d4e7fcf1792203b3069d0002ad5cb1ec05dd (diff) | |
download | pandoc-ed73bd28e511f72b17fc84126da85410e13b396b.tar.gz |
Markdown writer: Handle labels with integer names
Previously if labels had integer names, it could produce a conflict
with auto-labeled reference links. Now we test for a conflict and find
the next available integer.
Note that this involves adding a new state variable `stPrevRefs` to
keep track of refs used in other document parts when using
`--reference-location=block|section`
Closes #5495
Diffstat (limited to 'src/Text/Pandoc')
-rw-r--r-- | src/Text/Pandoc/Writers/Markdown.hs | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs index 5f165f7d3..046b82260 100644 --- a/src/Text/Pandoc/Writers/Markdown.hs +++ b/src/Text/Pandoc/Writers/Markdown.hs @@ -75,6 +75,7 @@ instance Default WriterEnv } data WriterState = WriterState { stNotes :: Notes + , stPrevRefs :: Refs , stRefs :: Refs , stKeys :: M.Map Key (M.Map (Target, Attr) Int) @@ -85,6 +86,7 @@ data WriterState = WriterState { stNotes :: Notes instance Default WriterState where def = WriterState{ stNotes = [] + , stPrevRefs = [] , stRefs = [] , stKeys = M.empty , stLastIdx = 0 @@ -355,7 +357,8 @@ notesAndRefs opts = do notes' <- reverse <$> gets stNotes >>= notesToMarkdown opts modify $ \s -> s { stNotes = [] } refs' <- reverse <$> gets stRefs >>= refsToMarkdown opts - modify $ \s -> s { stRefs = [] } + modify $ \s -> s { stPrevRefs = stPrevRefs s ++ stRefs s + , stRefs = []} let endSpacing = if | writerReferenceLocation opts == EndOfDocument -> empty @@ -867,6 +870,20 @@ blockListToMarkdown opts blocks = do getKey :: Doc -> Key getKey = toKey . render Nothing +findUsableIndex :: [Doc] -> Int -> Int +findUsableIndex lbls i = do + if (text (show i)) `elem` lbls + then findUsableIndex lbls (i + 1) + else i + +getNextIndex :: PandocMonad m => MD m Int +getNextIndex = do + prevRefs <- gets stPrevRefs + refs <- gets stRefs + i <- (+ 1) <$> gets stLastIdx + let refLbls = map (\(r,_,_) -> r) $ prevRefs ++ refs + return $ findUsableIndex refLbls i + -- | Get reference for target; if none exists, create unique one and return. -- Prefer label if possible; otherwise, generate a unique key. getReference :: PandocMonad m => Attr -> Doc -> Target -> MD m Doc @@ -880,7 +897,7 @@ getReference attr label target = do Nothing -> do -- no other refs with this label (lab', idx) <- if isEmpty label then do - i <- (+ 1) <$> gets stLastIdx + i <- getNextIndex modify $ \s -> s{ stLastIdx = i } return (text (show i), i) else return (label, 0) @@ -905,7 +922,7 @@ getReference attr label target = do stRefs = (lab', target, attr) : refs }) return lab' Nothing -> do -- but this one is to a new target - i <- (+ 1) <$> gets stLastIdx + i <- getNextIndex modify $ \s -> s{ stLastIdx = i } let lab' = text (show i) modify (\s -> s{ |