@@ -57,14 +57,15 @@ import qualified Data.Text as T
5757
5858type Notes = [[Block]]
5959type Refs = [([Inline], Target)]
60−data WriterState = WriterState { stNotes :: Notes
61− , stRefs :: Refs
62− , stInList :: Bool
63− , stIds :: [String]
64− , stPlain :: Bool }
60+data WriterState = WriterState { stNotes :: Notes
61+ , stRefs :: Refs
62+ , stRefShortcutable :: Bool
63+ , stInList :: Bool
64+ , stIds :: [String]
65+ , stPlain :: Bool }
6566instance Default WriterState
66− where def = WriterState{ stNotes = [], stRefs = [], stInList = False,
67− stIds = [], stPlain = False }
67+ where def = WriterState{ stNotes = [], stRefs = [], stRefShortcutable = True,
68+ stInList = False, stIds = [], stPlain = False }
6869
6970-- | Convert Pandoc to Markdown.
7071writeMarkdown :: WriterOptions -> Pandoc -> String
@@ -690,27 +691,47 @@ getReference label (src, tit) = do
690691inlineListToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc
691692inlineListToMarkdown opts lst = do
692693 inlist <- gets stInList
693− mapM (inlineToMarkdown opts)
694− (if inlist then avoidBadWraps lst else lst) >>= return . cat
695− where avoidBadWraps [] = []
696− avoidBadWraps (Space:Str ('>':cs):xs) =
697− Str (' ':'>':cs) : avoidBadWraps xs
698− avoidBadWraps (Space:Str [c]:[])
699− | c `elem` "-*+" = Str [' ', c] : []
700− avoidBadWraps (Space:Str [c]:Space:xs)
701− | c `elem` "-*+" = Str [' ', c] : Space : avoidBadWraps xs
702− avoidBadWraps (Space:Str cs:Space:xs)
703− | isOrderedListMarker cs = Str (' ':cs) : Space : avoidBadWraps xs
704− avoidBadWraps (Space:Str cs:[])
705− | isOrderedListMarker cs = Str (' ':cs) : []
706− avoidBadWraps (x:xs) = x : avoidBadWraps xs
707− isOrderedListMarker xs = endsWithListPunct xs &&
708− isRight (runParserT (anyOrderedListMarker >> eof)
709− defaultParserState "" xs)
710− endsWithListPunct xs = case reverse xs of
711− '.':_ -> True
712− ')':_ -> True
713− _ -> False
694+ go (if inlist then avoidBadWrapsInList lst else lst)
695+ where go [] = return empty
696+ go (i:is) = case i of
697+ (Link _ _) -> case is of
698+ -- If a link is followed by another link or '[' we don't shortcut
699+ (Link _ _):_ -> unshortcutable
700+ Space:(Link _ _):_ -> unshortcutable
701+ Space:(Str('[':_)):_ -> unshortcutable
702+ Space:(RawInline _ ('[':_)):_ -> unshortcutable
703+ Space:(Cite _ _):_ -> unshortcutable
704+ (Cite _ _):_ -> unshortcutable
705+ Str ('[':_):_ -> unshortcutable
706+ (RawInline _ ('[':_)):_ -> unshortcutable
707+ (RawInline _ (' ':'[':_)):_ -> unshortcutable
708+ _ -> shortcutable
709+ _ -> shortcutable
710+ where shortcutable = liftM2 (<>) (inlineToMarkdown opts i) (go is)
711+ unshortcutable = do
712+ iMark <- withState (\s -> s { stRefShortcutable = False })
713+ (inlineToMarkdown opts i)
714+ modify (\s -> s {stRefShortcutable = True })
715+ fmap (iMark <>) (go is)
716+
717+avoidBadWrapsInList :: [Inline] -> [Inline]
718+avoidBadWrapsInList [] = []
719+avoidBadWrapsInList (Space:Str ('>':cs):xs) =
720+ Str (' ':'>':cs) : avoidBadWrapsInList xs
721+avoidBadWrapsInList (Space:Str [c]:[])
722+ | c `elem` "-*+" = Str [' ', c] : []
723+avoidBadWrapsInList (Space:Str [c]:Space:xs)
724+ | c `elem` "-*+" = Str [' ', c] : Space : avoidBadWrapsInList xs
725+avoidBadWrapsInList (Space:Str cs:Space:xs)
726+ | isOrderedListMarker cs = Str (' ':cs) : Space : avoidBadWrapsInList xs
727+avoidBadWrapsInList (Space:Str cs:[])
728+ | isOrderedListMarker cs = Str (' ':cs) : []
729+avoidBadWrapsInList (x:xs) = x : avoidBadWrapsInList xs
730+
731+isOrderedListMarker :: String -> Bool
732+isOrderedListMarker xs = (last xs `elem` ".)") &&
733+ isRight (runParserT (anyOrderedListMarker >> eof)
734+ defaultParserState "" xs)
714735
715736isRight :: Either a b -> Bool
716737isRight (Right _) = True
@@ -873,6 +894,9 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
873894 [Str s] | escapeURI s == srcSuffix -> True
874895 _ -> False
875896 let useRefLinks = writerReferenceLinks opts && not useAuto
897+ shortcutable <- gets stRefShortcutable
898+ let useShortcutRefLinks = shortcutable &&
899+ isEnabled Ext_shortcut_reference_links opts
876900 ref <- if useRefLinks then getReference txt (src, tit) else return []
877901 reftext <- inlineListToMarkdown opts ref
878902 return $ if useAuto
@@ -882,7 +906,9 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
882906 else if useRefLinks
883907 then let first = "[" <> linktext <> "]"
884908 second = if txt == ref
885− then "[]"
909+ then if useShortcutRefLinks
910+ then ""
911+ else "[]"
886912 else "[" <> reftext <> "]"
887913 in first <> second
888914 else if plain