git.iko.soy/typeable/pandoc
on master help sign in
Muse writer: only escape brackets when necessary

It includes cases when they can be mistaken for footnotes and links, as well as inside link description.

commitaca4137c4094ec921276bf50278dfc58db5634a3 authorAlexander Krotov <ilabdsf@gmail.com> dateWed 14 Mar 2018, 12:23 (9 years ago) parentbdb8424
3 files changed+43−17
src/Text/Pandoc/Writers/Muse.hs+34−11 test/Tests/Writers/Muse.hs+3 test/writer.muse+6−6
src/Text/Pandoc/Writers/Muse.hs+34−11
@@ -67,11 +67,12 @@ type Notes = [[Block]]
6767type Muse m = ReaderT WriterEnv (StateT WriterState m)
6868
6969data WriterEnv =
70− WriterEnv { envOptions :: WriterOptions
71− , envTopLevel :: Bool
70+ WriterEnv { envOptions :: WriterOptions
71+ , envTopLevel :: Bool
7272 , envInsideBlock :: Bool
7373 , envInlineStart :: Bool
74− , envAfterSpace :: Bool
74+ , envInsideLinkDescription :: Bool -- Escape ] if True
75+ , envAfterSpace :: Bool
7576 }
7677
7778data WriterState =
@@ -98,6 +99,7 @@ writeMuse opts document =
9899 , envTopLevel = True
99100 , envInsideBlock = False
100101 , envInlineStart = True
102+ , envInsideLinkDescription = False
101103 , envAfterSpace = True
102104 }
103105
@@ -304,12 +306,31 @@ startsWithMarker f (x:xs) =
304306startsWithMarker _ [] = False
305307
306308-- | Escape special characters for Muse if needed.
307−conditionalEscapeString :: String -> String
308−conditionalEscapeString s =
309− if any (`elem` ("#*<=>[]|" :: String)) s ||
309+containsFootnotes :: String -> Bool
310+containsFootnotes st =
311+ p st
312+ where p ('[':xs) = q xs || p xs
313+ p (_:xs) = p xs
314+ p "" = False
315+ q (x:xs)
316+ | (x `elem` ("123456789"::String)) = r xs || p xs
317+ | otherwise = p xs
318+ q [] = False
319+ r ('0':xs) = r xs || p xs
320+ r (xs) = s xs || q xs || p xs
321+ s (']':_) = True
322+ s (_:xs) = p xs
323+ s [] = False
324+
325+conditionalEscapeString :: Bool -> String -> String
326+conditionalEscapeString isInsideLinkDescription s =
327+ if any (`elem` ("#*<=>|" :: String)) s ||
310328 "::" `isInfixOf` s ||
311329 "----" `isInfixOf` s ||
312− "~~" `isInfixOf` s
330+ "~~" `isInfixOf` s ||
331+ "[[" `isInfixOf` s ||
332+ ("]" `isInfixOf` s && isInsideLinkDescription) ||
333+ containsFootnotes s
313334 then escapeString s
314335 else s
315336
@@ -428,7 +449,9 @@ inlineListToMuse = inlineListToMuse'' False
428449inlineToMuse :: PandocMonad m
429450 => Inline
430451 -> Muse m Doc
431−inlineToMuse (Str str) = return $ text $ conditionalEscapeString str
452+inlineToMuse (Str str) = do
453+ insideLink <- asks envInsideLinkDescription
454+ return $ text $ conditionalEscapeString insideLink str
432455inlineToMuse (Emph lst) = do
433456 contents <- inlineListToMuse lst
434457 return $ "<em>" <> contents <> "</em>"
@@ -469,7 +492,7 @@ inlineToMuse (Link _ txt (src, _)) =
469492 case txt of
470493 [Str x] | escapeURI x == src ->
471494 return $ "[[" <> text (escapeLink x) <> "]]"
472− _ -> do contents <- inlineListToMuse txt
495+ _ -> do contents <- local (\env -> env { envInsideLinkDescription = True }) $ inlineListToMuse txt
473496 return $ "[[" <> text (escapeLink src) <> "][" <> contents <> "]]"
474497 where escapeLink lnk = if isImageUrl lnk then "URL:" ++ urlEscapeBrackets lnk else urlEscapeBrackets lnk
475498 -- Taken from muse-image-regexp defined in Emacs Muse file lisp/muse-regexps.el
@@ -479,7 +502,7 @@ inlineToMuse (Image attr alt (source,'f':'i':'g':':':title)) =
479502 inlineToMuse (Image attr alt (source,title))
480503inlineToMuse (Image attr inlines (source, title)) = do
481504 opts <- asks envOptions
482− alt <- inlineListToMuse inlines
505+ alt <- local (\env -> env { envInsideLinkDescription = True }) $ inlineListToMuse inlines
483506 let title' = if null title
484507 then if null inlines
485508 then ""
@@ -489,7 +512,7 @@ inlineToMuse (Image attr inlines (source, title)) = do
489512 Just (Percent x) | isEnabled Ext_amuse opts -> " " ++ show (round x :: Integer)
490513 _ -> ""
491514 return $ "[[" <> text (urlEscapeBrackets source ++ width) <> "]" <> title' <> "]"
492− where escape s = if "]" `isInfixOf` s then escapeString s else conditionalEscapeString s
515+ where escape s = if "]" `isInfixOf` s then escapeString s else conditionalEscapeString True s
493516inlineToMuse (Note contents) = do
494517 -- add to notes in state
495518 notes <- gets stNotes
test/Tests/Writers/Muse.hs+3
@@ -301,8 +301,11 @@ tests = [ testGroup "block elements"
301301 [ testGroup "string"
302302 [ "string" =: str "foo" =?> "foo"
303303 , "escape footnote" =: str "[1]" =?> "<verbatim>[1]</verbatim>"
304+ , "do not escape brackets" =: str "[12ab]" =?> "[12ab]"
304305 , "escape verbatim close tag" =: str "foo</verbatim>bar"
305306 =?> "<verbatim>foo<</verbatim><verbatim>/verbatim>bar</verbatim>"
307+ , "escape link-like text" =: str "[[https://www.example.org]]"
308+ =?> "<verbatim>[[https://www.example.org]]</verbatim>"
306309 , "escape pipe to avoid accidental tables" =: str "foo | bar"
307310 =?> "<verbatim>foo | bar</verbatim>"
308311 , "escape hash to avoid accidental anchors" =: text "#foo bar"
test/writer.muse+6−6
@@ -576,9 +576,9 @@ Left brace: {
576576
577577Right brace: }
578578
579−Left bracket: <verbatim>[</verbatim>
579+Left bracket: [
580580
581−Right bracket: <verbatim>]</verbatim>
581+Right bracket: ]
582582
583583Left paren: (
584584
@@ -634,7 +634,7 @@ Indented [[/url][twice]].
634634
635635Indented [[/url][thrice]].
636636
637−This should <verbatim>[not][]</verbatim> be a link.
637+This should [not][] be a link.
638638
639639<example>
640640[not]: /url
@@ -690,8 +690,8 @@ Here is a movie [[movie.jpg][movie]] icon.
690690* Footnotes
691691
692692Here is a footnote reference,[1] and another.[2] This should <em>not</em> be a
693−footnote reference, because it contains a <verbatim>space.[^my</verbatim>
694−<verbatim>note]</verbatim> Here is an inline note.[3]
693+footnote reference, because it contains a space.[^my note] Here is an inline
694+note.[3]
695695
696696<quote>
697697Notes can go in quotes.[4]
@@ -718,7 +718,7 @@ This paragraph should not be part of the note, as it is not indented.
718718
719719[3] This is <em>easier</em> to type. Inline notes may contain
720720 [[http://google.com][links]] and <code>]</code> verbatim characters, as
721− well as <verbatim>[bracketed</verbatim> <verbatim>text].</verbatim>
721+ well as [bracketed text].
722722
723723[4] In quote.
724724