diff options
| -rw-r--r-- | spec/src/Thermoprint/Printout/BBCode.hs | 14 | ||||
| -rw-r--r-- | spec/src/Thermoprint/Printout/BBCode/Attribute.hs | 33 | ||||
| -rw-r--r-- | spec/thermoprint-spec.cabal | 2 |
3 files changed, 37 insertions, 12 deletions
diff --git a/spec/src/Thermoprint/Printout/BBCode.hs b/spec/src/Thermoprint/Printout/BBCode.hs index 1ca1e01..7f09623 100644 --- a/spec/src/Thermoprint/Printout/BBCode.hs +++ b/spec/src/Thermoprint/Printout/BBCode.hs | |||
| @@ -11,14 +11,11 @@ module Thermoprint.Printout.BBCode | |||
| 11 | ) where | 11 | ) where |
| 12 | 12 | ||
| 13 | import Data.Text (Text) | 13 | import Data.Text (Text) |
| 14 | import qualified Data.Text as T (unpack) | 14 | import Data.Map (Map) |
| 15 | 15 | ||
| 16 | import qualified Data.Text.Lazy as Lazy (Text) | 16 | import qualified Data.Text.Lazy as Lazy (Text) |
| 17 | import qualified Data.Text.Lazy as TL (fromStrict) | 17 | import qualified Data.Text.Lazy as TL (fromStrict) |
| 18 | 18 | ||
| 19 | import Data.Map (Map) | ||
| 20 | import qualified Data.Map as Map (lookup) | ||
| 21 | |||
| 22 | import Data.Sequence (Seq) | 19 | import Data.Sequence (Seq) |
| 23 | import qualified Data.Sequence as Seq (fromList, singleton) | 20 | import qualified Data.Sequence as Seq (fromList, singleton) |
| 24 | 21 | ||
| @@ -32,15 +29,13 @@ import Data.Typeable (Typeable) | |||
| 32 | import Data.Bifunctor (bimap, first) | 29 | import Data.Bifunctor (bimap, first) |
| 33 | import Control.Monad (join) | 30 | import Control.Monad (join) |
| 34 | 31 | ||
| 35 | import Text.Read (readMaybe) | ||
| 36 | |||
| 37 | import Data.Maybe (fromMaybe) | ||
| 38 | |||
| 39 | import Text.BBCode (DomForest, DomTree(..), TreeError(..)) | 32 | import Text.BBCode (DomForest, DomTree(..), TreeError(..)) |
| 40 | import qualified Text.BBCode as Raw (bbcode, BBCodeError(..)) | 33 | import qualified Text.BBCode as Raw (bbcode, BBCodeError(..)) |
| 41 | 34 | ||
| 42 | import Thermoprint.Printout | 35 | import Thermoprint.Printout |
| 43 | 36 | ||
| 37 | import Thermoprint.Printout.BBCode.Attribute | ||
| 38 | |||
| 44 | -- ^ We replicate 'Raw.BBCodeError' but add a new failure mode documenting incompatibly of the parsed syntax tree with our document format | 39 | -- ^ We replicate 'Raw.BBCodeError' but add a new failure mode documenting incompatibly of the parsed syntax tree with our document format |
| 45 | data BBCodeError = LexerError String -- ^ Error while parsing input to stream of tokens | 40 | data BBCodeError = LexerError String -- ^ Error while parsing input to stream of tokens |
| 46 | | TreeError TreeError -- ^ Error while parsing stream of tokens to syntax tree | 41 | | TreeError TreeError -- ^ Error while parsing stream of tokens to syntax tree |
| @@ -123,9 +118,6 @@ parse :: Monoid a => Context a -> [DomTree] -> Either SemanticError a | |||
| 123 | -- @parse ctx = 'mergeResult' ctx . map 'parseDom'@ | 118 | -- @parse ctx = 'mergeResult' ctx . map 'parseDom'@ |
| 124 | parse ctx = mergeResult ctx . map parseDom | 119 | parse ctx = mergeResult ctx . map parseDom |
| 125 | 120 | ||
| 126 | lookupAttr :: Read a => CI Text -> a -> Map (CI Text) Text -> a | ||
| 127 | lookupAttr t def attrs = fromMaybe def $ Map.lookup t attrs >>= (readMaybe . T.unpack) | ||
| 128 | |||
| 129 | asBlock :: CI Text -> [DomTree] -> Map (CI Text) Text -> Either SemanticError Block | 121 | asBlock :: CI Text -> [DomTree] -> Map (CI Text) Text -> Either SemanticError Block |
| 130 | asBlock "VSpace" [] = Right . VSpace . lookupAttr "height" 1 | 122 | asBlock "VSpace" [] = Right . VSpace . lookupAttr "height" 1 |
| 131 | asBlock t _ = const $ Left . UnmappedBlockElement . CI.original $ t | 123 | asBlock t _ = const $ Left . UnmappedBlockElement . CI.original $ t |
diff --git a/spec/src/Thermoprint/Printout/BBCode/Attribute.hs b/spec/src/Thermoprint/Printout/BBCode/Attribute.hs new file mode 100644 index 0000000..60815c8 --- /dev/null +++ b/spec/src/Thermoprint/Printout/BBCode/Attribute.hs | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | {-# LANGUAGE DefaultSignatures #-} | ||
| 2 | |||
| 3 | -- | Parsing attributes | ||
| 4 | module Thermoprint.Printout.BBCode.Attribute | ||
| 5 | ( Attribute(..) | ||
| 6 | , lookupAttr | ||
| 7 | ) where | ||
| 8 | |||
| 9 | import Data.Text (Text) | ||
| 10 | import qualified Data.Text as T (unpack) | ||
| 11 | |||
| 12 | import Data.Map (Map) | ||
| 13 | import qualified Data.Map as Map (lookup) | ||
| 14 | |||
| 15 | import Data.CaseInsensitive (CI) | ||
| 16 | import qualified Data.CaseInsensitive as CI | ||
| 17 | |||
| 18 | import Text.Read (readMaybe) | ||
| 19 | import Data.Maybe (fromMaybe) | ||
| 20 | |||
| 21 | -- | We build our own version of 'Read' so we can override the presentation used | ||
| 22 | -- | ||
| 23 | -- We provide a default implementation for 'Read a => Attribute a' | ||
| 24 | class Attribute a where | ||
| 25 | attrRead :: Text -> Maybe a | ||
| 26 | default attrRead :: Read a => Text -> Maybe a | ||
| 27 | attrRead = readMaybe . T.unpack | ||
| 28 | |||
| 29 | instance Attribute Integer | ||
| 30 | |||
| 31 | lookupAttr :: Attribute a => CI Text -> a -> Map (CI Text) Text -> a | ||
| 32 | -- ^ Extract an attribute by name | ||
| 33 | lookupAttr t def attrs = fromMaybe def $ Map.lookup t attrs >>= attrRead | ||
diff --git a/spec/thermoprint-spec.cabal b/spec/thermoprint-spec.cabal index eb9d6d3..ad861aa 100644 --- a/spec/thermoprint-spec.cabal +++ b/spec/thermoprint-spec.cabal | |||
| @@ -22,7 +22,7 @@ library | |||
| 22 | , Thermoprint.Printout.BBCode | 22 | , Thermoprint.Printout.BBCode |
| 23 | , Thermoprint.Identifiers | 23 | , Thermoprint.Identifiers |
| 24 | , Thermoprint.API | 24 | , Thermoprint.API |
| 25 | -- other-modules: | 25 | other-modules: Thermoprint.Printout.BBCode.Attribute |
| 26 | -- other-extensions: | 26 | -- other-extensions: |
| 27 | extensions: DeriveGeneric | 27 | extensions: DeriveGeneric |
| 28 | , DeriveAnyClass | 28 | , DeriveAnyClass |
