LaTeX writer: Protect VERB in caption (#11139)

Also apply hlint suggestions for fewer imports and
moving brackets to avoid $.
This commit is contained in:
TuongNM
2025-09-15 10:28:57 +02:00
committed by GitHub
parent 4be17f77b7
commit e2f088f4e5
4 changed files with 96 additions and 5 deletions
+11 -4
View File
@@ -32,7 +32,7 @@ import Control.Monad
unless )
import Crypto.Hash (hashWith, MD5(MD5))
import Data.Containers.ListUtils (nubOrd)
import Data.Char (isDigit, isAscii)
import Data.Char (isDigit, isAscii, isLetter)
import Data.List (intersperse, (\\))
import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing)
import Data.Monoid (Any (..))
@@ -68,7 +68,6 @@ import Text.Pandoc.Writers.Shared
import qualified Data.Attoparsec.Text as A
import qualified Text.Pandoc.UTF8 as UTF8
import qualified Text.Pandoc.Writers.AnnotatedTable as Ann
import Data.Char (isLetter)
import Control.Applicative ((<|>))
-- Work around problems with notes inside emphasis (see #8982)
@@ -677,7 +676,7 @@ blockToLaTeX (Figure (ident, _, kvs) captnode body) = do
, stSubfigure = stSubfigure st || isSubfigure
}
let containsTable = getAny . (query $ \case
let containsTable = getAny . query (\case
Table {} -> Any True
_ -> Any False)
st <- get
@@ -948,6 +947,7 @@ inlineToLaTeX (Code (_,classes,kvs) str) = do
inHeading <- gets stInHeading
inItem <- gets stInItem
inSoul <- gets stInSoulCommand
inCaption <- gets stInCaption
let listingsCode = do
let listingsopts = (case getListingsLanguage classes of
Just l -> (("language", mbBraced l):)
@@ -1000,7 +1000,14 @@ inlineToLaTeX (Code (_,classes,kvs) str) = do
-- (see #1294). with regular texttt we don't get an error, but we get
-- incorrect results if there is a space (see #5529).
let inMbox x = "\\mbox" <> braces x
(if inSoul then inMbox else id) <$>
-- for captions we need to protect VERB with \protect (see #6821)
let protect x = "\\protect" <> x
let optionalProtect = case () of _ | inSoul -> inMbox
| inCaption -> protect
| otherwise -> id
optionalProtect <$>
case writerHighlightMethod opts of
_ | inHeading || inItem -> rawCode -- see #5574
IdiomaticHighlighting -> listingsCode
+3 -1
View File
@@ -23,7 +23,7 @@ import Text.Pandoc.Shared
import Text.Pandoc.Walk
import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
import Text.Pandoc.Writers.LaTeX.Types
( LW, WriterState (stExternalNotes, stNotes) )
( LW, WriterState (stExternalNotes, stNotes, stInCaption) )
-- | Produces the components of a LaTeX 'caption' command. Returns a triple
@@ -35,6 +35,7 @@ getCaption :: PandocMonad m
-> Caption
-> LW m (Doc Text, Doc Text, Doc Text)
getCaption inlineListToLaTeX externalNotes (Caption maybeShort long) = do
modify $ \st -> st{ stInCaption = True }
let long' = blocksToInlines long
oldExternalNotes <- gets stExternalNotes
modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }
@@ -53,4 +54,5 @@ getCaption inlineListToLaTeX externalNotes (Caption maybeShort long) = do
then toShortCapt long'
else return empty
Just short -> toShortCapt short
modify $ \st -> st{ stInCaption = False }
return (capt, captForLof, footnotes)
+2
View File
@@ -54,6 +54,7 @@ data WriterState =
, stLang :: Maybe Lang -- ^ lang specified in metadata
, stInSoulCommand :: Bool -- ^ in a soul command like ul
, stCancel :: Bool -- ^ true if document uses \cancel
, stInCaption :: Bool -- ^ true if in a caption
}
startingState :: WriterOptions -> WriterState
@@ -95,4 +96,5 @@ startingState options =
, stLang = Nothing
, stInSoulCommand = False
, stCancel = False
, stInCaption = False
}
+80
View File
@@ -0,0 +1,80 @@
```
% pandoc -f native -t latex
[ Para [ Code ( "" , [ "python" ] , [] ) "x = 5" ]
, Figure
( "" , [] , [] )
(Caption
Nothing
[ Plain
[ Str "This"
, Space
, Str "is"
, Space
, Str "a"
, Space
, Str "test"
, Space
, Code ( "" , [ "python" ] , [] ) "x = 5"
]
])
[ Plain
[ Image
( "" , [] , [] )
[ Str "This"
, Space
, Str "is"
, Space
, Str "a"
, Space
, Str "test"
, Space
, Code ( "" , [ "python" ] , [] ) "x = 5"
]
( "test.png" , "" )
]
]
, Table
( "" , [] , [] )
(Caption
Nothing
[ Plain [ Code ( "" , [ "cpp" ] , [] ) "caption" ] ])
[ ( AlignDefault , ColWidthDefault ) ]
(TableHead ( "" , [] , [] ) [])
[ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]
(TableFoot
( "" , [] , [] )
[ Row
( "" , [] , [] )
[ Cell
( "" , [] , [] )
AlignDefault
(RowSpan 1)
(ColSpan 1)
[ Plain [ Str "A" ] ]
]
])
, Para [ Code ( "" , [ "cpp" ] , [] ) "caption" ]
]
^D
\VERB|\NormalTok{x }\OperatorTok{=} \DecValTok{5}|
\begin{figure}
\centering
\pandocbounded{\includegraphics[keepaspectratio,alt={This is a test x = 5}]{test.png}}
\caption{This is a test
\protect\VERB|\NormalTok{x }\OperatorTok{=} \DecValTok{5}|}
\end{figure}
\begin{longtable}[]{@{}l@{}}
\caption{\protect\VERB|\NormalTok{caption}|}\tabularnewline
\toprule\noalign{}
\endfirsthead
\endhead
\midrule\noalign{}
A \\
\bottomrule\noalign{}
\endlastfoot
\end{longtable}
\VERB|\NormalTok{caption}|
```