align-equal-0.1.1.0: src/Data/Text/AlignEqual.hs
{-# LANGUAGE OverloadedStrings #-}
-- | A module providing functions for text alignment and padding.
module Data.Text.AlignEqual where
import Data.Text (Text)
import qualified Data.Text as T
import Safe
-- | Calculates the number of characters preceding the first '=' sign in a text line.
--
-- >>> prefixLength "key=value"
-- 3
-- >>> prefixLength "a=b"
-- 1
-- >>> prefixLength "noequals"
-- 8
prefixLength
:: Text
-- ^ The input text line
-> Int
-- ^ The number of characters before the first '=' sign
prefixLength line = T.length prefix
where
(prefix, _) = T.breakOn "=" line
-- | Adjusts the prefix of a text line to a desired length by adding padding.
--
-- >>> adjustLine 5 "key=value"
-- "key =value"
-- >>> adjustLine 3 "a=b"
-- "a =b"
adjustLine
:: Int
-- ^ The desired prefix length
-> Text
-- ^ The text line to pad
-> Text
-- ^ The padded text line
adjustLine desiredPrefixLength oldLine = newLine
where
(prefix, suffix) = T.breakOn "=" oldLine
actualPrefixLength = T.length prefix
additionalSpaces = desiredPrefixLength - actualPrefixLength
spaces = T.replicate additionalSpaces " "
newLine = T.concat [ prefix, spaces, suffix ]
-- | Processes multi-line text to align all '=' signs across lines.
-- Adjusts the prefix length of each line to match the maximum prefix length.
--
-- >>> adjustText "key=value\na=b"
-- "key=value\na =b"
-- >>> adjustText "x=y\nlong=var"
-- "x =y\nlong=var"
adjustText
:: Text
-- ^ The input text (possibly multi-line)
-> Text
-- ^ The aligned text
adjustText oldText = newText
where
oldLines = T.lines oldText
prefixLengths = map prefixLength oldLines
newLines =
case maximumMay prefixLengths of
Nothing ->
[]
Just desiredPrefixLength ->
map (adjustLine desiredPrefixLength) oldLines
newText = T.unlines newLines