Skip to content

Commit

Permalink
Handle close delimiters on line enclosures
Browse files Browse the repository at this point in the history
One-line enclosures need a little bit of state so that we don't parse
the closing delimiters that follow nested one-line or multiline
enclosures; the closing delimiters are meant to go after the close of
the outermost enclosure.

While we're here, ensure lineEnclosure consumes an eol, which saves us
from some extra eol bookkeeping when we use lineEnclosure in block
contexts.
  • Loading branch information
silby committed Nov 4, 2024
1 parent 4918b69 commit c1071f7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/Text/Pandoc/Readers/Mdoc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ data MdocState = MdocState
, tableCellsPlain :: Bool
, spacingMode :: Bool
, authorNameSplit :: Bool
, inLineEnclosure :: Bool
, progName :: Maybe T.Text
, currentSection :: MdocSection
, currentReference :: MdocReference
Expand All @@ -110,6 +111,7 @@ instance Default MdocState where
, tableCellsPlain = True
, spacingMode = True
, authorNameSplit = False
, inLineEnclosure = False
, currentSection = ShOther
, currentReference = M.empty
, progName = Nothing
Expand Down Expand Up @@ -268,7 +270,6 @@ parseHeader :: PandocMonad m => MdocParser m Blocks
parseHeader = do
(Macro m _) <- lookAhead $ macro "Sh" <|> macro "Ss"
txt <- lineEnclosure m id
eol
let lvl = if m == "Sh" then 1 else 2
when (lvl == 1) $ modifyState $ \s -> s{currentSection = (shToSectionMode . stringify) txt}
return $ B.header lvl txt
Expand Down Expand Up @@ -403,14 +404,20 @@ spanLikeInline nm = simpleInline nm (eliminateEmpty (B.spanWith (cls nm)))
lineEnclosure :: PandocMonad m => T.Text -> (Inlines -> Inlines) -> MdocParser m Inlines
lineEnclosure nm xform = do
macro nm
amNested <- inLineEnclosure <$> getState
trace $ nm <> " nested? " <> tshow amNested
modifyState $ \s -> s{inLineEnclosure = True}
--- XXX wtf
(first, further, finally) <- delimitedArgs
first <- openingDelimiters
further <-
(manyTill
(parseInlineMacro
<|> (try (litsAndDelimsToInlines <* notFollowedBy eol))
<|> litsToInlines)
(try (lookAhead (many (macro "Ns" <|> delim Close) *> eol))))
further' <- spacify further
finally <- if amNested then mempty else closingDelimiters <* optional eol
modifyState $ \s -> s{inLineEnclosure = amNested}
return $ first <> xform further' <> finally

noSpace :: Inlines
Expand Down Expand Up @@ -469,12 +476,15 @@ but pandoc inlines inside of these multiline enclosures. -}
multilineEnclosure :: PandocMonad m => T.Text -> T.Text -> (Inlines -> Inlines) -> MdocParser m Inlines
multilineEnclosure op cl xform = do
macro op
amNested <- inLineEnclosure <$> getState
openDelim <- mconcat <$> many (parseDelim Open)
optional eol
contents <- many parseInline
(macro cl <?> show cl)
closeDelim <- mconcat <$> many (parseDelim Close)
optional eol
closeDelim <-
if amNested
then mempty
else mconcat <$> many (parseDelim Close) <* optional eol
contents' <- spacify contents
return $ openDelim <> xform contents' <> closeDelim

Expand Down Expand Up @@ -654,13 +664,11 @@ parseAo = multilineEnclosure "Ao" "Ac" $ \x -> "⟨" <> x <> "⟩"
parseDl :: PandocMonad m => MdocParser m Blocks
parseDl = do
inner <- lineEnclosure "Dl" id
eol
return $ B.codeBlock (stringify inner)

parseD1 :: PandocMonad m => MdocParser m Blocks
parseD1 = do
inner <- lineEnclosure "D1" id
eol
return $ B.divWith (cls "display") $ B.plain inner

parseNm :: PandocMonad m => MdocParser m Inlines
Expand Down
9 changes: 9 additions & 0 deletions test/Tests/Readers/Mdoc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ tests = [
, "nested" =:
".Dq Pq hello world" =?>
para (doubleQuoted "(hello world)")
, "nested with closing delimiters" =:
".Dq Pq hi mom !" =?>
para (doubleQuoted "(hi mom)" <> "!")
, "nested multiline enclosure" =:
".Dq Po a \\&; b \\&; c Pc ." =?>
para (doubleQuoted "(a ; b ; c)" <> ".")
, "with inlines" =:
".Dq hello Sy world ." =?>
para (doubleQuoted ("hello" <> space <> strong "world" <> "."))
Expand All @@ -65,6 +71,9 @@ tests = [
, "nested on one line" =:
".Bo Po hi Pc Bc" =?>
para ("[(hi)]")
, "with wacky delimiters" =:
".Bo ( | hi ! Bc ?" =?>
para ("([| hi!]?")
]
, testGroup "simple inlines"
[ "Sy" =:
Expand Down

0 comments on commit c1071f7

Please sign in to comment.