git.iko.soy/typeable/pandoc
on master help sign in
LaTeX writer: Fix problem with escaping in lstinline.

Previously the LaTeX writer created invalid LaTeX when `--listings` was specified and a code span occured inside emphasis or another construction. This is because the characters `%{}\` must be escaped in lstinline when the listinline occurs in another command, otherwise they must not be escaped. To deal with this, adoping Michael Kofler's suggestion, we always wrap lstinline in a dummy command `\passthrough`, now defined in the default template if `--listings` is specified. This way we can consistently escape the special characters. Closes #1629.

commit730796ee314d42477fab216621b8e44539c94656 authorJohn MacFarlane <jgm@berkeley.edu> dateSat 29 Apr 2017, 11:05 (9 years ago) parente76b672
6 files changed+20−2
data/templates/default.beamer+1 data/templates/default.latex+1 src/Text/Pandoc/Writers/LaTeX.hs+6−1 test/command/1629.md+10 test/command/3422.md+1−1 test/lhs-test.latex+lhs+1
data/templates/default.beamer+1
@@ -125,6 +125,7 @@ $if(verbatim-in-note)$
125125$endif$
126126$if(listings)$
127127\usepackage{listings}
128+\newcommand{\passthrough}[1]{#1}
128129$endif$
129130$if(lhs)$
130131\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
data/templates/default.latex+1
@@ -129,6 +129,7 @@ $endfor$
129129$endif$
130130$if(listings)$
131131\usepackage{listings}
132+\newcommand{\passthrough}[1]{#1}
132133$endif$
133134$if(lhs)$
134135\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
src/Text/Pandoc/Writers/LaTeX.hs+6−1
@@ -967,7 +967,12 @@ inlineToLaTeX (Code (_,classes,_) str) = do
967967 let chr = case "!\"&'()*,-./:;?@_" \\ str of
968968 (c:_) -> c
969969 [] -> '!'
970− return $ text $ "\\lstinline" ++ listingsopt ++ [chr] ++ str ++ [chr]
970+ let str' = escapeStringUsing (backslashEscapes "\\{}%") str
971+ -- we always put lstinline in a dummy 'passthrough' command
972+ -- (defined in the default template) so that we don't have
973+ -- to change the way we escape characters depending on whether
974+ -- the lstinline is inside another command. See #1629:
975+ return $ text $ "\\passthrough{\\lstinline" ++ listingsopt ++ [chr] ++ str' ++ [chr] ++ "}"
971976 let rawCode = liftM (text . (\s -> "\\texttt{" ++ escapeSpaces s ++ "}"))
972977 $ stringToLaTeX CodeString str
973978 where escapeSpaces = concatMap
test/command/1629.mdnew file+10
@@ -0,0 +1,10 @@
1+```
2+% pandoc -t latex --listings
3+bla bla `a % b`
4+
5+*bla bla `a % b`*
6+^D
7+bla bla \passthrough{\lstinline!a \% b!}
8+
9+\emph{bla bla \passthrough{\lstinline!a \% b!}}
10+```
test/command/3422.md+1−1
@@ -4,6 +4,6 @@ See #3422
44% pandoc -t latex --listings
55`int main(int argc, const char *argv[]);`{.c}
66^D
7−\lstinline[language=C]!int main(int argc, const char *argv[]);!
7+\passthrough{\lstinline[language=C]!int main(int argc, const char *argv[]);!}
88```
99
test/lhs-test.latex+lhs+1
@@ -24,6 +24,7 @@
2424 breaklinks=true}
2525\urlstyle{same} % don't use monospace font for urls
2626\usepackage{listings}
27+\newcommand{\passthrough}[1]{#1}
2728\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
2829\IfFileExists{parskip.sty}{%
2930\usepackage{parskip}