From ed73bd28e511f72b17fc84126da85410e13b396b Mon Sep 17 00:00:00 2001 From: Jesse Rosenthal Date: Tue, 21 May 2019 11:31:38 -0400 Subject: 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 --- src/Text/Pandoc/Writers/Markdown.hs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src/Text') 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{ -- cgit v1.2.3