@@ -40,7 +40,7 @@ import Control.Monad (liftM, void, mzero, guard)
40import Control.Monad.Except (throwError)
40import Control.Monad.Except (throwError)
41import Text.Pandoc.Class
41import Text.Pandoc.Class
42 (getResourcePath, readFileFromDirs, PandocMonad(..), report)
42 (getResourcePath, readFileFromDirs, PandocMonad(..), report)
43−import Data.Char (isHexDigit, chr, ord)
43+import Data.Char (isHexDigit, chr, ord, isAscii, isAlphaNum)
44import Data.Default (Default)
44import Data.Default (Default)
45import Data.Maybe (catMaybes)
45import Data.Maybe (catMaybes)
46import qualified Data.Map as M
46import qualified Data.Map as M
@@ -60,6 +60,7 @@ import Text.Parsec.Pos (updatePosString)
60import Text.Pandoc.GroffChar (characterCodes, combiningAccents)
60import Text.Pandoc.GroffChar (characterCodes, combiningAccents)
61import qualified Data.Sequence as Seq
61import qualified Data.Sequence as Seq
62import qualified Data.Foldable as Foldable
62import qualified Data.Foldable as Foldable
63+import qualified Data.Text.Normalize as Normalize
64-- import Debug.Trace (traceShowId)
65-- import Debug.Trace (traceShowId)
@@ -157,7 +158,11 @@ spacetab = char ' ' <|> char '\t'
158characterCodeMap :: M.Map String Char
159characterCodeMap :: M.Map String Char
159characterCodeMap =
160characterCodeMap =
160− M.fromList $ map (\(x,y) -> (y,x)) $ characterCodes ++ combiningAccents
161+ M.fromList $ map (\(x,y) -> (y,x)) characterCodes
163+combiningAccentsMap :: M.Map String Char
164+combiningAccentsMap =
165+ M.fromList $ map (\(x,y) -> (y,x)) combiningAccents
162escapeLexer :: PandocMonad m => ManLexer m String
167escapeLexer :: PandocMonad m => ManLexer m String
163escapeLexer = try $ do
168escapeLexer = try $ do
@@ -189,7 +194,7 @@ escapeLexer = try $ do
189 '\'' -> return "`"
194 '\'' -> return "`"
190 '.' -> return "`"
195 '.' -> return "`"
191 '~' -> return "\160" -- nonbreaking space
196 '~' -> return "\160" -- nonbreaking space
192− _ -> escUnknown [c] "\xFFFD"
197+ _ -> escUnknown ['\\',c] "\xFFFD"
@@ -199,10 +204,34 @@ escapeLexer = try $ do
199 Just c -> return [c]
204 Just c -> return [c]
200 Nothing -> escUnknown ('\\':'(':cs) "\xFFFD"
205 Nothing -> escUnknown ('\\':'(':cs) "\xFFFD"
202− bracketedGlyph =
207+ bracketedGlyph = unicodeGlyph <|> charGlyph
203− ( ucharCode `sepBy1` (char '_')
208+
204− <|> charCode `sepBy1` (many1 Parsec.space)
209+ charGlyph = do
205− ) <* char ']'
210+ cs <- manyTill (noneOf ['[',']','\n']) (char ']')
213+ [s] -> case M.lookup s characterCodeMap of
215+ Just c -> return [c]
217+ basechar <- case M.lookup cs characterCodeMap of
220+ [ch] | isAscii ch && isAlphaNum ch ->
224+ let addAccents [] xs = return $ T.unpack .
225+ Normalize.normalize Normalize.NFC .
227+ addAccents (a:as) xs =
228+ case M.lookup a combiningAccentsMap of
229+ Just x -> addAccents as (x:xs)
231+ addAccents ss [basechar])
232+ <|> escUnknown ("\\[" ++ cs ++ "]") "\xFFFD"
234+ unicodeGlyph = try $ ucharCode `sepBy1` (char '_') <* char ']'
207 ucharCode = try $ do
236 ucharCode = try $ do
@@ -210,16 +239,9 @@ escapeLexer = try $ do
210 let lcs = length cs
239 let lcs = length cs
211 guard $ lcs >= 4 && lcs <= 6
240 guard $ lcs >= 4 && lcs <= 6
212 case chr <$> safeRead ('0':'x':cs) of
241 case chr <$> safeRead ('0':'x':cs) of
213− Nothing -> escUnknown ("\\[u" ++ cs ++ "]") '\xFFFD'
242+ Nothing -> mzero
214 Just c -> return c
243 Just c -> return c
217− cs <- many1 (noneOf ['[',']',' ','\t','\n'])
218− case M.lookup cs characterCodeMap of
219− Nothing -> escUnknown ("\\[" ++ cs ++ "]") '\xFFFD'
223 escFont :: PandocMonad m => ManLexer m String
245 escFont :: PandocMonad m => ManLexer m String
224 escFont = do
246 escFont = do
225 font <- choice [ S.singleton <$> letterFontKind
247 font <- choice [ S.singleton <$> letterFontKind