aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn MacFarlane <[email protected]>2025-03-23 10:29:17 -0700
committerJohn MacFarlane <[email protected]>2025-03-23 10:29:17 -0700
commit3bbca20240ebc26d614a6d01a44ceb39f0d994ec (patch)
tree4afe5178c970d03e6897461cbe05c0ee8197838f /src
parent4ab4c62de38372def66b07cfc8f75518a599d249 (diff)
Use the most compatible form for roff escapes.
This affects T.P.RoffChar, T.P.Writers.Roff, and the Man and Ms writers. That is, `\(xy` instead of `\[xy]`. This was the original AT&T troff form and is the most widely supported. The bracketed form causes problem for some tools, e.g. `makewhatis` on macOS. Closes #10716.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/RoffChar.hs30
-rw-r--r--src/Text/Pandoc/Writers/Man.hs6
-rw-r--r--src/Text/Pandoc/Writers/Ms.hs6
-rw-r--r--src/Text/Pandoc/Writers/Roff.hs7
4 files changed, 28 insertions, 21 deletions
diff --git a/src/Text/Pandoc/RoffChar.hs b/src/Text/Pandoc/RoffChar.hs
index f5a4134a1..257b44f4d 100644
--- a/src/Text/Pandoc/RoffChar.hs
+++ b/src/Text/Pandoc/RoffChar.hs
@@ -19,23 +19,25 @@ module Text.Pandoc.RoffChar (
import qualified Data.Text as T
-- | These are the escapes specifically mentioned in groff_man(7),
--- plus @ and ellipsis.
+-- plus @ and ellipsis. We use the \(aq form when possible (with
+-- two-letter escapes), because these are compatible with all forms
+-- of roff (#10716).
standardEscapes :: [(Char, T.Text)]
standardEscapes =
[ ('\160', "\\ ")
- , ('\'', "\\[aq]")
- , ('‘', "\\[oq]")
- , ('’', "\\[cq]")
- , ('"', "\\[dq]")
- , ('“', "\\[lq]")
- , ('”', "\\[rq]")
- , ('—', "\\[em]")
- , ('–', "\\[en]")
- , ('`', "\\[ga]")
- , ('^', "\\[ha]")
- , ('~', "\\[ti]")
- , ('\\', "\\[rs]")
- , ('@', "\\[at]") -- because we use @ as a table and math delimiter
+ , ('\'', "\\(aq")
+ , ('‘', "\\(oq")
+ , ('’', "\\(cq")
+ , ('"', "\\(dq")
+ , ('“', "\\(lq")
+ , ('”', "\\(rq")
+ , ('—', "\\(em")
+ , ('–', "\\(en")
+ , ('`', "\\(ga")
+ , ('^', "\\(ha")
+ , ('~', "\\(ti")
+ , ('\\', "\\(rs")
+ , ('@', "\\(at") -- because we use @ as a table and math delimiter
, ('\x2026', "\\&...") -- because u2026 doesn't render on tty
]
diff --git a/src/Text/Pandoc/Writers/Man.hs b/src/Text/Pandoc/Writers/Man.hs
index e43caa6e4..23eff037f 100644
--- a/src/Text/Pandoc/Writers/Man.hs
+++ b/src/Text/Pandoc/Writers/Man.hs
@@ -200,7 +200,7 @@ bulletListItemToMan opts (Para first:rest) =
bulletListItemToMan opts (Plain first:rest) = do
first' <- blockToMan opts (Plain first)
rest' <- blockListToMan opts rest
- let first'' = literal ".IP \\[bu] 2" $$ first'
+ let first'' = literal ".IP \\(bu 2" $$ first'
let rest'' = if null rest
then empty
else literal ".RS 2" $$ rest' $$ literal ".RE"
@@ -208,7 +208,7 @@ bulletListItemToMan opts (Plain first:rest) = do
bulletListItemToMan opts (first:rest) = do
first' <- blockToMan opts first
rest' <- blockListToMan opts rest
- return $ literal "\\[bu] .RS 2" $$ first' $$ rest' $$ literal ".RE"
+ return $ literal "\\(bu .RS 2" $$ first' $$ rest' $$ literal ".RE"
-- | Convert ordered list item (a list of blocks) to man.
orderedListItemToMan :: PandocMonad m
@@ -299,7 +299,7 @@ inlineToMan opts (Quoted SingleQuote lst) = do
return $ char '`' <> contents <> char '\''
inlineToMan opts (Quoted DoubleQuote lst) = do
contents <- inlineListToMan opts lst
- return $ literal "\\[lq]" <> contents <> literal "\\[rq]"
+ return $ literal "\\(lq" <> contents <> literal "\\(rq"
inlineToMan opts (Cite _ lst) =
inlineListToMan opts lst
inlineToMan opts (Code _ str) =
diff --git a/src/Text/Pandoc/Writers/Ms.hs b/src/Text/Pandoc/Writers/Ms.hs
index e2c97044f..8f5c11a51 100644
--- a/src/Text/Pandoc/Writers/Ms.hs
+++ b/src/Text/Pandoc/Writers/Ms.hs
@@ -328,7 +328,7 @@ bulletListItemToMs opts (Para first:rest) =
bulletListItemToMs opts (Plain first:rest) = do
first' <- blockToMs opts (Plain first)
rest' <- blockListToMs opts rest
- let first'' = literal ".IP \\[bu] 3" $$ first'
+ let first'' = literal ".IP \\(bu 3" $$ first'
let rest'' = if null rest
then empty
else literal ".RS 3" $$ rest' $$ literal ".RE"
@@ -336,7 +336,7 @@ bulletListItemToMs opts (Plain first:rest) = do
bulletListItemToMs opts (first:rest) = do
first' <- blockToMs opts first
rest' <- blockListToMs opts rest
- return $ literal "\\[bu] .RS 3" $$ first' $$ rest' $$ literal ".RE"
+ return $ literal "\\(bu .RS 3" $$ first' $$ rest' $$ literal ".RE"
-- | Convert ordered list item (a list of blocks) to ms.
orderedListItemToMs :: PandocMonad m
@@ -435,7 +435,7 @@ inlineToMs opts (Quoted SingleQuote lst) = do
return $ char '`' <> contents <> char '\''
inlineToMs opts (Quoted DoubleQuote lst) = do
contents <- inlineListToMs opts lst
- return $ literal "\\[lq]" <> contents <> literal "\\[rq]"
+ return $ literal "\\(lq" <> contents <> literal "\\(rq"
inlineToMs opts (Cite _ lst) =
inlineListToMs opts lst
inlineToMs opts (Code attr str) = do
diff --git a/src/Text/Pandoc/Writers/Roff.hs b/src/Text/Pandoc/Writers/Roff.hs
index 9a891b7a1..a37b93ee4 100644
--- a/src/Text/Pandoc/Writers/Roff.hs
+++ b/src/Text/Pandoc/Writers/Roff.hs
@@ -99,7 +99,12 @@ escapeString escapeHyphen e = Text.concat . escapeString' e . Text.unpack
(map (`Map.lookup` combiningAccentsMap) xs)
rest = drop (length accents) xs
s = case Map.lookup x characterCodeMap of
- Just t -> "\\[" <> Text.unwords (t:accents) <> "]"
+ Just t ->
+ if null accents
+ then if Text.length t == 2
+ then "\\(" <> t -- see #10716
+ else "\\[" <> t <> "]"
+ else "\\[" <> Text.unwords (t:accents) <> "]"
Nothing -> "\\[" <> Text.unwords
(Text.pack (printf "u%04X" (ord x)) : accents) <> "]"
in s : escapeString' escapeMode rest