BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Input / Output
.NET 3.5+

A Text-Based Box Generator

When working with console applications, or when adding to a log file, it is often useful to highlight elements of the text. One way in which to achieve this is to draw a box around the text, using standard symbols from the available character set.

Constructors

We'll configure each BoxGenerator instance in the constructor, either by selecting the appropriate configuration string or by creating a new one from a single character. When using the default constructor, the BoxGenerator will use the default border string, copying it into the _border field, as follows:

public BoxGenerator()
{
    _border = _defaultBorder;
}

Let's add a second constructor that permits the selection of one of the styles from the BoxStyle enumeration. This constructor selects one of the preset border strings and copies it into the _border field. If an unknown style, or the single character style, is passed to the constructor's parameter, we'll use the default border.

public BoxGenerator(BoxStyle style)
{
    switch (style)
    {
        case BoxStyle.Single: _border = _singleLine; break;
        case BoxStyle.Double: _border = _doubleLine; break;
        default: _border = _defaultBorder; break;
    }
}

Finally we can add the constructor that sets up the BoxGenerator to use a single character for every part of the box's border:

public BoxGenerator(char character)
{
    _border = new string(character, 8);
}

Adding the GenerateBox Method

The final job is to add the method that converts a string array into a string containing the text and the box. Depending upon the use of the generator, you might want to restrict the width of the box. To cater for this we'll use two parameters. The first will be the string array and the second the maximum width of the text within the box. The box itself could be two characters wider than this.

There are several ways in which we can use the maximum width. We could truncate any lines of text that are longer than the value. We could also split the lines, possibly using a word-wrapping algorithm, and wrap the entire text in a box. For the BoxGenerator class we'll use the first approach. It would be relatively easy to split the lines before adding the box if this is required.

There are four parts to the process of surrounding the text with a box. Firstly we need to make sure that the arguments are valid; the string array must not be null and the maximum width must be a positive value. Next we need to determine the width of the box, which may be any size up to the stated maximum. The third step is to pad or truncate the lines of text to make every line the same length, ready for the left and right borders to be added. Finally, the padded text needs to be surrounded with the box.

Each stage, other than validation, can be performed in a private method. We'll call each from the single, public method of the class, "GenerateBox":

public string GenerateBox(string[] text, int maxInternalWidth)
{
    if (text == null) throw new ArgumentNullException("text");
    if (maxInternalWidth < 1) throw new ArgumentException("width too small");

    int width = GetWidth(text, maxInternalWidth);
    var padded = PadText(text, width);
    return BuildBox(padded, width);
}

Determining the Text Width

If any line of the provided text is greater in length than the maximum length supplied to the GenerateBox method, we'll create a box with an internal size matching the maximum length and truncate any lines that are too long to fit. If all of the lines of text are shorter than the maximum internal width, we'll make the inside of the box be the same width as the longest line.

To determine the width, we therefore need to find the longest line of text and compare it to the maximum size. The smaller of these two values is the width we require. We'll calculate the length in the private, GetWidth method:

private int GetWidth(string[] text, int maxWidth)
{
    int largest = text.Max(s => s.Length);
    return Math.Min(largest, maxWidth);
}

NB: If you are using a version of the .NET framework prior to version 3.5, you could replace the LINQ query with a foreach loop and a conditional statement.

Padding the Text

The second private method pads or truncates the text to the correct length. The simplest way to do this is using the PadRight or Substring methods to add spaces to the end of the string or extract the start of the line respectively:

private IEnumerable<string> PadText(string[] text, int width)
{
    return text.Select(s =>
        s.Length > width ? s.Substring(0, width) : s.PadRight(width, ' '));
}
9 March 2014