git.iko.soy/typeable/pandoc
on master help sign in
Man reader: improved combining accents.
87fa837John MacFarlane
src/Text/Pandoc/Readers/Man.hs+37−15
@@ -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
63
64
64-- import Debug.Trace (traceShowId)
65-- import Debug.Trace (traceShowId)
65
66
@@ -157,7 +158,11 @@ spacetab = char ' ' <|> char '\t'
157
158
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
162+
163+combiningAccentsMap :: M.Map String Char
164+combiningAccentsMap =
165+ M.fromList $ map (\(x,y) -> (y,x)) combiningAccents
161
166
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"
193
198
194 where
199 where
195
200
@@ -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"
201
206
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 ']')
211+ (case words cs of
212+ [] -> mzero
213+ [s] -> case M.lookup s characterCodeMap of
214+ Nothing -> mzero
215+ Just c -> return [c]
216+ (s:ss) -> do
217+ basechar <- case M.lookup cs characterCodeMap of
218+ Nothing ->
219+ case s of
220+ [ch] | isAscii ch && isAlphaNum ch ->
221+ return ch
222+ _ -> mzero
223+ Just c -> return c
224+ let addAccents [] xs = return $ T.unpack .
225+ Normalize.normalize Normalize.NFC .
226+ T.pack $ reverse xs
227+ addAccents (a:as) xs =
228+ case M.lookup a combiningAccentsMap of
229+ Just x -> addAccents as (x:xs)
230+ Nothing -> mzero
231+ addAccents ss [basechar])
232+ <|> escUnknown ("\\[" ++ cs ++ "]") "\xFFFD"
233+
234+ unicodeGlyph = try $ ucharCode `sepBy1` (char '_') <* char ']'
206
235
207 ucharCode = try $ do
236 ucharCode = try $ do
208 char 'u'
237 char 'u'
@@ -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
215
244
216− charCode = do
217− cs <- many1 (noneOf ['[',']',' ','\t','\n'])
218− case M.lookup cs characterCodeMap of
219− Nothing -> escUnknown ("\\[" ++ cs ++ "]") '\xFFFD'
220− Just c -> return c
221−
222−
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