Skip to content

Commit 14467a4

Browse files
committed
Implemented more table renderers. Added Demo app.
1 parent 5623c06 commit 14467a4

15 files changed

Lines changed: 222 additions & 34 deletions

DemoApp/DemoApp.csproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<LangVersion>latest</LangVersion>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\TextTableBuilder\TextTableBuilder.csproj" />
13+
</ItemGroup>
14+
</Project>

DemoApp/Program.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using TextTableBuilder;
2+
using TextTableBuilder.TableRenderers;
3+
4+
var table = new Table()
5+
.AddColumns("No", "Name", "Position", "^Salary^")
6+
.AddRow(1, "Bill Gates", "Founder Microsoft", 10000m)
7+
.AddRow(2, "Steve Jobs", "Founder Apple", 1200000m)
8+
.AddRow(3, "Larry Page", "Founder Google", 1100000m)
9+
.AddRow(4, "Mark Zuckerberg", "Founder Facebook", 1300000m);
10+
11+
var renderers = new ITableRenderer[] {
12+
new DefaultTableRenderer(),
13+
new MinimalTableRenderer(),
14+
new MSDOSTableRenderer(),
15+
new SimpleLineTableRenderer(),
16+
new SingleLineTableRenderer(),
17+
new DoubleLineTableRenderer(),
18+
new HatchedTableRenderer()
19+
};
20+
21+
var tablebuilder = new TableBuilder();
22+
tablebuilder.TypeHandlers.AddHandler<decimal>((v, f) => $"$ {v.ToString("N2")}");
23+
24+
foreach (var r in renderers) {
25+
Console.Write($"{r.GetType().Name}:\n\n");
26+
Console.Write(tablebuilder.Build(table, r));
27+
Console.Write("\n\n");
28+
}

README.md

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -363,49 +363,101 @@ The `DefaultObjectHandler`, by default, pads all rows with missing values with `
363363

364364
The TextTableBuilder uses an `ITableRenderer` to do the actual 'rendering' of the table. The TableRenderer is provided with `RenderColums`, which provide column information, and an `IEnumerable<string[]>` which represents the rows and values. The values have been formatted at this point; the table renderer takes care of aligning, padding etc.
365365

366-
By default, the TextTableBuilder uses the `DefaultTableRenderer` which produced the above examples. Two other, very simple, renderers are provided. These are the `MinimalTableRenderer` and `MSDOSTableRenderer`.
366+
By default, the TextTableBuilder uses the `DefaultTableRenderer` which produced the above examples. A few other, very simple, renderers are provided. These are the `MinimalTableRenderer` and `MSDOSTableRenderer`, `SimpleLineTableRenderer`, `SingleLineTableRenderer`, `DoubleLineTableRenderer` and `HatchedTableRenderer`.
367367

368368
To use a specific `ITableRenderer` you pass one to the `Build()` method:
369369

370-
371370
```c#
372371
Console.WriteLine(tablebuilder.Build(table, new MSDOSTableRenderer()));
373372
```
374373

375374
Going back to our [very first example](#quickstart), the following styles are currently provided. More _may_ be added in the future (as well as ANSI color support etc.) but it's also trivial to build your own; just implement `ITableRenderer`:
376375

377-
### DefaultTableRenderer
376+
### DefaultTableRenderer:
378377

379378
```cmd
380-
No | Name | Position | Salary
381-
-- | --------------- | ----------------- | ---------
382-
1 | Bill Gates | Founder Microsoft | 10,000
383-
2 | Steve Jobs | Founder Apple | 1,200,000
384-
3 | Larry Page | Founder Google | 1,100,000
385-
4 | Mark Zuckerberg | Founder Facebook | 1,300,000
379+
No | Name | Position | Salary
380+
----|-----------------|-------------------|----------------
381+
1 | Bill Gates | Founder Microsoft | $ 10,000.00
382+
2 | Steve Jobs | Founder Apple | $ 1,200,000.00
383+
3 | Larry Page | Founder Google | $ 1,100,000.00
384+
4 | Mark Zuckerberg | Founder Facebook | $ 1,300,000.00
385+
```
386+
387+
### MinimalTableRenderer:
388+
389+
```cmd
390+
No Name Position Salary
391+
1 Bill Gates Founder Microsoft $ 10,000.00
392+
2 Steve Jobs Founder Apple $ 1,200,000.00
393+
3 Larry Page Founder Google $ 1,100,000.00
394+
4 Mark Zuckerberg Founder Facebook $ 1,300,000.00
395+
```
396+
397+
### MSDOSTableRenderer:
398+
399+
```cmd
400+
No ║ Name ║ Position ║ Salary
401+
════║═════════════════║═══════════════════║════════════════
402+
1 ║ Bill Gates ║ Founder Microsoft ║ $ 10,000.00
403+
2 ║ Steve Jobs ║ Founder Apple ║ $ 1,200,000.00
404+
3 ║ Larry Page ║ Founder Google ║ $ 1,100,000.00
405+
4 ║ Mark Zuckerberg ║ Founder Facebook ║ $ 1,300,000.00
406+
```
407+
408+
### SimpleLineTableRenderer:
409+
410+
```cmd
411+
+----+-----------------+-------------------+----------------+
412+
| No | Name | Position | Salary |
413+
+----+-----------------+-------------------+----------------+
414+
| 1 | Bill Gates | Founder Microsoft | $ 10,000.00 |
415+
| 2 | Steve Jobs | Founder Apple | $ 1,200,000.00 |
416+
| 3 | Larry Page | Founder Google | $ 1,100,000.00 |
417+
| 4 | Mark Zuckerberg | Founder Facebook | $ 1,300,000.00 |
418+
+----+-----------------+-------------------+----------------+
419+
```
420+
421+
### SingleLineTableRenderer:
422+
423+
```cmd
424+
┌────┬─────────────────┬───────────────────┬────────────────┐
425+
│ No │ Name │ Position │ Salary │
426+
├────┼─────────────────┼───────────────────┼────────────────┤
427+
│ 1 │ Bill Gates │ Founder Microsoft │ $ 10,000.00 │
428+
│ 2 │ Steve Jobs │ Founder Apple │ $ 1,200,000.00 │
429+
│ 3 │ Larry Page │ Founder Google │ $ 1,100,000.00 │
430+
│ 4 │ Mark Zuckerberg │ Founder Facebook │ $ 1,300,000.00 │
431+
└────┴─────────────────┴───────────────────┴────────────────┘
386432
```
387433

388-
### MinimalTableRenderer
434+
### DoubleLineTableRenderer:
389435

390436
```cmd
391-
No Name Position Salary
392-
1 Bill Gates Founder Microsoft 10,000
393-
2 Steve Jobs Founder Apple 1,200,000
394-
3 Larry Page Founder Google 1,100,000
395-
4 Mark Zuckerberg Founder Facebook 1,300,000
437+
╔════╦═════════════════╦═══════════════════╦════════════════╗
438+
║ No ║ Name ║ Position ║ Salary ║
439+
╠════╬═════════════════╬═══════════════════╬════════════════╣
440+
║ 1 ║ Bill Gates ║ Founder Microsoft ║ $ 10,000.00 ║
441+
║ 2 ║ Steve Jobs ║ Founder Apple ║ $ 1,200,000.00 ║
442+
║ 3 ║ Larry Page ║ Founder Google ║ $ 1,100,000.00 ║
443+
║ 4 ║ Mark Zuckerberg ║ Founder Facebook ║ $ 1,300,000.00 ║
444+
╚════╩═════════════════╩═══════════════════╩════════════════╝
396445
```
397446

398-
### MSDOSTableRenderer
447+
### HatchedTableRenderer:
399448

400449
```cmd
401-
No║Name ║Position ║ Salary
402-
══║═══════════════║═════════════════║═════════
403-
1 ║Bill Gates ║Founder Microsoft║ 10,000
404-
2 ║Steve Jobs ║Founder Apple ║1,200,000
405-
3 ║Larry Page ║Founder Google ║1,100,000
406-
4 ║Mark Zuckerberg║Founder Facebook ║1,300,000
450+
/----+-----------------+-------------------+----------------\
451+
| No | Name | Position | Salary |
452+
+----+-----------------+-------------------+----------------+
453+
| 1 | Bill Gates | Founder Microsoft | $ 10,000.00 |
454+
| 2 | Steve Jobs | Founder Apple | $ 1,200,000.00 |
455+
| 3 | Larry Page | Founder Google | $ 1,100,000.00 |
456+
| 4 | Mark Zuckerberg | Founder Facebook | $ 1,300,000.00 |
457+
\----+-----------------+-------------------+----------------/
407458
```
408459

460+
409461
## Example
410462

411463
With all the examples above demonstrating a specific option each, you may not have noticed how easy this package can make your life (that's what it's meant to do). So here's an example that shows typical usage. Assuming you have a `Person` class/record but you can't (or don't want to) 'pollute' it with `ColumnOrder`-attributes:

TextTableBuilder.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1212
README.md = README.md
1313
EndProjectSection
1414
EndProject
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoApp", "DemoApp\DemoApp.csproj", "{EE019203-07E9-4282-8436-074DCA55557F}"
16+
EndProject
1517
Global
1618
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1719
Debug|Any CPU = Debug|Any CPU
@@ -26,6 +28,10 @@ Global
2628
{86252320-3AF7-41F2-8851-E4C9CE9A4A1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
2729
{86252320-3AF7-41F2-8851-E4C9CE9A4A1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
2830
{86252320-3AF7-41F2-8851-E4C9CE9A4A1D}.Release|Any CPU.Build.0 = Release|Any CPU
31+
{EE019203-07E9-4282-8436-074DCA55557F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32+
{EE019203-07E9-4282-8436-074DCA55557F}.Debug|Any CPU.Build.0 = Debug|Any CPU
33+
{EE019203-07E9-4282-8436-074DCA55557F}.Release|Any CPU.ActiveCfg = Release|Any CPU
34+
{EE019203-07E9-4282-8436-074DCA55557F}.Release|Any CPU.Build.0 = Release|Any CPU
2935
EndGlobalSection
3036
GlobalSection(SolutionProperties) = preSolution
3137
HideSolutionNode = FALSE

TextTableBuilder/Table.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,15 @@ public Table AddColumns(IEnumerable<Column> columns)
4040
public Table AddColumns(IEnumerable<string> columns)
4141
=> AddColumns(columns.Select(c => Column.FromName(c)));
4242

43+
public Table AddColumns(params string[] columns)
44+
=> AddColumns(columns.Select(c => Column.FromName(c)));
45+
4346
public Table AddRow(params object?[] values)
4447
=> AddRowImpl(new ValueRow(values));
4548

49+
public Table AddRow(params string?[] values)
50+
=> AddRowImpl(new ValueRow(values));
51+
4652
public Table AddRow(Row row)
4753
=> AddRowImpl(row);
4854

TextTableBuilder/TableRenderers/BaseTableRenderer.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,22 @@ namespace TextTableBuilder.TableRenderers;
44

55
public abstract class BaseTableRenderer : ITableRenderer
66
{
7+
public const char DEFAULTPADDINGCHAR = ' ';
8+
public const int DEFAULTCELLPADDING = 1;
9+
710
public abstract string Render(ReadOnlyCollection<RenderColumn> columns, IEnumerable<string[]> rows);
811

9-
protected static string RenderRow(string columnSeparator, IEnumerable<string> values)
10-
=> string.Join(columnSeparator, values);
12+
protected static string RenderRow(char columnSeparator, IEnumerable<string> values, char paddingChar, int cellPadding)
13+
=> string.Join(columnSeparator.ToString(), values);
1114

12-
protected static string RenderCell(string value, Align align, int width, char paddingChar)
13-
=> AlignString(TruncateString(value, align, width), align, width, paddingChar);
15+
protected static string RenderLine(char left, char mid, char right, char pad, ReadOnlyCollection<RenderColumn> widths, int cellPadding)
16+
=> $"{left}{string.Join(mid.ToString(), widths.Select(c => new string(pad, c.Width + (cellPadding * 2))))}{right}";
17+
18+
protected static string RenderCell(string value, Align align, int width, char paddingChar, int cellPadding)
19+
=> PadCell(AlignString(TruncateString(value, align, width), align, width, paddingChar), paddingChar, cellPadding);
20+
21+
protected static string PadCell(string value, char paddingChar, int count)
22+
=> value.PadLeft(value.Length + count, paddingChar).PadRight(value.Length + (count * 2), paddingChar);
1423

1524
protected static string AlignString(string value, Align align, int width, char paddingChar)
1625
=> align switch
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Collections.ObjectModel;
2+
using System.Text;
3+
4+
namespace TextTableBuilder.TableRenderers;
5+
6+
public class BorderedTableRenderer : BaseTableRenderer
7+
{
8+
private readonly string _chars;
9+
private readonly char _paddingchar;
10+
private readonly int _cellpadding;
11+
12+
public BorderedTableRenderer(string borderChars, int cellPadding = DEFAULTCELLPADDING, char paddingChar = DEFAULTPADDINGCHAR)
13+
{
14+
if (borderChars.Length != 15)
15+
throw new Exception($"{nameof(borderChars)} must be exactly 15 characters long");
16+
_chars = borderChars;
17+
_cellpadding = cellPadding;
18+
_paddingchar = paddingChar;
19+
}
20+
21+
public override string Render(ReadOnlyCollection<RenderColumn> columns, IEnumerable<string[]> rows)
22+
{
23+
var sb = new StringBuilder();
24+
25+
// Top border
26+
sb.AppendLine(RenderLine(_chars[0], _chars[2], _chars[3], _chars[1], columns, _cellpadding));
27+
28+
// Headers
29+
sb.AppendLine($"{_chars[4]}{RenderRow(_chars[5], columns.Select(c => RenderCell(c.Name, c.HeaderAlign, c.Width, _paddingchar, _cellpadding)), _paddingchar, _cellpadding)}{_chars[6]}");
30+
31+
// Header separator
32+
sb.AppendLine(RenderLine(_chars[7], _chars[9], _chars[10], _chars[8], columns, _cellpadding));
33+
34+
// Rows
35+
foreach (var row in rows)
36+
{
37+
sb.AppendLine($"{_chars[4]}{RenderRow(_chars[5], row.Select((value, i) => RenderCell(value, columns[i].ValueAlign, columns[i].Width, _paddingchar, _cellpadding)), _paddingchar, _cellpadding)}{_chars[6]}");
38+
}
39+
40+
// Bottom border
41+
sb.AppendLine(RenderLine(_chars[11], _chars[13], _chars[14], _chars[12], columns, _cellpadding));
42+
return sb.ToString();
43+
}
44+
}

TextTableBuilder/TableRenderers/DefaultTableRenderer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
public class DefaultTableRenderer : SimpleTableRenderer
44
{
5-
public DefaultTableRenderer() : base(' ', " | ", '-') { }
5+
public DefaultTableRenderer(int cellPadding = DEFAULTCELLPADDING, char paddingChar = DEFAULTPADDINGCHAR)
6+
: base('|', '-', cellPadding, paddingChar) { }
67
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace TextTableBuilder.TableRenderers;
2+
3+
public class DoubleLineTableRenderer : BorderedTableRenderer {
4+
public DoubleLineTableRenderer(int cellPadding = DEFAULTCELLPADDING, char paddingChar = DEFAULTPADDINGCHAR)
5+
: base("╔═╦╗║║║╠═╬╣╚═╩╝", cellPadding, paddingChar) { }
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace TextTableBuilder.TableRenderers;
2+
3+
public class HatchedTableRenderer : BorderedTableRenderer {
4+
public HatchedTableRenderer(int cellPadding = DEFAULTCELLPADDING, char paddingChar = DEFAULTPADDINGCHAR)
5+
: base(@"/-+\|||+-++\-+/", cellPadding, paddingChar) { }
6+
}

0 commit comments

Comments
 (0)