aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <[email protected]>2025-05-08 11:14:34 -0700
committerJohn MacFarlane <[email protected]>2025-05-08 11:19:54 -0700
commit60b4011902d202e25b22542127f10f180c27d87d (patch)
treeca59e0720b57565bada373c42a52ed1c65fe89c9
parent6a1679921bd630cfdfb85517303ab92293a222b8 (diff)
DocBook reader: improve handling of literallayout.
This is now only made a CodeBlock when there is a `monospaced` class. Otherwise it is made a LineBlock. Closes #10825.
-rw-r--r--src/Text/Pandoc/Readers/DocBook.hs37
-rw-r--r--test/command/10825.md39
2 files changed, 68 insertions, 8 deletions
diff --git a/src/Text/Pandoc/Readers/DocBook.hs b/src/Text/Pandoc/Readers/DocBook.hs
index 7910ef25a..c84064f4b 100644
--- a/src/Text/Pandoc/Readers/DocBook.hs
+++ b/src/Text/Pandoc/Readers/DocBook.hs
@@ -25,6 +25,7 @@ import Data.ByteString (ByteString)
import Data.FileEmbed
import Data.Char (isSpace, isLetter, chr)
import Data.Default
+import Data.List.Split (splitWhen)
import Data.Either (rights)
import Data.Foldable (asum)
import Data.Generics
@@ -539,11 +540,12 @@ List of all DocBook tags, with [x] indicating implemented,
type DB m = StateT DBState m
-data DBState = DBState{ dbSectionLevel :: Int
- , dbQuoteType :: QuoteType
- , dbMeta :: Meta
- , dbBook :: Bool
- , dbContent :: [Content]
+data DBState = DBState{ dbSectionLevel :: Int
+ , dbQuoteType :: QuoteType
+ , dbMeta :: Meta
+ , dbBook :: Bool
+ , dbContent :: [Content]
+ , dbLiteralLayout :: Bool
} deriving Show
instance Default DBState where
@@ -551,7 +553,8 @@ instance Default DBState where
, dbQuoteType = DoubleQuote
, dbMeta = mempty
, dbBook = False
- , dbContent = [] }
+ , dbContent = []
+ , dbLiteralLayout = False }
readDocBook :: (PandocMonad m, ToSources a)
@@ -966,7 +969,7 @@ parseBlock (Elem e) =
"informalexample" -> divWith ("", ["informalexample"], []) <$>
getBlocks e
"linegroup" -> lineBlock <$> lineItems
- "literallayout" -> codeBlockWithLang
+ "literallayout" -> literalLayout
"screen" -> codeBlockWithLang
"programlisting" -> codeBlockWithLang
"?xml" -> return mempty
@@ -990,6 +993,17 @@ parseBlock (Elem e) =
then map (fmap paraToPlain)
else id
+ literalLayout
+ | "monospaced" `elem` (T.words (attrValue "class" e))
+ = codeBlockWithLang
+ | otherwise = do
+ oldLiteralLayout <- gets dbLiteralLayout
+ modify $ \st -> st{ dbLiteralLayout = True }
+ content <- mconcat <$> mapM parseInline (elContent e)
+ let ls = map fromList . splitWhen (== LineBreak) . toList $ content
+ modify $ \st -> st{ dbLiteralLayout = oldLiteralLayout }
+ return $ lineBlock ls
+
codeBlockWithLang = do
let classes' = case attrValue "language" e of
"" -> []
@@ -1203,7 +1217,14 @@ attrValueAsOptionalAttr n e = case attrValue n e of
_ -> Just (n, attrValue n e)
parseInline :: PandocMonad m => Content -> DB m Inlines
-parseInline (Text (CData _ s _)) = return $ text s
+parseInline (Text (CData _ s _)) = do
+ literalLayout <- gets dbLiteralLayout
+ if literalLayout
+ then do
+ let ls = T.splitOn "\n" s
+ let toLiteralLine = str . T.map (\c -> if c == ' ' then '\xa0' else c)
+ return $ mconcat $ intersperse linebreak $ map toLiteralLine ls
+ else return $ text s
parseInline (CRef ref) =
return $ text $ fromMaybe (T.toUpper ref) $ lookupEntity ref
parseInline (Elem e) =
diff --git a/test/command/10825.md b/test/command/10825.md
new file mode 100644
index 000000000..90124aa2e
--- /dev/null
+++ b/test/command/10825.md
@@ -0,0 +1,39 @@
+```
+% pandoc -f docbook -t html
+<?xml version="1.0" encoding="utf-8"?>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0">
+ <info><title>Literallayout test</title></info>
+ <chapter>
+ <info><title>Literallayout without class</title></info>
+ <literallayout>First line.
+Second line.
+ Third line, indented two spaces.</literallayout>
+ </chapter>
+ <chapter>
+ <info><title>Literallayout with normal class</title></info>
+ <literallayout class="normal">First line.
+Second line.
+ Third line, indented two spaces.</literallayout>
+ </chapter>
+ <chapter>
+ <info><title>Literallayout with monospaced</title></info>
+ <literallayout class="monospaced">First line.
+Second line.
+ Third line, indented two spaces.</literallayout>
+ </chapter>
+</book>
+^D
+<h1>Literallayout without class</h1>
+<div class="line-block">First line.<br />
+Second line.<br />
+  Third line, indented two spaces.</div>
+<h1>Literallayout with normal class</h1>
+<div class="line-block">First line.<br />
+Second line.<br />
+  Third line, indented two spaces.</div>
+<h1>Literallayout with monospaced</h1>
+<pre><code>First line.
+Second line.
+ Third line, indented two spaces.</code></pre>
+
+```