LaTeX: Handle formatted text inside code inline (#8129)

Add `formatCode` function to Text.Pandoc.Shared [API change].

Use this in the LaTeX reader so that e.g.
`\texttt{\textbf{bold code}}` is parsed as `Strong [Code ("",[],[]) "bold code"]`.
This commit is contained in:
Elliot Bobrow 2022-06-20 12:18:05 -07:00 committed by GitHub
parent a21d6e9fa6
commit f317ec41a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 8 deletions

View file

@ -347,7 +347,7 @@ inlineCommands = M.unions
, ("textmd", extractSpaces (spanWith ("",["medium"],[])) <$> tok)
, ("textrm", extractSpaces (spanWith ("",["roman"],[])) <$> tok)
, ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
, ("texttt", ttfamily)
, ("texttt", formatCode nullAttr <$> tok)
, ("sout", extractSpaces strikeout <$> tok)
, ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
, ("textsuperscript", extractSpaces superscript <$> tok)
@ -368,7 +368,7 @@ inlineCommands = M.unions
, ("it", extractSpaces emph <$> inlines)
, ("sl", extractSpaces emph <$> inlines)
, ("bf", extractSpaces strong <$> inlines)
, ("tt", code . stringify . toList <$> inlines)
, ("tt", formatCode nullAttr <$> inlines)
, ("rm", inlines)
, ("itshape", extractSpaces emph <$> inlines)
, ("slshape", extractSpaces emph <$> inlines)
@ -407,8 +407,8 @@ inlineCommands = M.unions
, ("hypertarget", hypertargetInline)
-- hyphenat
, ("nohyphens", tok)
, ("textnhtt", ttfamily)
, ("nhttfamily", ttfamily)
, ("textnhtt", formatCode nullAttr <$> tok)
, ("nhttfamily", formatCode nullAttr <$> tok)
-- LaTeX colors
, ("textcolor", coloredInline "color")
, ("colorbox", coloredInline "background-color")
@ -547,9 +547,6 @@ coloredInline stylename = do
color <- braced
spanWith ("",[],[("style",stylename <> ": " <> untokenize color)]) <$> tok
ttfamily :: PandocMonad m => LP m Inlines
ttfamily = code . stringify . toList <$> tok
processHBox :: Inlines -> Inlines
processHBox = walk convert
where

View file

@ -70,6 +70,7 @@ module Text.Pandoc.Shared (
eastAsianLineBreakFilter,
htmlSpanLikeElements,
filterIpynbOutput,
formatCode,
-- * TagSoup HTML handling
renderTags',
-- * File handling
@ -106,7 +107,7 @@ import Data.Char (isAlpha, isLower, isSpace, isUpper, toLower, isAlphaNum,
generalCategory, GeneralCategory(NonSpacingMark,
SpacingCombiningMark, EnclosingMark, ConnectorPunctuation))
import Data.Containers.ListUtils (nubOrd)
import Data.List (find, intercalate, intersperse, sortOn, foldl')
import Data.List (find, intercalate, intersperse, sortOn, foldl', groupBy)
import qualified Data.Map as M
import Data.Maybe (mapMaybe, fromMaybe)
import Data.Monoid (Any (..))
@ -779,6 +780,26 @@ filterIpynbOutput mode = walk go
| otherwise = ""
go x = x
-- | Reformat 'Inlines' as code, putting the stringlike parts in 'Code'
-- elements while bringing other inline formatting outside.
-- The idea is that e.g. `[Str "a",Space,Strong [Str "b"]]` should turn
-- into `[Code ("",[],[]) "a ", Strong [Code ("",[],[]) "b"]]`.
-- This helps work around the limitation that pandoc's Code element can
-- only contain string content (see issue #7525).
formatCode :: Attr -> Inlines -> Inlines
formatCode attr = B.fromList . walk fmt . B.toList
where
isPlaintext (Str _) = True
isPlaintext Space = True
isPlaintext SoftBreak = True
isPlaintext (Quoted _ _) = True
isPlaintext _ = False
fmt = concatMap go . groupBy (\a b -> isPlaintext a && isPlaintext b)
where
go xs
| all isPlaintext xs = B.toList $ B.codeWith attr $ stringify xs
| otherwise = xs
--
-- TagSoup HTML handling
--

19
test/command/7525.md Normal file
View file

@ -0,0 +1,19 @@
```
% pandoc -f latex -t native
\texttt{Normal code. \emph{Emph and code.} \textsc{\textbf{Bold small caps.}} \sout{Strikeout. \underline{Strikeout and underline.}}}
^D
[ Para
[ Code ( "" , [] , [] ) "Normal code. "
, Emph [ Code ( "" , [] , [] ) "Emph and code." ]
, Code ( "" , [] , [] ) " "
, SmallCaps
[ Strong [ Code ( "" , [] , [] ) "Bold small caps." ] ]
, Code ( "" , [] , [] ) " "
, Strikeout
[ Code ( "" , [] , [] ) "Strikeout. "
, Underline
[ Code ( "" , [] , [] ) "Strikeout and underline." ]
]
]
]
```