| Safe Haskell | Safe-Infered |
|---|
TextDisplay
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.
- 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
- 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
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 -> BoolSource
True if the character is any white space character, except the space character itself.
findTextFrameError :: [String] -> Maybe StringSource
A TextFrame is correct iff all its strings are of equal length and (isNonSpaceWhite ch) is false for all characters ch.
correctTextFrame :: [String] -> TextFrameSource
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? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The width of a TextFrame [str1,...,strN] is the maximal length of the strings str1,...,strN. In particular,
(width []) == 0 (width [""]) == 0
The height of a TextFrame [str1,...,strN] is N.
printTextFrame :: TextFrame -> IO ()Source
prints its TextFrame argument.
surrounds the text frame with a solid line
surrounds the text frame with a square bracket
defaultTextFrame :: Show a => a -> TextFrameSource
(defaultTextFrame x) == [show x]
The Display type class
Instances
| Display Bool | |
| Display Char | |
| Display Double | |
| Display Float | |
| Display Int | |
| Display Integer | |
| Display String | |
| Display () | |
| Display IForm | |
| (Ord a, Display a) => Display [Valuator a] | |
| Display a => Display (PropForm a) | |
| Display a => Display (MultiTruthTable a) | |
| Display a => Display (TruthTable a) | |
| Display a => Display (Valuator a) | |
| Display a => Display (LiteralPair a) | |
| Display a => Display (MixForm a) | |
| Display a => Display (XPCNF a) | |
| Display a => Display (XPDNF a) | |
| Display a => Display (XForm a) |
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]]Source
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]Source
rowHeightList :: TextFrameTable -> [Int]Source
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]
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.
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,topAlignandcenterAlign. - 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, andmiddleAlign.
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__"
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
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_ |"
"+----------+-----------+-------+"