@@ -87,7 +87,6 @@ type MacroKind = String
8787
8888data LinePart = RoffStr String
8989 | Font FontSpec
90− | FontSize Int
9190 | MacroArg Int
9291 deriving Show
9392
@@ -215,58 +214,85 @@ escapeNormal :: PandocMonad m => RoffLexer m [LinePart]
215214escapeNormal = do
216215 c <- anyChar
217216 case c of
218− 'A' -> quoteArg >>= checkDefined
219− 'C' -> quoteArg >>= resolveGlyph '\''
220− 'f' -> escFont
221− 's' -> escFontSize
222− '*' -> escString
217+ ' ' -> return [RoffStr " "]
223218 '"' -> mempty <$ skipMany (satisfy (/='\n')) -- line comment
224219 '#' -> mempty <$ manyTill anyChar newline
225220 '%' -> return mempty -- optional hyphenation
226− ':' -> return mempty -- zero-width break
227− '{' -> return mempty
228− '}' -> return mempty
229221 '&' -> return mempty -- nonprintable zero-width
230222 ')' -> return mempty -- nonprintable zero-width
231− '/' -> return mempty -- to fix spacing before roman
223+ '*' -> escString
232224 ',' -> return mempty -- to fix spacing after roman
233− '\n' -> return mempty -- line continuation
234− 'c' -> return mempty -- interrupt text processing
235− 'a' -> return mempty -- "non-interpreted leader character"
236225 '-' -> return [RoffStr "-"]
237− '_' -> return [RoffStr "_"]
238− ' ' -> return [RoffStr " "]
239− '\\' -> do
240− mode <- roffMode <$> getState
241− case mode of
242− CopyMode -> char '\\'
243− NormalMode -> return '\\'
244− return [RoffStr "\\"]
245− 't' -> return [RoffStr "\t"]
246− 'e' -> return [RoffStr "\\"]
226+ '.' -> return [RoffStr "`"]
227+ '/' -> return mempty -- to fix spacing before roman
228+ '0' -> return [RoffStr "\x2007"] -- digit-width space
229+ ':' -> return mempty -- zero-width break
230+ 'A' -> quoteArg >>= checkDefined
231+ 'B' -> escIgnore 'B' [quoteArg]
232+ 'C' -> quoteArg >>= resolveGlyph '\''
233+ 'D' -> escIgnore 'D' [quoteArg]
247234 'E' -> do
248235 mode <- roffMode <$> getState
249236 case mode of
250237 CopyMode -> return mempty
251238 NormalMode -> return [RoffStr "\\"]
252− '`' -> return [RoffStr "`"]
239+ 'H' -> escIgnore 'H' [quoteArg]
240+ 'L' -> escIgnore 'L' [quoteArg]
241+ 'M' -> escIgnore 'M' [escapeArg, count 1 (satisfy (/='\n'))]
242+ 'N' -> escIgnore 'N' [quoteArg]
243+ 'O' -> escIgnore 'O' [count 1 (oneOf ['0','1'])]
244+ 'R' -> escIgnore 'R' [quoteArg]
245+ 'S' -> escIgnore 'S' [quoteArg]
246+ 'V' -> escIgnore 'V' [escapeArg, count 1 alphaNum]
247+ 'X' -> escIgnore 'X' [quoteArg]
248+ 'Y' -> escIgnore 'Y' [escapeArg, count 1 (satisfy (/='\n'))]
249+ 'Z' -> escIgnore 'Z' [quoteArg]
250+ '\'' -> return [RoffStr "`"]
251+ '\n' -> return mempty -- line continuation
253252 '^' -> return [RoffStr "\x200A"] -- 1/12 em space
253+ '_' -> return [RoffStr "_"]
254+ '`' -> return [RoffStr "`"]
255+ 'a' -> return mempty -- "non-interpreted leader character"
256+ 'b' -> escIgnore 'b' [quoteArg]
257+ 'c' -> return mempty -- interrupt text processing
258+ 'd' -> escIgnore 'd' [] -- forward down 1/2em
259+ 'e' -> return [RoffStr "\\"]
260+ 'f' -> escFont
261+ 'g' -> escIgnore 'g' [escapeArg, count 1 (satisfy (/='\n'))]
262+ 'h' -> escIgnore 'h' [quoteArg]
263+ 'k' -> escIgnore 'k' [escapeArg, count 1 (satisfy (/='\n'))]
264+ 'l' -> escIgnore 'l' [quoteArg]
265+ 'm' -> escIgnore 'm' [escapeArg, count 1 (satisfy (/='\n'))]
266+ 'n' -> escIgnore 'm' [escapeArg, count 1 (satisfy (/='\n'))]
267+ 'o' -> escIgnore 'o' [quoteArg]
268+ 'p' -> escIgnore 'p' []
269+ 'r' -> escIgnore 'r' []
270+ 's' -> escIgnore 's' [escapeArg, signedNumber]
271+ 't' -> return [RoffStr "\t"]
272+ 'u' -> escIgnore 'u' []
273+ 'v' -> escIgnore 'v' [quoteArg]
274+ 'w' -> escIgnore 'w' [quoteArg]
275+ 'x' -> escIgnore 'x' [quoteArg]
276+ 'z' -> escIgnore 'z' [count 1 anyChar]
277+ '{' -> return mempty
254278 '|' -> return [RoffStr "\x2006"] --1/6 em space
255− '\'' -> return [RoffStr "`"]
256− '.' -> return [RoffStr "`"]
279+ '}' -> return mempty
257280 '~' -> return [RoffStr "\160"] -- nonbreaking space
258− '0' -> return [RoffStr "\x2007"] -- digit-width space
259− _ -> escIgnore c
281+ '\\' -> do
282+ mode <- roffMode <$> getState
283+ case mode of
284+ CopyMode -> char '\\'
285+ NormalMode -> return '\\'
286+ return [RoffStr "\\"]
287+ _ -> fail $ "Unknown escape character \\" ++ [c]
260288
261−escIgnore :: PandocMonad m => Char -> RoffLexer m [LinePart]
262−escIgnore c = do
289+escIgnore :: PandocMonad m
290+ => Char
291+ -> [RoffLexer m String]
292+ -> RoffLexer m [LinePart]
293+escIgnore c argparsers = do
263294 pos <- getPosition
264− nextc <- lookAhead anyChar
265− arg <- case nextc of
266− '[' -> (\x -> "[" ++ x ++ "]") <$> escapeArg
267− '(' -> ('(':) <$> escapeArg
268− '\'' -> (\x -> "'" ++ x ++ "'") <$> quoteArg
269− _ -> count 1 anyChar
295+ arg <- snd <$> withRaw (choice argparsers) <|> return ""
270296 report $ SkippedContent ('\\':c:arg) pos
271297 return mempty
272298
@@ -276,34 +302,17 @@ escUnknown s = do
276302 report $ SkippedContent s pos
277303 return [RoffStr "\xFFFD"]
278304
279−-- \s-1 \s0
280−escFontSize :: PandocMonad m => RoffLexer m [LinePart]
281−escFontSize = do
282− let sign = option "" ("-" <$ char '-' <|> "" <$ char '+')
283− let toFontSize xs =
284− case safeRead xs of
285− Nothing -> mzero
286− Just n -> return [FontSize n]
287− choice
288− [ do char '('
289− s <- sign
290− ds <- count 2 digit
291− toFontSize (s ++ ds)
292− , do char '['
293− s <- sign
294− ds <- many1 digit
295− char ']'
296− toFontSize (s ++ ds)
297− , do s <- sign
298− ds <- count 1 digit
299− toFontSize (s ++ ds)
300− ]
305+signedNumber :: PandocMonad m => RoffLexer m String
306+signedNumber = try $ do
307+ sign <- option "" ("-" <$ char '-' <|> "" <$ char '+')
308+ ds <- many1 digit
309+ return (sign ++ ds)
301310
302311-- Parses: [..] or (..
303312escapeArg :: PandocMonad m => RoffLexer m String
304313escapeArg = choice
305314 [ char '[' *> manyTill (noneOf ['\n',']']) (char ']')
306− , char '(' *> count 2 anyChar
315+ , char '(' *> count 2 (satisfy (/='\n'))
307316 ]
308317
309318-- Parses: '..'