git.iko.soy/typeable/pandoc
on master help sign in
Rewrote functions in Text/Pandoc/Shared so as not to use Text.Regex,

which does not support unicode: - escapePreservingRegex removed - stringToSGML rewritten using Parsec parser - new parsers for SGML character entities - escapeSGML rewritten using specialCharToEntity - new function specialCharToEntity git-svn-id: https://pandoc.googlecode.com/svn/trunk@514 788f1e2b-df1e-0410-8736-df70ead52e1b

commitf2de08864ee9870147839389554b9353631d21f8 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateWed 24 Jan 2007, 23:25 (20 years ago) parent11456ba
1 file changed+51−28
src/Text/Pandoc/Shared.hs+51−28
src/Text/Pandoc/Shared.hs+51−28
@@ -36,7 +36,6 @@ module Text.Pandoc.Shared (
3636 joinWithSep,
3737 tabsToSpaces,
3838 backslashEscape,
39− escapePreservingRegex,
4039 endsWith,
4140 stripTrailingNewlines,
4241 removeLeadingTrailingSpace,
@@ -74,12 +73,11 @@ module Text.Pandoc.Shared (
7473 inTagsIndented
7574 ) where
7675import Text.Pandoc.Definition
77−import Text.ParserCombinators.Parsec
78−import Text.Pandoc.Entities ( decodeEntities, encodeEntities, characterEntity )
79−import Text.Regex ( matchRegexAll, mkRegex, subRegex, Regex )
80−import Text.PrettyPrint.HughesPJ as PP ( text, char, (<>), ($$), nest, Doc,
81− isEmpty )
82−import Data.Char ( toLower )
76+import Text.ParserCombinators.Parsec as Parsec
77+import Text.Pandoc.Entities ( decodeEntities, charToEntity )
78+import Text.PrettyPrint.HughesPJ as PP ( text, char, (<>),
79+ ($$), nest, Doc, isEmpty )
80+import Data.Char ( toLower, ord )
8381import Data.List ( find, groupBy, isPrefixOf )
8482
8583-- | Parse a string with a given parser and state.
@@ -228,17 +226,6 @@ backslashEscape special (x:xs) = if x `elem` special
228226 then '\\':x:(backslashEscape special xs)
229227 else x:(backslashEscape special xs)
230228
231−-- | Escape string by applying a function, but don't touch anything that matches regex.
232−escapePreservingRegex :: (String -> String) -- ^ Escaping function
233− -> Regex -- ^ Regular expression
234− -> String -- ^ String to be escaped
235− -> String
236−escapePreservingRegex escapeFunction regex str =
237− case (matchRegexAll regex str) of
238− Nothing -> escapeFunction str
239− Just (before, matched, after, _) -> (escapeFunction before) ++
240− matched ++ (escapePreservingRegex escapeFunction regex after)
241−
242229-- | Returns @True@ if string ends with given character.
243230endsWith :: Char -> [Char] -> Bool
244231endsWith char [] = False
@@ -536,20 +523,56 @@ replaceRefLinksInline keytable (Quoted t lst) =
536523 Quoted t (map (replaceRefLinksInline keytable) lst)
537524replaceRefLinksInline keytable other = other
538525
526+-- | Parse SGML character entity.
527+sgmlCharacterEntity :: GenParser Char st [Char]
528+sgmlCharacterEntity = sgmlNamedEntity <|> sgmlDecimalEntity <|>
529+ sgmlHexEntity <?> "SGML entity"
530+
531+-- | Parse SGML character entity.
532+sgmlNamedEntity :: GenParser Char st [Char]
533+sgmlNamedEntity = try $ do
534+ st <- Parsec.char '&'
535+ body <- many1 alphaNum
536+ end <- Parsec.char ';'
537+ return $ (st:body) ++ [end]
538+
539+-- | Parse SGML decimal entity.
540+sgmlDecimalEntity :: GenParser Char st [Char]
541+sgmlDecimalEntity = try $ do
542+ st <- string "&#"
543+ body <- many1 (oneOf "0123456789")
544+ end <- Parsec.char ';'
545+ return $ st ++ body ++ [end]
546+
547+-- | Parse SGML hexadecimal entity.
548+sgmlHexEntity :: GenParser Char st [Char]
549+sgmlHexEntity = try $ do
550+ st <- string "&#"
551+ hex <- oneOf "Xx"
552+ body <- many1 (oneOf "0123456789ABCDEFabcdef")
553+ end <- Parsec.char ';'
554+ return $ st ++ (hex:body) ++ [end]
555+
556+-- | Escape special character to SGML entity.
557+specialCharToEntity :: Char -> [Char]
558+specialCharToEntity c = if (c `elem` "&<>\"") || (ord c > 127)
559+ then charToEntity c
560+ else [c]
561+
539562-- | Escape string, preserving character entities.
540563stringToSGML :: String -> String
541−stringToSGML =
542− encodeEntities . (escapePreservingRegex escapeSGML characterEntity)
564+stringToSGML str =
565+ let segment = sgmlCharacterEntity <|>
566+ (do{c <- anyChar;
567+ return $ specialCharToEntity c})
568+ sgmlString = (do{segs <- many segment; return $ concat segs}) in
569+ case parse sgmlString str str of
570+ Left err -> error $ "\nError:\n" ++ show err
571+ Right result -> result
543572
544−-- | Escape string as needed for HTML. Entity references are not preserved.
573+-- | Escape string as needed for SGML. Entity references are not preserved.
545574escapeSGML :: String -> String
546−escapeSGML [] = []
547−escapeSGML (x:xs) = case x of
548− '&' -> "&amp;" ++ escapeSGML xs
549− '<' -> "&lt;" ++ escapeSGML xs
550− '>' -> "&gt;" ++ escapeSGML xs
551− '"' -> "&quot;" ++ escapeSGML xs
552− _ -> x:(escapeSGML xs)
575+escapeSGML = concatMap specialCharToEntity
553576
554577-- | Return a text object with a string of formatted SGML attributes.
555578attributeList :: [(String, String)] -> Doc