align :: [[String]] -> [Alignment] -> [[String]]
align rows columnFormats = map alignRow rows
    where
        alignRow = zipWith alignCell columnFormats
        alignCell (LeftAligned w) cell = ' ' : cell' ++ replicate (w - length cell') ' ' ++ " "
            where cell' = strip cell
        alignCell (RightAligned w) cell = ' ' : replicate (w - length cell') ' ' ++ cell' ++ " "
            where cell' = strip cell
        strip = halfStrip . halfStrip where halfStrip = dropWhile isSpace . reverse

-- remove new lines in cells
align :: [[String]] -> [Alignment] -> [[String]]
align rows columnFormats = map alignRow rows
    where
        alignRow = zipWith alignCell columnFormats
        alignCell (LeftAligned w) cell = ' ' : cell' ++ replicate (w - length cell') ' ' ++ " "
            where cell' = strip cell
        alignCell (RightAligned w) cell = ' ' : replicate (w - length cell') ' ' ++ cell' ++ " "
            where cell' = strip cell
        strip = halfStrip . halfStrip where halfStrip = dropWhile isSpace . reverse

-- remove new lines in cells
align rows columnFormats = map alignRow rows
    where
        alignRow = zipWith alignCell columnFormats
        alignCell (LeftAligned w) cell = ' ' : cell' ++ replicate (w - length cell') ' ' ++ " "
            where cell' = strip cell
        alignCell (RightAligned w) cell = ' ' : replicate (w - length cell') ' ' ++ cell' ++ " "
            where cell' = strip cell
        strip = halfStrip . halfStrip where halfStrip = dropWhile isSpace . reverse

-- remove new lines in cells