{-# LANGUAGE DeriveTraversable, Safe #-} {-| Module : Data.Char.Braille Description : A module used to render Braille characters in unicode. Maintainer : hapytexeu+gh@gmail.com Stability : experimental Portability : POSIX Unicode has a Braille segment for Braille with six dot cells, and a segment for Braille with eight dot cells, this module aims to make it more convenient to render such characters. -} module Data.Char.Braille( -- * Datastructures to store the state of the Braille character. Braille6(Braille6, top, middle, bottom) , Braille(Braille, row1, row2, row3, row4) -- * Converting 'Braille6' to 'Braille' , toBraille', toBraille -- * Rendering Braille characters. , braille6, braille ) where import Data.Bits((.|.), shiftL) import Data.Bool(bool) import Data.Char(chr) import Data.Char.Block(Row(Row)) import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary), Arbitrary1(liftArbitrary), arbitrary1) -- | A datastructure to render Braille patterns with six dots cells. data Braille6 a = Braille6 { top :: Row a -- ^ The state of the top row of the Braille character. , middle :: Row a -- ^ The state of the middle row of the Braille character. , bottom :: Row a -- ^ The state of the bottom row of the Braille character. } deriving (Eq, Foldable, Functor, Ord, Read, Show, Traversable) -- | A datastructure to render Braille patterns with eight dots cells. data Braille a = Braille { row1 :: Row a -- ^ The state of the top row of the Braille character. , row2 :: Row a -- ^ The state of the second row of the Braille character. , row3 :: Row a -- ^ The state of the third row of the Braille character. , row4 :: Row a -- ^ The state of the bottom row of the Braille character. } deriving (Eq, Foldable, Functor, Ord, Read, Show, Traversable) -- | Convert a 'Braille6' value to a 'Braille' character, by putting in a given -- value at the two values at the bottom row. toBraille' :: a -- ^ The value to put in the cells of the bottom row. -> Braille6 a -- ^ The given 'Braille6' value to convert. -> Braille a -- ^ A 'Braille' value that uses as bottom two values given as first parameter. toBraille' d (Braille6 r0 r1 r2) = Braille r0 r1 r2 (Row d d) -- | Convert a 'Braille6' value to a 'Braille6' character by setting the bottom -- row with two 'False' values. toBraille :: Braille6 Bool -- ^ The given 'Braille6' value to convert. -> Braille Bool -- ^ A 'Braille' value that uses as bottom two times 'False'. toBraille = toBraille' False instance Arbitrary a => Arbitrary (Braille6 a) where arbitrary = arbitrary1 instance Arbitrary1 Braille6 where liftArbitrary arb = Braille6 <$> arb' <*> arb' <*> arb' where arb' = liftArbitrary arb instance Arbitrary a => Arbitrary (Braille a) where arbitrary = arbitrary1 instance Arbitrary1 Braille where liftArbitrary arb = Braille <$> arb' <*> arb' <*> arb' <*> arb' where arb' = liftArbitrary arb _rowValue' :: Int -> Row Bool -> Int _rowValue' d (Row b0 b1) = bool 0 1 b0 .|. bool 0 d b1 _rowValue :: Row Bool -> Int _rowValue = _rowValue' 8 -- | Convert the given 'Braille6' value to a unicode character representing this -- Braille value. braille6 :: Braille6 Bool -> Char braille6 = braille . toBraille -- | Convert the given 'Braille' value to a unicode character representing this -- braille value. braille :: Braille Bool -> Char braille (Braille r1 r2 r3 r4) = chr (0x2800 .|. _rowValue r1 .|. shiftL (_rowValue r2) 1 .|. shiftL (_rowValue r3) 2 .|. shiftL (_rowValue' 2 r4) 6)