40 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
			
		
		
	
	
			40 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
-- | Calculate the width of String and Text, being aware of wide characters.
 | 
						|
 | 
						|
module Text.WideString (
 | 
						|
  -- * Text Builders which keep track of length
 | 
						|
  WideBuilder(..),
 | 
						|
  wbUnpack,
 | 
						|
  wbToText,
 | 
						|
  wbFromText
 | 
						|
  ) where
 | 
						|
 | 
						|
import Data.Text (Text)
 | 
						|
import qualified Data.Text.Lazy as TL
 | 
						|
import qualified Data.Text.Lazy.Builder as TB
 | 
						|
import Text.DocLayout (realLength)
 | 
						|
 | 
						|
 | 
						|
-- | Helper for constructing Builders while keeping track of text width.
 | 
						|
data WideBuilder = WideBuilder
 | 
						|
  { wbBuilder :: !TB.Builder
 | 
						|
  , wbWidth   :: !Int
 | 
						|
  } deriving (Show)
 | 
						|
 | 
						|
instance Semigroup WideBuilder where
 | 
						|
  WideBuilder x i <> WideBuilder y j = WideBuilder (x <> y) (i + j)
 | 
						|
 | 
						|
instance Monoid WideBuilder where
 | 
						|
  mempty = WideBuilder mempty 0
 | 
						|
 | 
						|
-- | Convert a WideBuilder to a strict Text.
 | 
						|
wbToText :: WideBuilder -> Text
 | 
						|
wbToText = TL.toStrict . TB.toLazyText . wbBuilder
 | 
						|
 | 
						|
-- | Convert a strict Text to a WideBuilder.
 | 
						|
wbFromText :: Text -> WideBuilder
 | 
						|
wbFromText t = WideBuilder (TB.fromText t) (realLength t)
 | 
						|
 | 
						|
-- | Convert a WideBuilder to a String.
 | 
						|
wbUnpack :: WideBuilder -> String
 | 
						|
wbUnpack = TL.unpack . TB.toLazyText . wbBuilder
 |