summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2024-01-25 09:41:47 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2024-01-25 09:41:47 -0800
commitd9a70d2eaf30a3fe4836f8b69a0c32181d84bd00 (patch)
tree9de745c5e675179c48c95f70c4c1a7e8b14da4bc
parent23f67c8458ea9a052dca9ed7a49151ea677d09dc (diff)
Add some kerns where needed between quotes in LaTeX output.
Closes #9371.
-rw-r--r--src/Text/Pandoc/Writers/LaTeX.hs44
-rw-r--r--test/command/9371.md30
2 files changed, 62 insertions, 12 deletions
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
index 943f50ef9..4426c8da1 100644
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -775,7 +775,8 @@ inlineListToLaTeX :: PandocMonad m
=> [Inline] -- ^ Inlines to convert
-> LW m (Doc Text)
inlineListToLaTeX lst = hcat <$>
- mapM inlineToLaTeX (fixLineInitialSpaces . fixInitialLineBreaks $ lst)
+ mapM inlineToLaTeX
+ (addKerns . fixLineInitialSpaces . fixInitialLineBreaks $ lst)
-- nonbreaking spaces (~) in LaTeX don't work after line breaks,
-- so we insert a strut: this is mostly used in verse.
where fixLineInitialSpaces [] = []
@@ -790,6 +791,21 @@ inlineListToLaTeX lst = hcat <$>
RawInline (Format "latex") "\\hfill\\break\n" :
fixInitialLineBreaks xs
fixInitialLineBreaks xs = xs
+ addKerns [] = []
+ addKerns (Str s : q@Quoted{} : rest)
+ | isQuote (T.takeEnd 1 s) =
+ Str s : RawInline (Format "latex") "\\," : addKerns (q:rest)
+ addKerns (q@Quoted{} : Str s : rest)
+ | isQuote (T.take 1 s) =
+ q : RawInline (Format "latex") "\\," : addKerns (Str s : rest)
+ addKerns (x:xs) = x : addKerns xs
+ isQuote "\"" = True
+ isQuote "'" = True
+ isQuote "\x2018" = True
+ isQuote "\x2019" = True
+ isQuote "\x201C" = True
+ isQuote "\x201D" = True
+ isQuote _ = False
-- | Convert inline element to LaTeX
inlineToLaTeX :: PandocMonad m
@@ -928,13 +944,21 @@ inlineToLaTeX (Quoted qt lst) = do
DoubleQuote -> "\\enquote" <> braces contents
SingleQuote -> "\\enquote*" <> braces contents
else do
- let s1 = if not (null lst) && isQuoted (head lst)
- then "\\,"
- else empty
- let s2 = if not (null lst) && isQuoted (last lst)
- then "\\,"
- else empty
- let inner = s1 <> contents <> s2
+ let endsWithQuote xs =
+ case reverse xs of
+ Quoted{}:_ -> True
+ Span _ ys : _ -> endsWithQuote ys
+ Str s:_ -> T.takeEnd 1 s == "'"
+ _ -> False
+ let beginsWithQuote xs =
+ case xs of
+ Quoted{}:_ -> True
+ Span _ ys : _ -> beginsWithQuote ys
+ Str s:_ -> T.take 1 s == "`"
+ _ -> False
+ let inner = (if beginsWithQuote lst then "\\," else mempty)
+ <> contents
+ <> (if endsWithQuote lst then "\\," else mempty)
return $ case qt of
DoubleQuote ->
if isEnabled Ext_smart opts
@@ -944,10 +968,6 @@ inlineToLaTeX (Quoted qt lst) = do
if isEnabled Ext_smart opts
then char '`' <> inner <> char '\''
else char '\x2018' <> inner <> char '\x2019'
- where
- isQuoted (Span _ (x:_)) = isQuoted x
- isQuoted (Quoted _ _) = True
- isQuoted _ = False
inlineToLaTeX (Str str) = do
setEmptyLine False
liftM literal $ stringToLaTeX TextString str
diff --git a/test/command/9371.md b/test/command/9371.md
new file mode 100644
index 000000000..bb34f87a6
--- /dev/null
+++ b/test/command/9371.md
@@ -0,0 +1,30 @@
+```
+% pandoc -t latex
+"'In this case (A),
+
+I get a kern to separate the quotes,' he said."
+
+"'Also in this case (B), I get a kern,' he added."
+
+"'But in this case (C), there is no kern,'
+
+he continued."
+
+"He concluded,
+
+'Nor in this case (D) is there a kern.'"
+^D
+``\,'In this case (A),
+
+I get a kern to separate the quotes,' he said.''
+
+``\,`Also in this case (B), I get a kern,' he added.''
+
+``\,`But in this case (C), there is no kern,'
+
+he continued.''
+
+``He concluded,
+
+`Nor in this case (D) is there a kern.'\,''
+```