Markup: make markup support multi-line strings (fixes #41)

This commit is contained in:
Jonathan Daugherty 2016-01-23 15:55:23 -08:00
parent 01bafb0b5b
commit 568df56630
3 changed files with 25 additions and 12 deletions

View File

@ -7,9 +7,12 @@ import qualified Graphics.Vty as V
import Brick.Main (App(..), defaultMain, resizeOrQuit, neverShowCursor)
import Brick.Types
( Widget
, Padding(..)
)
import Brick.Widgets.Core
( (<=>)
, (<+>)
, padLeft
)
import Brick.Util (on, fg)
import Brick.Markup (markup, (@?))
@ -17,10 +20,11 @@ import Brick.AttrMap (attrMap, AttrMap)
import Data.Text.Markup ((@@))
ui :: Widget
ui = m1 <=> m2
ui = (m1 <=> m2) <+> (padLeft (Pad 1) m3)
where
m1 = markup $ ("Hello" @@ fg V.blue) <> ", " <> ("world!" @@ fg V.red)
m2 = markup $ ("Hello" @? "keyword1") <> ", " <> ("world!" @? "keyword2")
m3 = markup $ ("Hello," @? "keyword1") <> "\n" <> ("world!" @? "keyword2")
theMap :: AttrMap
theMap = attrMap V.defAttr

View File

@ -17,7 +17,7 @@ import qualified Data.Text as T
import Data.Text.Markup
import Data.Default (def)
import Graphics.Vty (Attr, horizCat, string)
import Graphics.Vty (Attr, vertCat, horizCat, string)
import Brick.AttrMap
import Brick.Types
@ -47,8 +47,11 @@ instance GetAttr AttrName where
markup :: (Eq a, GetAttr a) => Markup a -> Widget
markup m =
Widget Fixed Fixed $ do
let pairs = markupToList m
imgs <- forM pairs $ \(t, aSrc) -> do
a <- getAttr aSrc
return $ string a $ T.unpack t
return $ def & imageL .~ horizCat imgs
let markupLines = markupToList m
mkLine pairs = do
is <- forM pairs $ \(t, aSrc) -> do
a <- getAttr aSrc
return $ string a $ T.unpack t
return $ horizCat is
lineImgs <- mapM mkLine markupLines
return $ def & imageL .~ vertCat lineImgs

View File

@ -45,7 +45,7 @@ fromText = (@@ def)
-- | Extract the text from markup, discarding the markup metadata.
toText :: (Eq a) => Markup a -> T.Text
toText = T.concat . (fst <$>) . markupToList
toText = T.concat . (fst <$>) . concat . markupToList
-- | Set the metadata for a range of character positions in a piece of
-- markup. This is useful for, e.g., syntax highlighting.
@ -59,11 +59,17 @@ markupSet (start, len) val m@(Markup l) = if start < 0 || start + len > length l
(theOldEntries, theTail) = splitAt len theLongTail
theNewEntries = zip (fst <$> theOldEntries) (repeat val)
-- | Convert markup to a list of pairs in which each pair contains the
-- longest subsequence of characters having the same metadata.
markupToList :: (Eq a) => Markup a -> [(T.Text, a)]
markupToList (Markup thePairs) = toList thePairs
-- | Convert markup to a list of lines. Each line is represented by a
-- list of pairs in which each pair contains the longest subsequence of
-- characters having the same metadata.
markupToList :: (Eq a) => Markup a -> [[(T.Text, a)]]
markupToList (Markup thePairs) = toList <$> toLines [] [] thePairs
where
toLines ls cur [] = ls ++ [cur]
toLines ls cur ((ch, val):rest)
| ch == '\n' = toLines (ls ++ [cur]) [] rest
| otherwise = toLines ls (cur ++ [(ch, val)]) rest
toList [] = []
toList ((ch, val):rest) = (T.pack $ ch : (fst <$> matching), val) : toList remaining
where