module Wumpus.Core.TextInternal
(
EncodedText(..)
, TextChunk(..)
, EncodedChar(..)
, textLength
, lookupByCharCode
, lookupByGlyphName
, lexLabel
) where
import Wumpus.Core.FormatCombinators
import Wumpus.Core.TextEncoder
import Data.Char
newtype EncodedText = EncodedText { getEncodedText :: [TextChunk] }
deriving (Eq,Show)
data TextChunk = TextSpan String
| TextEscInt Int
| TextEscName GlyphName
deriving (Eq,Show)
data EncodedChar = CharLiteral Char
| CharEscInt Int
| CharEscName GlyphName
deriving (Eq,Show)
instance Format EncodedText where
format = hcat . map format . getEncodedText
instance Format TextChunk where
format (TextSpan s) = text s
format (TextEscInt i) = text "&#" <> int i <> semicolon
format (TextEscName s) = text "&#" <> text s <> semicolon
instance Format EncodedChar where
format (CharLiteral c) = char c
format (CharEscInt i) = text "&#" <> int i <> semicolon
format (CharEscName s) = text "&#" <> text s <> semicolon
textLength :: EncodedText -> Int
textLength = foldr add 0 . getEncodedText where
add (TextSpan s) n = n + length s
add _ n = n + 1
lookupByCharCode :: CharCode -> TextEncoder -> Maybe GlyphName
lookupByCharCode i enc = (ps_lookup enc) i
lookupByGlyphName :: GlyphName -> TextEncoder -> Maybe CharCode
lookupByGlyphName i enc = (svg_lookup enc) i
lexLabel :: String -> EncodedText
lexLabel = EncodedText . lexer
lexer :: String -> [TextChunk]
lexer [] = []
lexer ('&':'#':xs) = esc xs
where
esc (c:cs) | isDigit c = let (s,cs') = span isDigit cs
in intval (c:s) cs'
| otherwise = let (s,cs') = span isAlpha cs
in TextEscName (c:s) : optsemi cs'
esc [] = []
optsemi (';':cs) = lexer cs
optsemi cs = lexer cs
intval [] rest = optsemi rest
intval cs rest = TextEscInt (read cs) : optsemi rest
lexer (x:xs) = let (s,xs') = span (/= '&') xs
in TextSpan (x:s) : lexer xs'