ContentsIndex
TextDisplay
Contents
Text frames
The Display type class
Text frame tables
Description
The default representation of any type is the string and the show function, which returns a string for each element of an instance of the Show class. But sometimes, it is more intuitive, if a type is represented by a more three-dimensional layout. For that matter, we not only have a show function for many types to come, but also a textFrame converter, where a TextFrame is basically defined as a list of strings of equal length. Similar to the Show type class, we also define a Display type class.
Synopsis
type TextFrame = [String]
isNonSpaceWhite :: Char -> Bool
findTextFrameError :: [String] -> Maybe String
correctTextFrame :: [String] -> TextFrame
width :: TextFrame -> Int
height :: TextFrame -> Int
printTextFrame :: TextFrame -> IO ()
textFrameBox :: TextFrame -> TextFrame
textFrameBracket :: TextFrame -> TextFrame
defaultTextFrame :: Show a => a -> TextFrame
class Display a where
textFrame :: a -> TextFrame
display :: a -> IO ()
type TextFrameTable = [[TextFrame]]
columnWidthList :: TextFrameTable -> [Int]
rowHeightList :: TextFrameTable -> [Int]
correctTextFrameTable :: TextFrameTable -> TextFrameTable
bottomAlign :: TextFrameTable -> TextFrameTable
topAlign :: TextFrameTable -> TextFrameTable
centerAlign :: TextFrameTable -> TextFrameTable
leftAlign :: TextFrameTable -> TextFrameTable
rightAlign :: TextFrameTable -> TextFrameTable
middleAlign :: TextFrameTable -> TextFrameTable
normalTextFrameTable :: TextFrameTable -> TextFrameTable
plainMerge :: TextFrameTable -> TextFrame
gridMerge :: TextFrameTable -> TextFrame
Text frames
type TextFrame = [String]
A TextFrame is a list of strings. But for a correct TextFrame, there are more constraints that have to hold: 1. The strings must all be of equal length. 2. There must be no white space characters in a string, other than the space character ' '.
isNonSpaceWhite :: Char -> Bool
True if the character is any white space character, except the space character itself.
findTextFrameError :: [String] -> Maybe String
A TextFrame is correct iff all its strings are of equal length and (isNonSpaceWhite ch) is false for all characters ch.
correctTextFrame :: [String] -> TextFrame
Turns the argument string list into a correct version by adding spaces. But returns an error in case any string contains a character ch with (isNonSpaceWhite ch). IMPROVE the String instance of Display: new line characters should create new lines in the text frame and what about tabs etc? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
width :: TextFrame -> Int

The width of a TextFrame [str1,...,strN] is the maximal length of the strings str1,...,strN. In particular,

 (width []) == 0           (width [""]) == 0
height :: TextFrame -> Int
The height of a TextFrame [str1,...,strN] is N.
printTextFrame :: TextFrame -> IO ()
prints its TextFrame argument.
textFrameBox :: TextFrame -> TextFrame
surrounds the text frame with a solid line
textFrameBracket :: TextFrame -> TextFrame
surrounds the text frame with a square bracket
defaultTextFrame :: Show a => a -> TextFrame
(defaultTextFrame x) == [show x]
The Display type class
class Display a where
Methods
textFrame :: a -> TextFrame
display :: a -> IO ()
show/hide Instances
textFrame converts into a TextFrame. display prints the text frame (actually, display = printTextFrame . textFrame, i.e. to define an instance of Display, Actually, when an instance of Display is defined, only textFrame needs to be specified.
Text frame tables
type TextFrameTable = [[TextFrame]]

A TextFrameTable is a list of rows, where each cell is a TextFrame. For example,

 [[["aaa","aaa"],["b","b","b"]],
  [["cccccccc","cccccccc"],["ddddddddd","ddddddddd","ddddddddd"],["eeeee","eeeee","eeeee","eeeee"]],
  [["ff","ff"],[],["ggg","ggg","ggg","ggg"]]]

or, more intuitively in table layout

   "aaa"      "b"
   "aaa"      "b"
              "b"

   "cccccccc" "ddddddddd" "eeeee"
   "cccccccc" "ddddddddd" "eeeee"
              "ddddddddd" "eeeee"
                          "eeeee"

   "ff"                   "ggg"
   "ff"                   "ggg"
                          "ggg"
                          "ggg"
columnWidthList :: TextFrameTable -> [Int]
rowHeightList :: TextFrameTable -> [Int]

Column widths and row heights for the previous example text frame table tft are given by

 (columnWidthList tft) == [8,9,5]
 (rowHeightList tft)   == [3,4,4]
correctTextFrameTable :: TextFrameTable -> TextFrameTable
A TextFrameTable is said to be correct, if (1) each row has the same amount of cells, (2) there is no column of zero width, (3) there is no row of zero height. With correctTextFrameTable we remove these flaws.
bottomAlign :: TextFrameTable -> TextFrameTable
topAlign :: TextFrameTable -> TextFrameTable
centerAlign :: TextFrameTable -> TextFrameTable
leftAlign :: TextFrameTable -> TextFrameTable
rightAlign :: TextFrameTable -> TextFrameTable
middleAlign :: TextFrameTable -> TextFrameTable

A TextFrameTable is said to be normal, if it is correct and each of its TextFrame cells has the width of its according column and the height of its row. To convert a text frame table into a normal one, we need to perform two steps (in arbitrary order):

  • A row normalization, which makes all text frame cells in one row of equal height. We use three modes to achieve that: bottomAlign, topAlign and centerAlign.
  • A column normalization, which makes all text frame cells in one column of equal width. Again, we have three functions to do that: leftAlign, rightAlign, and middleAlign.

For example, given the correct text frame table tft, we obtain (we use _ for space characters):

   tft =                               leftAlign tft =                      middleAlign (leftAlign tft) =

   "aaa"      "b"         ""           "aaa ____" "b________" "_____"       "aaa_____" "b________" "_____"
   "aaa"      "b"                      "aaa_____" "b________"               "aaa_____" "b________" "_____"
              "b"                                 "b________"               "________" "b________" "_____"

   "cccccccc" "ddddddddd" "eeeee"      "cccccccc" "ddddddddd" "eeeee"       "________" "ddddddddd" "eeeee"
   "cccccccc" "ddddddddd" "eeeee"      "cccccccc" "ddddddddd" "eeeee"       "cccccccc" "ddddddddd" "eeeee"
              "ddddddddd" "eeeee"                 "ddddddddd" "eeeee"       "cccccccc" "ddddddddd" "eeeee"
                          "eeeee"                             "eeeee"       "________" "_________" "eeeee"

   "ff"                   "ggg"        "ff______" "_________" "ggg__"       "________" "_________" "ggg__"
   "ff"                   "ggg"        "ff______"             "ggg__"       "ff______" "_________" "ggg__"
                          "ggg"                               "ggg__"       "ff______" "_________" "ggg__"
                          "ggg"                               "ggg__"       "________" "_________" "ggg__"
normalTextFrameTable :: TextFrameTable -> TextFrameTable

The default way to convert any text frame table into a normal one is defined by the normalTextFrameTable function, which is defined by

 normalTextFrameTable = middleAlign . centerAlign . correctTextFrameTable
plainMerge :: TextFrameTable -> TextFrame
gridMerge :: TextFrameTable -> TextFrame

There is a plainMerge and a gridMerge to turn a normal text frame table into a single text frame. For the example,

   tft =                              plainMerge tft =               gridMerge tft =

   "___aaa__" "____b____" "_____"     "___aaa______b_________"       "+----------+-----------+-------+"
   "___aaa__" "____b____" "_____"     "___aaa______b_________"       "| ___aaa__ | ____b____ | _____ |"
   "________" "____b____" "_____"     "____________b_________"       "| ___aaa__ | ____b____ | _____ |"
                                      "________dddddddddeeeee"       "| ________ | ____b____ | _____ |"
   "________" "ddddddddd" "eeeee"     "ccccccccdddddddddeeeee"       "+----------+-----------+-------+"
   "cccccccc" "ddddddddd" "eeeee"     "ccccccccdddddddddeeeee"       "| ________ | ddddddddd | eeeee |"
   "cccccccc" "ddddddddd" "eeeee"     "_________________eeeee"       "| cccccccc | ddddddddd | eeeee |"
   "________" "_________" "eeeee"     "__________________ggg_"       "| cccccccc | ddddddddd | eeeee |"
                                      "___ff_____________ggg_"       "| ________ | _________ | eeeee |"
   "________" "_________" "_ggg_"     "___ff_____________ggg_"       "+----------+-----------+-------+"
   "___ff___" "_________" "_ggg_"     "__________________ggg_"       "| ________ | _________ | _ggg_ |"
   "___ff___" "_________" "_ggg_"                                    "| ___ff___ | _________ | _ggg_ |"
   "________" "_________" "_ggg_"                                    "| ___ff___ | _________ | _ggg_ |"
                                                                     "| ________ | _________ | _ggg_ |"
                                                                     "+----------+-----------+-------+"
Produced by Haddock version 2.4.2