@@ -55,7 +55,8 @@ import qualified Data.Vector as V
5555import qualified Data.Text as T
5656
5757type Notes = [[Block]]
58−type Refs = [([Inline], Target)]
58+type Ref = ([Inline], Target, Attr)
59+type Refs = [Ref]
5960data WriterState = WriterState { stNotes :: Notes
6061 , stRefs :: Refs
6162 , stRefShortcutable :: Bool
@@ -200,15 +201,16 @@ refsToMarkdown opts refs = mapM (keyToMarkdown opts) refs >>= return . vcat
200201
201202-- | Return markdown representation of a reference key.
202203keyToMarkdown :: WriterOptions
203− -> ([Inline], (String, String))
204+ -> Ref
204205 -> State WriterState Doc
205−keyToMarkdown opts (label, (src, tit)) = do
206+keyToMarkdown opts (label, (src, tit), attr) = do
206207 label' <- inlineListToMarkdown opts label
207208 let tit' = if null tit
208209 then empty
209210 else space <> "\"" <> text tit <> "\""
210211 return $ nest 2 $ hang 2
211212 ("[" <> label' <> "]:" <> space) (text src <> tit')
213+ <> linkAttributes opts attr
212214
213215-- | Return markdown representation of notes.
214216notesToMarkdown :: WriterOptions -> [[Block]] -> State WriterState Doc
@@ -280,6 +282,12 @@ attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
280282 map (\(k,v) -> text k
281283 <> "=\"" <> text v <> "\"") ks
282284
285+linkAttributes :: WriterOptions -> Attr -> Doc
286+linkAttributes opts attr =
287+ if isEnabled Ext_common_link_attributes opts && attr /= nullAttr
288+ then attrsToMarkdown attr
289+ else empty
290+
283291-- | Ordered list start parser for use in Para below.
284292olMarker :: Parser [Char] ParserState Char
285293olMarker = do (start, style', delim) <- anyOrderedListMarker
@@ -665,21 +673,21 @@ blockListToMarkdown opts blocks =
665673
666674-- | Get reference for target; if none exists, create unique one and return.
667675-- Prefer label if possible; otherwise, generate a unique key.
668−getReference :: [Inline] -> Target -> State WriterState [Inline]
669−getReference label (src, tit) = do
676+getReference :: Attr -> [Inline] -> Target -> State WriterState [Inline]
677+getReference attr label target = do
670678 st <- get
671− case find ((== (src, tit)) . snd) (stRefs st) of
672− Just (ref, _) -> return ref
679+ case find (\(_,t,a) -> t == target && a == attr) (stRefs st) of
680+ Just (ref, _, _) -> return ref
673681 Nothing -> do
674− let label' = case find ((== label) . fst) (stRefs st) of
682+ let label' = case find (\(l,_,_) -> l == label) (stRefs st) of
675683 Just _ -> -- label is used; generate numerical label
676684 case find (\n -> notElem [Str (show n)]
677− (map fst (stRefs st)))
685+ (map (\(l,_,_) -> l) (stRefs st)))
678686 [1..(10000 :: Integer)] of
679687 Just x -> [Str (show x)]
680688 Nothing -> error "no unique label"
681689 Nothing -> label
682− modify (\s -> s{ stRefs = (label', (src,tit)) : stRefs st })
690+ modify (\s -> s{ stRefs = (label', target, attr) : stRefs st })
683691 return label'
684692
685693-- | Convert list of Pandoc inline elements to markdown.
@@ -689,10 +697,10 @@ inlineListToMarkdown opts lst = do
689697 go (if inlist then avoidBadWrapsInList lst else lst)
690698 where go [] = return empty
691699 go (i:is) = case i of
692− (Link _ _) -> case is of
700+ (Link _ _ _) -> case is of
693701 -- If a link is followed by another link or '[' we don't shortcut
694− (Link _ _):_ -> unshortcutable
695− Space:(Link _ _):_ -> unshortcutable
702+ (Link _ _ _):_ -> unshortcutable
703+ Space:(Link _ _ _):_ -> unshortcutable
696704 Space:(Str('[':_)):_ -> unshortcutable
697705 Space:(RawInline _ ('[':_)):_ -> unshortcutable
698706 Space:(Cite _ _):_ -> unshortcutable
@@ -883,7 +891,7 @@ inlineToMarkdown opts (Cite (c:cs) lst)
883891 return $ pdoc <+> r
884892 modekey SuppressAuthor = "-"
885893 modekey _ = ""
886−inlineToMarkdown opts (Link txt (src, tit)) = do
894+inlineToMarkdown opts (Link attr txt (src, tit)) = do
887895 plain <- gets stPlain
888896 linktext <- inlineListToMarkdown opts txt
889897 let linktitle = if null tit
@@ -898,7 +906,7 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
898906 shortcutable <- gets stRefShortcutable
899907 let useShortcutRefLinks = shortcutable &&
900908 isEnabled Ext_shortcut_reference_links opts
901− ref <- if useRefLinks then getReference txt (src, tit) else return []
909+ ref <- if useRefLinks then getReference attr txt (src, tit) else return []
902910 reftext <- inlineListToMarkdown opts ref
903911 return $ if useAuto
904912 then if plain
@@ -915,21 +923,18 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
915923 else if plain
916924 then linktext
917925 else "[" <> linktext <> "](" <>
918− text src <> linktitle <> ")"
926+ text src <> linktitle <> ")" <>
927+ linkAttributes opts attr
919928inlineToMarkdown opts (Image attr alternate (source, tit)) = do
920929 plain <- gets stPlain
921930 let txt = if null alternate || alternate == [Str source]
922931 -- to prevent autolinks
923932 then [Str ""]
924933 else alternate
925− linkPart <- inlineToMarkdown opts (Link txt (source, tit))
934+ linkPart <- inlineToMarkdown opts (Link attr txt (source, tit))
926935 return $ if plain
927936 then "[" <> linkPart <> "]"
928− else "!" <> linkPart <>
929− if isEnabled Ext_common_link_attributes opts
930− && attr /= nullAttr
931− then attrsToMarkdown attr
932− else empty
937+ else "!" <> linkPart
933938inlineToMarkdown opts (Note contents) = do
934939 modify (\st -> st{ stNotes = contents : stNotes st })
935940 st <- get