aboutsummaryrefslogtreecommitdiff
path: root/src/Text/Pandoc
diff options
context:
space:
mode:
authorJesse Rosenthal <jrosenthal@jhu.edu>2019-05-21 11:31:38 -0400
committerJesse Rosenthal <jrosenthal@jhu.edu>2019-05-21 12:19:59 -0400
commited73bd28e511f72b17fc84126da85410e13b396b (patch)
treebd3a8351fa5015dddd24f82709ee3b7784a9bde4 /src/Text/Pandoc
parent6208d4e7fcf1792203b3069d0002ad5cb1ec05dd (diff)
downloadpandoc-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.hs23
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{