@@ -35,7 +35,8 @@ import Text.Pandoc.Shared
3535import Text.Pandoc.Templates
3636import Text.Printf ( printf )
3737import Network.URI ( isAbsoluteURI, unEscapeString )
38−import Data.List ( (\\), isSuffixOf, isPrefixOf, intercalate, intersperse )
38+import Data.List ( (\\), isSuffixOf, isInfixOf,
39+ isPrefixOf, intercalate, intersperse )
3940import Data.Char ( toLower, isPunctuation )
4041import Control.Monad.State
4142import Text.Pandoc.Pretty
@@ -57,6 +58,7 @@ data WriterState =
5758 , stGraphics :: Bool -- true if document contains images
5859 , stLHS :: Bool -- true if document has literate haskell code
5960 , stBook :: Bool -- true if document uses book or memoir class
61+ , stCsquotes :: Bool -- true if document uses csquotes
6062 }
6163
6264-- | Convert Pandoc to LaTeX.
@@ -68,7 +70,8 @@ writeLaTeX options document =
6870 stVerbInNote = False, stEnumerate = False,
6971 stTable = False, stStrikeout = False, stSubscript = False,
7072 stUrl = False, stGraphics = False,
71− stLHS = False, stBook = writerChapters options }
73+ stLHS = False, stBook = writerChapters options,
74+ stCsquotes = False }
7275
7376pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String
7477pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
@@ -78,6 +81,10 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
7881 "{report}" `isSuffixOf` x)
7982 when (any usesBookClass (lines template)) $
8083 modify $ \s -> s{stBook = True}
84+ -- check for \usepackage...{csquotes}; if present, we'll use
85+ -- \enquote{...} for smart quotes:
86+ when ("{csquotes}" `isInfixOf` template) $
87+ modify $ \s -> s{stCsquotes = True}
8188 opts <- liftM stOptions get
8289 let colwidth = if writerWrapText opts
8390 then Just $ writerColumns opts
@@ -380,22 +387,30 @@ inlineToLaTeX (Code _ str) = do
380387 else return $ text $ "\\texttt{" ++ stringToLaTeX str ++ "}"
381388inlineToLaTeX (Quoted SingleQuote lst) = do
382389 contents <- inlineListToLaTeX lst
383− let s1 = if (not (null lst)) && (isQuoted (head lst))
384− then "\\,"
385− else empty
386− let s2 = if (not (null lst)) && (isQuoted (last lst))
387− then "\\,"
388− else empty
389− return $ char '`' <> s1 <> contents <> s2 <> char '\''
390+ csquotes <- liftM stCsquotes get
391+ if csquotes
392+ then return $ "\\enquote" <> braces contents
393+ else do
394+ let s1 = if (not (null lst)) && (isQuoted (head lst))
395+ then "\\,"
396+ else empty
397+ let s2 = if (not (null lst)) && (isQuoted (last lst))
398+ then "\\,"
399+ else empty
400+ return $ char '`' <> s1 <> contents <> s2 <> char '\''
390401inlineToLaTeX (Quoted DoubleQuote lst) = do
391402 contents <- inlineListToLaTeX lst
392− let s1 = if (not (null lst)) && (isQuoted (head lst))
393− then "\\,"
394− else empty
395− let s2 = if (not (null lst)) && (isQuoted (last lst))
396− then "\\,"
397− else empty
398− return $ "``" <> s1 <> contents <> s2 <> "''"
403+ csquotes <- liftM stCsquotes get
404+ if csquotes
405+ then return $ "\\enquote" <> braces contents
406+ else do
407+ let s1 = if (not (null lst)) && (isQuoted (head lst))
408+ then "\\,"
409+ else empty
410+ let s2 = if (not (null lst)) && (isQuoted (last lst))
411+ then "\\,"
412+ else empty
413+ return $ "``" <> s1 <> contents <> s2 <> "''"
399414inlineToLaTeX Apostrophe = return $ char '\''
400415inlineToLaTeX EmDash = return "---"
401416inlineToLaTeX EnDash = return "--"