@@ -39,8 +39,8 @@ import Prelude
39import Control.Applicative ((<|>))
39import Control.Applicative ((<|>))
40import Control.Monad.State.Strict
40import Control.Monad.State.Strict
41import Data.Aeson (FromJSON, object, (.=))
41import Data.Aeson (FromJSON, object, (.=))
42−import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isPunctuation, ord,
42+import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isSpace,
43− toLower)
43+ isPunctuation, ord, toLower)
44import Data.List (foldl', intercalate, intersperse, isInfixOf, nubBy,
44import Data.List (foldl', intercalate, intersperse, isInfixOf, nubBy,
45 stripPrefix, (\\), uncons)
45 stripPrefix, (\\), uncons)
46import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing)
46import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing)
@@ -345,10 +345,20 @@ stringToLaTeX context zs = do
345 Just cmd -> ((cmd ++ "{" ++ [c] ++ "}") ++)
345 Just cmd -> ((cmd ++ "{" ++ [c] ++ "}") ++)
346 <$> go opts ctx (drop 1 xs) -- drop combining accent
346 <$> go opts ctx (drop 1 xs) -- drop combining accent
347 Nothing -> (c:) <$> go opts ctx xs
347 Nothing -> (c:) <$> go opts ctx xs
348+ let emitcseq cs = do
349+ rest <- go opts ctx xs
353+ -> return (cs <> " " <> rest)
354+ | isSpace c -> return (cs <> "{}" <> rest)
356+ -> return (cs <> rest)
357+ _ -> return (cs <> "{}" <> rest)
348 case x of
358 case x of
349 '{' -> emits "\\{"
359 '{' -> emits "\\{"
350 '}' -> emits "\\}"
360 '}' -> emits "\\}"
351− '`' | ctx == CodeString -> emits "\\textasciigrave{}"
361+ '`' | ctx == CodeString -> emitcseq "\\textasciigrave"
352 '$' | not isUrl -> emits "\\$"
362 '$' | not isUrl -> emits "\\$"
353 '%' -> emits "\\%"
363 '%' -> emits "\\%"
354 '&' -> emits "\\&"
364 '&' -> emits "\\&"
@@ -358,19 +368,19 @@ stringToLaTeX context zs = do
358 -- prevent adjacent hyphens from forming ligatures
368 -- prevent adjacent hyphens from forming ligatures
359 ('-':_) -> emits "-\\/"
369 ('-':_) -> emits "-\\/"
360 _ -> emitc '-'
370 _ -> emitc '-'
361− '~' | not isUrl -> emits "\\textasciitilde{}"
371+ '~' | not isUrl -> emitcseq "\\textasciitilde"
362 '^' -> emits "\\^{}"
372 '^' -> emits "\\^{}"
363 '\\'| isUrl -> emitc '/' -- NB. / works as path sep even on Windows
373 '\\'| isUrl -> emitc '/' -- NB. / works as path sep even on Windows
364− | otherwise -> emits "\\textbackslash{}"
374+ | otherwise -> emitcseq "\\textbackslash"
365− '|' | not isUrl -> emits "\\textbar{}"
375+ '|' | not isUrl -> emitcseq "\\textbar"
366− '<' -> emits "\\textless{}"
376+ '<' -> emitcseq "\\textless"
367− '>' -> emits "\\textgreater{}"
377+ '>' -> emitcseq "\\textgreater"
368 '[' -> emits "{[}" -- to avoid interpretation as
378 '[' -> emits "{[}" -- to avoid interpretation as
369 ']' -> emits "{]}" -- optional arguments
379 ']' -> emits "{]}" -- optional arguments
370− '\'' | ctx == CodeString -> emits "\\textquotesingle{}"
380+ '\'' | ctx == CodeString -> emitcseq "\\textquotesingle"
371 '\160' -> emits "~"
381 '\160' -> emits "~"
372 '\x202F' -> emits "\\,"
382 '\x202F' -> emits "\\,"
373− '\x2026' -> emits "\\ldots{}"
383+ '\x2026' -> emitcseq "\\ldots"
374 '\x2018' | ligatures -> emits "`"
384 '\x2018' | ligatures -> emits "`"
375 '\x2019' | ligatures -> emits "'"
385 '\x2019' | ligatures -> emits "'"
376 '\x201C' | ligatures -> emits "``"
386 '\x201C' | ligatures -> emits "``"
@@ -379,22 +389,22 @@ stringToLaTeX context zs = do
379 '\x2013' | ligatures -> emits "--"
389 '\x2013' | ligatures -> emits "--"
380 _ | writerPreferAscii opts
390 _ | writerPreferAscii opts
381 -> case x of
391 -> case x of
382− 'ı' -> emits "\\i "
392+ 'ı' -> emitcseq "\\i"
383− 'ȷ' -> emits "\\j "
393+ 'ȷ' -> emitcseq "\\j"
384− 'å' -> emits "\\aa "
394+ 'å' -> emitcseq "\\aa"
385− 'Å' -> emits "\\AA "
395+ 'Å' -> emitcseq "\\AA"
386− 'ß' -> emits "\\ss "
396+ 'ß' -> emitcseq "\\ss"
387− 'ø' -> emits "\\o "
397+ 'ø' -> emitcseq "\\o"
388− 'Ø' -> emits "\\O "
398+ 'Ø' -> emitcseq "\\O"
389− 'Ł' -> emits "\\L "
399+ 'Ł' -> emitcseq "\\L"
390− 'ł' -> emits "\\l "
400+ 'ł' -> emitcseq "\\l"
391− 'æ' -> emits "\\ae "
401+ 'æ' -> emitcseq "\\ae"
392− 'Æ' -> emits "\\AE "
402+ 'Æ' -> emitcseq "\\AE"
393− 'œ' -> emits "\\oe "
403+ 'œ' -> emitcseq "\\oe"
394− 'Œ' -> emits "\\OE "
404+ 'Œ' -> emitcseq "\\OE"
395− '£' -> emits "\\pounds "
405+ '£' -> emitcseq "\\pounds"
396− '€' -> emits "\\euro "
406+ '€' -> emitcseq "\\euro"
397− '©' -> emits "\\copyright "
407+ '©' -> emitcseq "\\copyright"
398 _ -> emitc x
408 _ -> emitc x
399 | otherwise -> emitc x
409 | otherwise -> emitc x