Skip to content

Commit

Permalink
Implement functionality to handle table header columns spans
Browse files Browse the repository at this point in the history
- Add functionality to process column headers using an opt-in config TableHeaderColumnSpanHandling
- Add unit test
- Fixes GH-392
  • Loading branch information
mysticmind committed Jun 18, 2024
1 parent d9b2172 commit 8d2f058
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| col1 | col2 | col2 | col3 |
| --- | --- | --- | --- |
| data1 | data2.1 | data2.2 | data3 |
15 changes: 15 additions & 0 deletions src/ReverseMarkdown.Test/ConverterTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using ReverseMarkdown.Converters;
using VerifyTests;
using VerifyXunit;
using Xunit;
Expand Down Expand Up @@ -1350,5 +1351,19 @@ public Task When_SuppressNewlineFlag_PrefixDiv_Should_Be_Empty()
SuppressDivNewlines = true
});
}

[Fact]
public Task WhenTable_WithColSpan_TableHeaderColumnSpansHandling_ThenConvertToGFMTable()
{
var html =
"<table><tr><th>col1</th><th colspan=\"2\">col2</th><th>col3</th></tr><tr><td>data1</td><td>data2.1</td><td>data2.2</td><td>data3</td></tr></table>";

var config = new Config
{
UnknownTags = Config.UnknownTagsOption.Bypass,
TableHeaderColumnSpanHandling = true
};
return CheckConversion(html, config);
}
}
}
7 changes: 5 additions & 2 deletions src/ReverseMarkdown/Config.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Linq;
using System;
using System.Linq;

namespace ReverseMarkdown
{
Expand Down Expand Up @@ -80,6 +78,11 @@ public enum TableWithoutHeaderRowHandlingOption
EmptyRow
}

/// <summary>
/// Set this flag to handle table header column with column spans
/// </summary>
public bool TableHeaderColumnSpanHandling { get; set; } = false;


/// <summary>
/// Determines whether url is allowed: WhitelistUriSchemes contains no elements or contains passed url.
Expand Down
16 changes: 15 additions & 1 deletion src/ReverseMarkdown/Converters/Td.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using HtmlAgilityPack;
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;

namespace ReverseMarkdown.Converters
Expand All @@ -22,7 +24,8 @@ public override string Convert(HtmlNode node)
.Chomp()
.Replace(Environment.NewLine, "<br>");

return $" {content} |";
var colSpan = GetColSpan(node);
return string.Concat(Enumerable.Repeat($" {content} |", colSpan));
}

/// <summary>
Expand Down Expand Up @@ -55,5 +58,16 @@ public override string Convert(HtmlNode node)
}
return false;
}

private int GetColSpan(HtmlNode node)
{
var colSpan = 1;

if (Converter.Config.TableHeaderColumnSpanHandling && node.Name == "th")
{
colSpan = node.GetAttributeValue("colspan", 1);
}
return colSpan;
}
}
}
32 changes: 25 additions & 7 deletions src/ReverseMarkdown/Converters/Tr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public override string Convert(HtmlNode node)

if (IsTableHeaderRow(node) || UseFirstRowAsHeaderRow(node))
{
underline = UnderlineFor(node, indent);
underline = UnderlineFor(node, indent, Converter.Config.TableHeaderColumnSpanHandling);
}

return $"{indent}|{content}{Environment.NewLine}{underline}";
Expand Down Expand Up @@ -58,35 +58,53 @@ private static bool IsTableHeaderRow(HtmlNode node)
return node.ChildNodes.FindFirst("th") != null;
}

private static string UnderlineFor(HtmlNode node, string indent)
private static string UnderlineFor(HtmlNode node, string indent, bool tableHeaderColumnSpanHandling)
{
var nodes = node.ChildNodes.Where(x => x.Name == "th" || x.Name == "td").ToList();

var cols = new List<string>();
foreach (var styles in nodes.Select(nd => StringUtils.ParseStyle(nd.GetAttributeValue("style", ""))))
foreach (var nd in nodes)
{
var colSpan = GetColSpan(nd, tableHeaderColumnSpanHandling);
var styles = StringUtils.ParseStyle(nd.GetAttributeValue("style", ""));
styles.TryGetValue("text-align", out var align);

string content;
switch (align?.Trim())
{
case "left":
cols.Add(":---");
content = ":---";
break;
case "right":
cols.Add("---:");
content ="---:";
break;
case "center":
cols.Add(":---:");
content = ":---:";
break;
default:
cols.Add("---");
content ="---";
break;
}

for (var i = 0; i < colSpan; i++) {
cols.Add(content);
}
}

var colsAggregated = string.Join(" | ", cols);

return $"{indent}| {colsAggregated} |{Environment.NewLine}";
}

private static int GetColSpan(HtmlNode node, bool tableHeaderColumnSpanHandling)
{
var colSpan = 1;

if (tableHeaderColumnSpanHandling && node.Name == "th")
{
colSpan = node.GetAttributeValue("colspan", 1);
}
return colSpan;
}
}
}

0 comments on commit 8d2f058

Please sign in to comment.