@@ -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
@@ -695,27 +696,47 @@ getReference label (src, tit) = do
695696inlineListToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc
696697inlineListToMarkdown opts lst = do
697698 inlist <- gets stInList
698− mapM (inlineToMarkdown opts)
699− (if inlist then avoidBadWraps lst else lst) >>= return . cat
700− where avoidBadWraps [] = []
701− avoidBadWraps (Space:Str ('>':cs):xs) =
702− Str (' ':'>':cs) : avoidBadWraps xs
703− avoidBadWraps (Space:Str [c]:[])
704− | c `elem` "-*+" = Str [' ', c] : []
705− avoidBadWraps (Space:Str [c]:Space:xs)
706− | c `elem` "-*+" = Str [' ', c] : Space : avoidBadWraps xs
707− avoidBadWraps (Space:Str cs:Space:xs)
708− | isOrderedListMarker cs = Str (' ':cs) : Space : avoidBadWraps xs
709− avoidBadWraps (Space:Str cs:[])
710− | isOrderedListMarker cs = Str (' ':cs) : []
711− avoidBadWraps (x:xs) = x : avoidBadWraps xs
712− isOrderedListMarker xs = endsWithListPunct xs &&
713− isRight (runParserT (anyOrderedListMarker >> eof)
714− defaultParserState "" xs)
715− endsWithListPunct xs = case reverse xs of
716− '.':_ -> True
717− ')':_ -> True
718− _ -> False
699+ go (if inlist then avoidBadWrapsInList lst else lst)
700+ where go [] = return empty
701+ go (i:is) = case i of
702+ (Link _ _) -> case is of
703+ -- If a link is followed by another link or '[' we don't shortcut
704+ (Link _ _):_ -> unshortcutable
705+ Space:(Link _ _):_ -> unshortcutable
706+ Space:(Str('[':_)):_ -> unshortcutable
707+ Space:(RawInline _ ('[':_)):_ -> unshortcutable
708+ Space:(Cite _ _):_ -> unshortcutable
709+ (Cite _ _):_ -> unshortcutable
710+ Str ('[':_):_ -> unshortcutable
711+ (RawInline _ ('[':_)):_ -> unshortcutable
712+ (RawInline _ (' ':'[':_)):_ -> unshortcutable
713+ _ -> shortcutable
714+ _ -> shortcutable
715+ where shortcutable = liftM2 (<>) (inlineToMarkdown opts i) (go is)
716+ unshortcutable = do
717+ iMark <- withState (\s -> s { stRefShortcutable = False })
718+ (inlineToMarkdown opts i)
719+ modify (\s -> s {stRefShortcutable = True })
720+ fmap (iMark <>) (go is)
721+
722+avoidBadWrapsInList :: [Inline] -> [Inline]
723+avoidBadWrapsInList [] = []
724+avoidBadWrapsInList (Space:Str ('>':cs):xs) =
725+ Str (' ':'>':cs) : avoidBadWrapsInList xs
726+avoidBadWrapsInList (Space:Str [c]:[])
727+ | c `elem` "-*+" = Str [' ', c] : []
728+avoidBadWrapsInList (Space:Str [c]:Space:xs)
729+ | c `elem` "-*+" = Str [' ', c] : Space : avoidBadWrapsInList xs
730+avoidBadWrapsInList (Space:Str cs:Space:xs)
731+ | isOrderedListMarker cs = Str (' ':cs) : Space : avoidBadWrapsInList xs
732+avoidBadWrapsInList (Space:Str cs:[])
733+ | isOrderedListMarker cs = Str (' ':cs) : []
734+avoidBadWrapsInList (x:xs) = x : avoidBadWrapsInList xs
735+
736+isOrderedListMarker :: String -> Bool
737+isOrderedListMarker xs = (last xs `elem` ".)") &&
738+ isRight (runParserT (anyOrderedListMarker >> eof)
739+ defaultParserState "" xs)
719740
720741isRight :: Either a b -> Bool
721742isRight (Right _) = True
@@ -878,6 +899,9 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
878899 [Str s] | escapeURI s == srcSuffix -> True
879900 _ -> False
880901 let useRefLinks = writerReferenceLinks opts && not useAuto
902+ shortcutable <- gets stRefShortcutable
903+ let useShortcutRefLinks = shortcutable &&
904+ isEnabled Ext_shortcut_reference_links opts
881905 ref <- if useRefLinks then getReference txt (src, tit) else return []
882906 reftext <- inlineListToMarkdown opts ref
883907 return $ if useAuto
@@ -887,7 +911,9 @@ inlineToMarkdown opts (Link txt (src, tit)) = do
887911 else if useRefLinks
888912 then let first = "[" <> linktext <> "]"
889913 second = if txt == ref
890− then "[]"
914+ then if useShortcutRefLinks
915+ then ""
916+ else "[]"
891917 else "[" <> reftext <> "]"
892918 in first <> second
893919 else if plain