git.iko.soy/typeable/pandoc
on master help sign in
Muse reader: cleanup and conversion to applicative style
095fff7Alexander Krotov
src/Text/Pandoc/Readers/Muse.hs+75−95
@@ -180,38 +180,31 @@ someUntil p end = first <$> ((:) <$> p) <*> manyUntil p end
180-- ** HTML parsers
180-- ** HTML parsers
181
181
182openTag :: PandocMonad m => String -> MuseParser m [(String, String)]
182openTag :: PandocMonad m => String -> MuseParser m [(String, String)]
183−openTag tag = try $ do
183+openTag tag = try $
184− char '<'
185− string tag
186− manyTill attr (char '>')
184+ char '<' *> string tag *> manyTill attr (char '>')
187 where
185 where
188− attr = try $ do
186+ attr = try $ (,)
189− many1 spaceChar
187+ <$ many1 spaceChar
190− key <- many1 (noneOf "=\n")
188+ <*> many1 (noneOf "=\n")
191− string "=\""
189+ <* string "=\""
192− value <- manyTill (noneOf "\"") (char '"')
190+ <*> manyTill (noneOf "\"") (char '"')
193− return (key, value)
194
191
195closeTag :: PandocMonad m => String -> MuseParser m ()
192closeTag :: PandocMonad m => String -> MuseParser m ()
196−closeTag tag = try $ string "</" >> string tag >> void (char '>')
193+closeTag tag = try $ string "</" *> string tag *> void (char '>')
197
194
198-- | Parse HTML tag, returning its attributes and literal contents.
195-- | Parse HTML tag, returning its attributes and literal contents.
199htmlElement :: PandocMonad m
196htmlElement :: PandocMonad m
200 => String -- ^ Tag name
197 => String -- ^ Tag name
201 -> MuseParser m (Attr, String)
198 -> MuseParser m (Attr, String)
202−htmlElement tag = try $ do
199+htmlElement tag = try $ (,)
203− attr <- openTag tag
200+ <$> (htmlAttrToPandoc <$> openTag tag)
204− content <- manyTill anyChar $ closeTag tag
201+ <*> manyTill anyChar (closeTag tag)
205− return (htmlAttrToPandoc attr, content)
206
202
207htmlBlock :: PandocMonad m
203htmlBlock :: PandocMonad m
208 => String -- ^ Tag name
204 => String -- ^ Tag name
209 -> MuseParser m (Attr, String)
205 -> MuseParser m (Attr, String)
210−htmlBlock tag = try $ do
206+htmlBlock tag = try $
211− many spaceChar
212− res <- htmlElement tag
213− manyTill spaceChar eol
207+ many spaceChar *> htmlElement tag <* manyTill spaceChar eol
214− return res
215
208
216-- | Convert HTML attributes to Pandoc 'Attr'
209-- | Convert HTML attributes to Pandoc 'Attr'
217htmlAttrToPandoc :: [Attribute String] -> Attr
210htmlAttrToPandoc :: [Attribute String] -> Attr
@@ -229,7 +222,7 @@ parseHtmlContent tag = try $ do
229 pos <- getPosition
222 pos <- getPosition
230 attr <- openTag tag
223 attr <- openTag tag
231 manyTill spaceChar eol
224 manyTill spaceChar eol
232− content <- parseBlocksTill $ try $ count (sourceColumn pos - 1) spaceChar >> closeTag tag
225+ content <- parseBlocksTill $ try $ count (sourceColumn pos - 1) spaceChar *> closeTag tag
233 manyTill spaceChar eol -- closing tag must be followed by optional whitespace and newline
226 manyTill spaceChar eol -- closing tag must be followed by optional whitespace and newline
234 return (htmlAttrToPandoc attr, content)
227 return (htmlAttrToPandoc attr, content)
235
228
@@ -240,21 +233,19 @@ parseDirectiveKey :: PandocMonad m => MuseParser m String
240parseDirectiveKey = char '#' *> many (letter <|> char '-')
233parseDirectiveKey = char '#' *> many (letter <|> char '-')
241
234
242parseEmacsDirective :: PandocMonad m => MuseParser m (String, F Inlines)
235parseEmacsDirective :: PandocMonad m => MuseParser m (String, F Inlines)
243−parseEmacsDirective = do
236+parseEmacsDirective = (,)
244− key <- parseDirectiveKey
237+ <$> parseDirectiveKey
245− spaceChar
238+ <* spaceChar
246− value <- trimInlinesF . mconcat <$> manyTill (choice inlineList) eol
239+ <*> (trimInlinesF . mconcat <$> manyTill (choice inlineList) eol)
247− return (key, value)
248
240
249parseAmuseDirective :: PandocMonad m => MuseParser m (String, F Inlines)
241parseAmuseDirective :: PandocMonad m => MuseParser m (String, F Inlines)
250−parseAmuseDirective = do
242+parseAmuseDirective = (,)
251− key <- parseDirectiveKey
243+ <$> parseDirectiveKey
252− many1 spaceChar
244+ <* many1 spaceChar
253− value <- trimInlinesF . mconcat <$> many1Till inline endOfDirective
245+ <*> (trimInlinesF . mconcat <$> many1Till inline endOfDirective)
254− many blankline
246+ <* many blankline
255− return (key, value)
256 where
247 where
257− endOfDirective = lookAhead $ eof <|> try (newline >> (void blankline <|> void parseDirectiveKey))
248+ endOfDirective = lookAhead $ eof <|> try (newline *> (void blankline <|> void parseDirectiveKey))
258
249
259directive :: PandocMonad m => MuseParser m ()
250directive :: PandocMonad m => MuseParser m ()
260directive = do
251directive = do
@@ -372,18 +363,17 @@ comment :: PandocMonad m => MuseParser m (F Blocks)
372comment = try $ do
363comment = try $ do
373 getPosition >>= \pos -> guard (sourceColumn pos == 1)
364 getPosition >>= \pos -> guard (sourceColumn pos == 1)
374 char ';'
365 char ';'
375− optional (spaceChar >> many (noneOf "\n"))
366+ optional (spaceChar *> many (noneOf "\n"))
376 eol
367 eol
377 return mempty
368 return mempty
378
369
379-- | Parse a horizontal rule, consisting of 4 or more @\'-\'@ characters.
370-- | Parse a horizontal rule, consisting of 4 or more @\'-\'@ characters.
380separator :: PandocMonad m => MuseParser m (F Blocks)
371separator :: PandocMonad m => MuseParser m (F Blocks)
381−separator = try $ do
372+separator = try $ pure B.horizontalRule
382− string "----"
373+ <$ string "----"
383− many $ char '-'
374+ <* many (char '-')
384− many spaceChar
375+ <* many spaceChar
385− eol
376+ <* eol
386− return $ return B.horizontalRule
387
377
388headingStart :: PandocMonad m => MuseParser m (String, Int)
378headingStart :: PandocMonad m => MuseParser m (String, Int)
389headingStart = try $ do
379headingStart = try $ do
@@ -418,11 +408,10 @@ amuseHeadingUntil end = try $ do
418-- | Parse an example between @{{{@ and @}}}@.
408-- | Parse an example between @{{{@ and @}}}@.
419-- It is an Amusewiki extension influenced by Creole wiki, as described in @Text::Amuse@ documentation.
409-- It is an Amusewiki extension influenced by Creole wiki, as described in @Text::Amuse@ documentation.
420example :: PandocMonad m => MuseParser m (F Blocks)
410example :: PandocMonad m => MuseParser m (F Blocks)
421−example = try $ do
411+example = try $ pure . B.codeBlock
422− string "{{{"
412+ <$ string "{{{"
423− optional blankline
413+ <* optional blankline
424− contents <- manyTill anyChar $ try (optional blankline >> string "}}}")
414+ <*> manyTill anyChar (try (optional blankline *> string "}}}"))
425− return $ return $ B.codeBlock contents
426
415
427-- | Parse an @\<example>@ tag.
416-- | Parse an @\<example>@ tag.
428exampleTag :: PandocMonad m => MuseParser m (F Blocks)
417exampleTag :: PandocMonad m => MuseParser m (F Blocks)
@@ -482,7 +471,7 @@ playTag = do
482
471
483verseLine :: PandocMonad m => MuseParser m (F Inlines)
472verseLine :: PandocMonad m => MuseParser m (F Inlines)
484verseLine = do
473verseLine = do
485− indent <- (B.str <$> many1 (char ' ' >> pure '\160')) <|> pure mempty
474+ indent <- (B.str <$> many1 ('\160' <$ char ' ')) <|> pure mempty
486 rest <- manyTill (choice inlineList) newline
475 rest <- manyTill (choice inlineList) newline
487 return $ trimInlinesF $ mconcat (pure indent : rest)
476 return $ trimInlinesF $ mconcat (pure indent : rest)
488
477
@@ -494,13 +483,13 @@ verseTag = try $ do
494 openTag "verse"
483 openTag "verse"
495 manyTill spaceChar eol
484 manyTill spaceChar eol
496 let indent = count (sourceColumn pos - 1) spaceChar
485 let indent = count (sourceColumn pos - 1) spaceChar
497− content <- sequence <$> manyTill (indent >> verseLine) (try $ indent >> closeTag "verse")
486+ content <- sequence <$> manyTill (indent *> verseLine) (try $ indent *> closeTag "verse")
498 manyTill spaceChar eol
487 manyTill spaceChar eol
499 return $ B.lineBlock <$> content
488 return $ B.lineBlock <$> content
500
489
501-- | Parse @\<comment>@ tag.
490-- | Parse @\<comment>@ tag.
502commentTag :: PandocMonad m => MuseParser m (F Blocks)
491commentTag :: PandocMonad m => MuseParser m (F Blocks)
503−commentTag = htmlBlock "comment" >> return mempty
492+commentTag = mempty <$ htmlBlock "comment"
504
493
505-- | Parse paragraph contents.
494-- | Parse paragraph contents.
506paraContentsUntil :: PandocMonad m
495paraContentsUntil :: PandocMonad m
@@ -508,7 +497,7 @@ paraContentsUntil :: PandocMonad m
508 -> MuseParser m (F Inlines, a)
497 -> MuseParser m (F Inlines, a)
509paraContentsUntil end = do
498paraContentsUntil end = do
510 updateState (\st -> st { museInPara = True })
499 updateState (\st -> st { museInPara = True })
511− (l, e) <- someUntil inline $ try (manyTill spaceChar eol >> end)
500+ (l, e) <- someUntil inline $ try (manyTill spaceChar eol *> end)
512 updateState (\st -> st { museInPara = False })
501 updateState (\st -> st { museInPara = False })
513 return (trimInlinesF $ mconcat l, e)
502 return (trimInlinesF $ mconcat l, e)
514
503
@@ -522,9 +511,10 @@ paraUntil end = do
522 first (fmap B.para) <$> paraContentsUntil end
511 first (fmap B.para) <$> paraContentsUntil end
523
512
524noteMarker :: PandocMonad m => MuseParser m String
513noteMarker :: PandocMonad m => MuseParser m String
525−noteMarker = try $ do
514+noteMarker = try $ (:)
526− char '['
515+ <$ char '['
516+ <*> oneOf "123456789"
527− (:) <$> oneOf "123456789" <*> manyTill digit (char ']')
517+ <*> manyTill digit (char ']')
528
518
529-- Amusewiki version of note
519-- Amusewiki version of note
530-- Parsing is similar to list item, except that note marker is used instead of list marker
520-- Parsing is similar to list item, except that note marker is used instead of list marker
@@ -567,16 +557,15 @@ emacsNoteBlock = try $ do
567lineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
557lineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
568lineVerseLine = try $ do
558lineVerseLine = try $ do
569 string "> "
559 string "> "
570− indent <- many (char ' ' >> pure '\160')
560+ indent <- many ('\160' <$ char ' ')
571 let indentEl = if null indent then mempty else B.str indent
561 let indentEl = if null indent then mempty else B.str indent
572 rest <- manyTill (choice inlineList) eol
562 rest <- manyTill (choice inlineList) eol
573 return $ trimInlinesF $ mconcat (pure indentEl : rest)
563 return $ trimInlinesF $ mconcat (pure indentEl : rest)
574
564
575blanklineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
565blanklineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
576−blanklineVerseLine = try $ do
566+blanklineVerseLine = try $ mempty
577− char '>'
567+ <$ char '>'
578− blankline
568+ <* blankline
579− pure mempty
580
569
581-- | Parse a line block indicated by @\'>\'@ characters.
570-- | Parse a line block indicated by @\'>\'@ characters.
582lineBlock :: PandocMonad m => MuseParser m (F Blocks)
571lineBlock :: PandocMonad m => MuseParser m (F Blocks)
@@ -596,7 +585,7 @@ bulletListItemsUntil indent end = try $ do
596 char '-'
585 char '-'
597 void spaceChar <|> lookAhead eol
586 void spaceChar <|> lookAhead eol
598 updateState (\st -> st { museInPara = False })
587 updateState (\st -> st { museInPara = False })
599− (x, (xs, e)) <- listItemContentsUntil (indent + 2) (try (optional blankline >> indentWith indent >> bulletListItemsUntil indent end)) (([],) <$> end)
588+ (x, (xs, e)) <- listItemContentsUntil (indent + 2) (try (optional blankline *> indentWith indent *> bulletListItemsUntil indent end)) (([],) <$> end)
600 return (x:xs, e)
589 return (x:xs, e)
601
590
602-- | Parse a bullet list.
591-- | Parse a bullet list.
@@ -643,7 +632,7 @@ orderedListItemsUntil indent style end =
643 pos <- getPosition
632 pos <- getPosition
644 void spaceChar <|> lookAhead eol
633 void spaceChar <|> lookAhead eol
645 updateState (\st -> st { museInPara = False })
634 updateState (\st -> st { museInPara = False })
646− (x, (xs, e)) <- listItemContentsUntil (sourceColumn pos) (try (optional blankline >> indentWith indent >> museOrderedListMarker style >> continuation)) (([],) <$> end)
635+ (x, (xs, e)) <- listItemContentsUntil (sourceColumn pos) (try (optional blankline *> indentWith indent *> museOrderedListMarker style *> continuation)) (([],) <$> end)
647 return (x:xs, e)
636 return (x:xs, e)
648
637
649-- | Parse an ordered list.
638-- | Parse an ordered list.
@@ -667,7 +656,7 @@ descriptionsUntil :: PandocMonad m
667descriptionsUntil indent end = do
656descriptionsUntil indent end = do
668 void spaceChar <|> lookAhead eol
657 void spaceChar <|> lookAhead eol
669 updateState (\st -> st { museInPara = False })
658 updateState (\st -> st { museInPara = False })
670− (x, (xs, e)) <- listItemContentsUntil indent (try (optional blankline >> indentWith indent >> manyTill spaceChar (string "::") >> descriptionsUntil indent end)) (([],) <$> end)
659+ (x, (xs, e)) <- listItemContentsUntil indent (try (optional blankline *> indentWith indent *> manyTill spaceChar (string "::") *> descriptionsUntil indent end)) (([],) <$> end)
671 return (x:xs, e)
660 return (x:xs, e)
672
661
673definitionListItemsUntil :: PandocMonad m
662definitionListItemsUntil :: PandocMonad m
@@ -680,7 +669,7 @@ definitionListItemsUntil indent end =
680 continuation = try $ do
669 continuation = try $ do
681 pos <- getPosition
670 pos <- getPosition
682 term <- trimInlinesF . mconcat <$> manyTill (choice inlineList) (try $ string "::")
671 term <- trimInlinesF . mconcat <$> manyTill (choice inlineList) (try $ string "::")
683− (x, (xs, e)) <- descriptionsUntil (sourceColumn pos) (try (optional blankline >> indentWith indent >> continuation) <|> (([],) <$> end))
672+ (x, (xs, e)) <- descriptionsUntil (sourceColumn pos) (try (optional blankline *> indentWith indent *> continuation) <|> (([],) <$> end))
684 let xx = (,) <$> term <*> sequence x
673 let xx = (,) <$> term <*> sequence x
685 return (xx:xs, e)
674 return (xx:xs, e)
686
675
@@ -736,7 +725,7 @@ museAppendElement element tbl =
736
725
737tableCell :: PandocMonad m => MuseParser m (F Blocks)
726tableCell :: PandocMonad m => MuseParser m (F Blocks)
738tableCell = try $ fmap B.plain . trimInlinesF . mconcat <$> manyTill inline (lookAhead cellEnd)
727tableCell = try $ fmap B.plain . trimInlinesF . mconcat <$> manyTill inline (lookAhead cellEnd)
739− where cellEnd = try $ void (many1 spaceChar >> char '|') <|> eol
728+ where cellEnd = try $ void (many1 spaceChar *> char '|') <|> eol
740
729
741tableElements :: PandocMonad m => MuseParser m (F [MuseTableElement])
730tableElements :: PandocMonad m => MuseParser m (F [MuseTableElement])
742tableElements = sequence <$> (tableParseElement `sepEndBy1` eol)
731tableElements = sequence <$> (tableParseElement `sepEndBy1` eol)
@@ -758,11 +747,10 @@ tableParseElement = tableParseHeader
758tableParseRow :: PandocMonad m
747tableParseRow :: PandocMonad m
759 => Int -- ^ Number of separator characters
748 => Int -- ^ Number of separator characters
760 -> MuseParser m (F [Blocks])
749 -> MuseParser m (F [Blocks])
761−tableParseRow n = try $ do
750+tableParseRow n = try $
762− fields <- tableCell `sepBy2` fieldSep
751+ sequence <$> (tableCell `sepBy2` fieldSep)
763− return $ sequence fields
764− where p `sepBy2` sep = (:) <$> p <*> many1 (sep >> p)
752+ where p `sepBy2` sep = (:) <$> p <*> many1 (sep *> p)
765− fieldSep = many1 spaceChar >> count n (char '|') >> (void (many1 spaceChar) <|> void (lookAhead newline))
753+ fieldSep = many1 spaceChar *> count n (char '|') *> (void (many1 spaceChar) <|> void (lookAhead newline))
766
754
767-- | Parse a table header row.
755-- | Parse a table header row.
768tableParseHeader :: PandocMonad m => MuseParser m (F MuseTableElement)
756tableParseHeader :: PandocMonad m => MuseParser m (F MuseTableElement)
@@ -778,10 +766,10 @@ tableParseFooter = fmap MuseFooterRow <$> tableParseRow 3
778
766
779-- | Parse table caption.
767-- | Parse table caption.
780tableParseCaption :: PandocMonad m => MuseParser m (F MuseTableElement)
768tableParseCaption :: PandocMonad m => MuseParser m (F MuseTableElement)
781−tableParseCaption = try $ do
782− many spaceChar
783− string "|+"
784− fmap MuseCaption <$> (trimInlinesF . mconcat <$> many1Till inline (string "+|"))
769+tableParseCaption = try $ fmap MuseCaption . trimInlinesF . mconcat
770+ <$ many spaceChar
771+ <* string "|+"
772+ <*> many1Till inline (string "+|")
785
773
786-- ** Inline parsers
774-- ** Inline parsers
787
775
@@ -815,10 +803,7 @@ inline = endline <|> choice inlineList <?> "inline"
815
803
816-- | Parse a soft break.
804-- | Parse a soft break.
817endline :: PandocMonad m => MuseParser m (F Inlines)
805endline :: PandocMonad m => MuseParser m (F Inlines)
818−endline = try $ do
819− newline
820− notFollowedBy blankline
806+endline = try $ pure B.softbreak <$ newline <* notFollowedBy blankline
821− return $ return B.softbreak
822
807
823parseAnchor :: PandocMonad m => MuseParser m String
808parseAnchor :: PandocMonad m => MuseParser m String
824parseAnchor = try $ do
809parseAnchor = try $ do
@@ -848,15 +833,11 @@ footnote = try $ do
848 return $ B.note contents'
833 return $ B.note contents'
849
834
850whitespace :: PandocMonad m => MuseParser m (F Inlines)
835whitespace :: PandocMonad m => MuseParser m (F Inlines)
851−whitespace = try $ do
836+whitespace = try $ pure B.space <$ skipMany1 spaceChar
852− skipMany1 spaceChar
853− return $ return B.space
854
837
855-- | Parse @\<br>@ tag.
838-- | Parse @\<br>@ tag.
856br :: PandocMonad m => MuseParser m (F Inlines)
839br :: PandocMonad m => MuseParser m (F Inlines)
857−br = try $ do
858− string "<br>"
859− return $ return B.linebreak
840+br = try $ pure B.linebreak <$ string "<br>"
860
841
861emphasisBetween :: (PandocMonad m, Show a) => MuseParser m a -> MuseParser m (F Inlines)
842emphasisBetween :: (PandocMonad m, Show a) => MuseParser m a -> MuseParser m (F Inlines)
862emphasisBetween c = try $ enclosedInlines c c
843emphasisBetween c = try $ enclosedInlines c c
@@ -867,7 +848,7 @@ enclosed :: (Show end, Stream s m Char) => ParserT s st m t -- ^ start parser
867 -> ParserT s st m a -- ^ content parser (to be used repeatedly)
848 -> ParserT s st m a -- ^ content parser (to be used repeatedly)
868 -> ParserT s st m [a]
849 -> ParserT s st m [a]
869enclosed start end parser = try $
850enclosed start end parser = try $
870− start >> notFollowedBy spaceChar >> many1Till parser end
851+ start *> notFollowedBy spaceChar *> many1Till parser end
871
852
872enclosedInlines :: (PandocMonad m, Show a, Show b)
853enclosedInlines :: (PandocMonad m, Show a, Show b)
873 => MuseParser m a
854 => MuseParser m a
@@ -880,9 +861,9 @@ enclosedInlines start end = try $
880inlineTag :: PandocMonad m
861inlineTag :: PandocMonad m
881 => String -- ^ Tag name
862 => String -- ^ Tag name
882 -> MuseParser m (F Inlines)
863 -> MuseParser m (F Inlines)
883−inlineTag tag = try $ do
864+inlineTag tag = try $ mconcat
884− openTag tag
865+ <$ openTag tag
885− mconcat <$> manyTill inline (closeTag tag)
866+ <*> manyTill inline (closeTag tag)
886
867
887-- | Parse strong inline markup, indicated by @**@.
868-- | Parse strong inline markup, indicated by @**@.
888strong :: PandocMonad m => MuseParser m (F Inlines)
869strong :: PandocMonad m => MuseParser m (F Inlines)
@@ -933,9 +914,7 @@ classTag = do
933
914
934-- | Parse "~~" as nonbreaking space.
915-- | Parse "~~" as nonbreaking space.
935nbsp :: PandocMonad m => MuseParser m (F Inlines)
916nbsp :: PandocMonad m => MuseParser m (F Inlines)
936−nbsp = try $ do
917+nbsp = try $ pure (B.str "\160") <$ string "~~"
937− string "~~"
938− return $ return $ B.str "\160"
939
918
940-- | Parse code markup, indicated by @\'=\'@ characters.
919-- | Parse code markup, indicated by @\'=\'@ characters.
941code :: PandocMonad m => MuseParser m (F Inlines)
920code :: PandocMonad m => MuseParser m (F Inlines)
@@ -983,7 +962,9 @@ linkOrImage = try $ do
983 return res
962 return res
984
963
985linkContent :: PandocMonad m => MuseParser m (F Inlines)
964linkContent :: PandocMonad m => MuseParser m (F Inlines)
986−linkContent = char '[' >> trimInlinesF . mconcat <$> manyTill inline (char ']')
965+linkContent = trimInlinesF . mconcat
966+ <$ char '['
967+ <*> manyTill inline (char ']')
987
968
988-- | Parse a link starting with @URL:@
969-- | Parse a link starting with @URL:@
989explicitLink :: PandocMonad m => MuseParser m (F Inlines)
970explicitLink :: PandocMonad m => MuseParser m (F Inlines)
@@ -1016,12 +997,11 @@ image = try $ do
1016 ext <- imageExtension
997 ext <- imageExtension
1017 (width, align) <- option (Nothing, Nothing) imageAttrs
998 (width, align) <- option (Nothing, Nothing) imageAttrs
1018 return (ext, width, align)
999 return (ext, width, align)
1019− imageAttrs = do
1000+ imageAttrs = (,)
1020− many1 spaceChar
1001+ <$ many1 spaceChar
1021− width <- optionMaybe (many1 digit)
1002+ <*> optionMaybe (many1 digit)
1022− many spaceChar
1003+ <* many spaceChar
1023− align <- optionMaybe (oneOf "rlf")
1004+ <*> optionMaybe (oneOf "rlf")
1024− return (width, align)
1025
1005
1026link :: PandocMonad m => MuseParser m (F Inlines)
1006link :: PandocMonad m => MuseParser m (F Inlines)
1027link = try $ do
1007link = try $ do