diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-18 11:38:44 +0000 | 
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-18 11:38:44 +0000 | 
| commit | abb427bdccfe78649f5d75654a8179093201609c (patch) | |
| tree | 3c2fbed64af3b1eb4a50a098655be1f109e743fa /spec/src | |
| parent | 1ec5c1cb2f118c906a27b3763c73c0098fe67b4a (diff) | |
| download | thermoprint-abb427bdccfe78649f5d75654a8179093201609c.tar thermoprint-abb427bdccfe78649f5d75654a8179093201609c.tar.gz thermoprint-abb427bdccfe78649f5d75654a8179093201609c.tar.bz2 thermoprint-abb427bdccfe78649f5d75654a8179093201609c.tar.xz thermoprint-abb427bdccfe78649f5d75654a8179093201609c.zip | |
Moved handling of lines in block context
Now allows arbitrary (instead of prefix only) switching between block
and line contexts
Diffstat (limited to 'spec/src')
| -rw-r--r-- | spec/src/Thermoprint/Printout/BBCode.hs | 24 | 
1 files changed, 21 insertions, 3 deletions
| diff --git a/spec/src/Thermoprint/Printout/BBCode.hs b/spec/src/Thermoprint/Printout/BBCode.hs index 8825732..ce2aa43 100644 --- a/spec/src/Thermoprint/Printout/BBCode.hs +++ b/spec/src/Thermoprint/Printout/BBCode.hs | |||
| @@ -29,6 +29,8 @@ import Data.Typeable (Typeable) | |||
| 29 | import Data.Bifunctor (bimap, first) | 29 | import Data.Bifunctor (bimap, first) | 
| 30 | import Control.Monad (join) | 30 | import Control.Monad (join) | 
| 31 | 31 | ||
| 32 | import Data.List (groupBy) | ||
| 33 | |||
| 32 | import Text.BBCode (DomForest, DomTree(..), TreeError(..)) | 34 | import Text.BBCode (DomForest, DomTree(..), TreeError(..)) | 
| 33 | import qualified Text.BBCode as Raw (bbcode, BBCodeError(..)) | 35 | import qualified Text.BBCode as Raw (bbcode, BBCodeError(..)) | 
| 34 | 36 | ||
| @@ -63,6 +65,7 @@ data ParseResult = RBlock Block -- ^ Parses only as 'Block' | |||
| 63 | | RLine Line -- ^ Parses only as 'Line' | 65 | | RLine Line -- ^ Parses only as 'Line' | 
| 64 | | RAmbiguous Block Line -- ^ Parses as either 'Block' or 'Line' depending on context | 66 | | RAmbiguous Block Line -- ^ Parses as either 'Block' or 'Line' depending on context | 
| 65 | | RNoParse SemanticError SemanticError -- ^ Does not parse as either 'Block' or 'Line' | 67 | | RNoParse SemanticError SemanticError -- ^ Does not parse as either 'Block' or 'Line' | 
| 68 | deriving (Show) | ||
| 66 | 69 | ||
| 67 | -- | Current parser context | 70 | -- | Current parser context | 
| 68 | data Context a where | 71 | data Context a where | 
| @@ -80,6 +83,16 @@ extract LineCtx (RNoParse _ lErr) = Left lErr | |||
| 80 | extract BlockCtx _ = Left LineInBlockContext | 83 | extract BlockCtx _ = Left LineInBlockContext | 
| 81 | extract LineCtx _ = Left BlockInLineContext | 84 | extract LineCtx _ = Left BlockInLineContext | 
| 82 | 85 | ||
| 86 | hasBlockCtx :: ParseResult -> Bool | ||
| 87 | -- ^ Result can be 'extract'ed in a 'Block' 'Context' | ||
| 88 | hasBlockCtx (RLine _) = False | ||
| 89 | hasBlockCtx _ = True | ||
| 90 | |||
| 91 | hasLineCtx :: ParseResult -> Bool | ||
| 92 | -- ^ Result can be 'extract'ed in a 'Line' 'Context' | ||
| 93 | hasLineCtx (RBlock _) = False | ||
| 94 | hasLineCtx _ = True | ||
| 95 | |||
| 83 | bbcode :: Text -> Either BBCodeError Printout | 96 | bbcode :: Text -> Either BBCodeError Printout | 
| 84 | -- ^ Parse BBCode | 97 | -- ^ Parse BBCode | 
| 85 | bbcode = join . fmap (first SemanticError) . bimap morph' morph . Raw.bbcode | 98 | bbcode = join . fmap (first SemanticError) . bimap morph' morph . Raw.bbcode | 
| @@ -88,7 +101,7 @@ morph :: DomForest -> Either SemanticError Printout | |||
| 88 | -- ^ Parse a list of paragraphs | 101 | -- ^ Parse a list of paragraphs | 
| 89 | -- | 102 | -- | 
| 90 | -- Since we permit only cooked input via 'Raw' 'Paragraph' is identical to 'Block' | 103 | -- Since we permit only cooked input via 'Raw' 'Paragraph' is identical to 'Block' | 
| 91 | morph f = Seq.fromList <$> mapM (\t -> Seq.singleton . Cooked <$> parse BlockCtx t) f | 104 | morph = fmap Seq.fromList . mapM (\t -> Seq.singleton . Cooked <$> parse BlockCtx t) | 
| 92 | 105 | ||
| 93 | parseDom :: DomTree -> ParseResult | 106 | parseDom :: DomTree -> ParseResult | 
| 94 | -- ^ Invoke 'asLine' and 'asBlock' to parse a single 'DomTree' | 107 | -- ^ Invoke 'asLine' and 'asBlock' to parse a single 'DomTree' | 
| @@ -107,7 +120,6 @@ parseDom (Element t attrs cs) | |||
| 107 | mergeResult :: Monoid a => Context a -> [ParseResult] -> Either SemanticError a | 120 | mergeResult :: Monoid a => Context a -> [ParseResult] -> Either SemanticError a | 
| 108 | -- ^ Merge a list of 'ParseResults' in a certain 'Context' | 121 | -- ^ Merge a list of 'ParseResults' in a certain 'Context' | 
| 109 | mergeResult _ [] = Right mempty | 122 | mergeResult _ [] = Right mempty | 
| 110 | mergeResult BlockCtx xs@((RLine _):_) = bimap (const LineInBlockContext) Line $ mergeResult LineCtx xs | ||
| 111 | mergeResult ctx (amb@(RAmbiguous _ _):xs) = mappend <$> extract ctx amb <*> mergeResult ctx xs | 123 | mergeResult ctx (amb@(RAmbiguous _ _):xs) = mappend <$> extract ctx amb <*> mergeResult ctx xs | 
| 112 | mergeResult ctx (err@(RNoParse _ _):_) = extract ctx err | 124 | mergeResult ctx (err@(RNoParse _ _):_) = extract ctx err | 
| 113 | mergeResult ctx (x:xs) = mappend <$> extract ctx x <*> mergeResult ctx xs | 125 | mergeResult ctx (x:xs) = mappend <$> extract ctx x <*> mergeResult ctx xs | 
| @@ -116,7 +128,13 @@ parse :: Monoid a => Context a -> [DomTree] -> Either SemanticError a | |||
| 116 | -- ^ Parse a list of 'DomTree's in a certain 'Context' | 128 | -- ^ Parse a list of 'DomTree's in a certain 'Context' | 
| 117 | -- | 129 | -- | 
| 118 | -- @parse ctx = 'mergeResult' ctx . map 'parseDom'@ | 130 | -- @parse ctx = 'mergeResult' ctx . map 'parseDom'@ | 
| 119 | parse ctx = mergeResult ctx . map parseDom | 131 | parse BlockCtx = fmap mconcat . mapM mergeResult' . groupBy sameCtx . map parseDom | 
| 132 | where | ||
| 133 | sameCtx a b = (hasLineCtx a && hasLineCtx b) || (hasBlockCtx a && hasBlockCtx b) | ||
| 134 | mergeResult' xs | ||
| 135 | | hasLineCtx `all` xs = Line <$> mergeResult LineCtx xs | ||
| 136 | | otherwise = mergeResult BlockCtx xs | ||
| 137 | parse ctx = mergeResult ctx . map parseDom | ||
| 120 | 138 | ||
| 121 | asBlock :: CI Text -> [DomTree] -> Map (CI Text) Text -> Either SemanticError Block | 139 | asBlock :: CI Text -> [DomTree] -> Map (CI Text) Text -> Either SemanticError Block | 
| 122 | asBlock "VSpace" _ = Right . VSpace . lookupAttr "height" True 1 | 140 | asBlock "VSpace" _ = Right . VSpace . lookupAttr "height" True 1 | 
