Created
April 14, 2016 06:15
-
-
Save kbilsted/d8d38a3b76da8096aa4fb9e7b3363427 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.IO; | |
using System.Text; | |
namespace MarkDownTableReformatter | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var path = args[0]; | |
var result = FormatBlock(File.ReadLines(path).ToArray()); | |
var text = MakeString(result); | |
File.WriteAllText(path + "2", text, Encoding.UTF8); | |
} | |
private static string MakeString(List<List<string>> lines) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
foreach (var line in lines) | |
{ | |
foreach (var cell in line) | |
sb.Append(cell); | |
sb.AppendLine(); | |
} | |
return sb.ToString(); | |
} | |
private static List<List<string>> FormatBlock(string[] textLines) | |
{ | |
var cellLines = textLines | |
.Select((x,i) => new {line=x.Trim(), lineno=i}) | |
.Where(x=>!string.IsNullOrWhiteSpace(x.line)) | |
.Select(x => SplitLine(x.line, x.lineno)) | |
.ToList(); | |
var maxColumnCount = cellLines.Select(line => line.Count).Max(); | |
NormalizeAllLinesToSameColumnCount(cellLines, maxColumnCount); | |
PadColumnsToSameWidth(maxColumnCount, cellLines); | |
return cellLines; | |
} | |
private static void PadColumnsToSameWidth(int maxColumnCount, List<List<string>> cellLines) | |
{ | |
for (int col = 0; col < maxColumnCount; col++) | |
{ | |
var maxColumnWidth = cellLines.Select(x => x[col].Length).Max(); | |
foreach (var cellLine in cellLines) | |
cellLine[col] = PadColumnToWidth(cellLine, col, maxColumnWidth); | |
} | |
} | |
private static string PadColumnToWidth(List<string> cellLine, int col, int maxColumnWidth) | |
{ | |
var cell = cellLine[col]; | |
if (cell.Length < maxColumnWidth) | |
return cell.Substring(0, cell.Length - 1).PadRight(maxColumnWidth-1) + cell.Last(); | |
return cell; | |
} | |
private static void NormalizeAllLinesToSameColumnCount(List<List<string>> cellLines, int maxColumns) | |
{ | |
foreach (var cellLine in cellLines) | |
{ | |
if (cellLine.Count < maxColumns) | |
{ | |
for (int i = 0; i < maxColumns - cellLine.Count; i++) | |
cellLine.Add("|"); | |
} | |
} | |
} | |
private static List<string> SplitLine(string line, int lineno) | |
{ | |
if (!line.StartsWith("^") && !line.StartsWith("|")) | |
throw new Exception(string.Format("Cannot parse line. Needs to start with characters ^ or | at line {0}. Content: '{1}'", lineno, line)); | |
char separator = line[0]; | |
List<string> elements = new List<string>(); | |
elements.Add(separator.ToString()); | |
int pos = 1; | |
while (pos < line.Length) | |
{ | |
var cell = GetCell(line, pos, separator, lineno); | |
pos += cell.Length; | |
elements.Add(" "+cell.Trim()); | |
} | |
return elements; | |
} | |
private static string GetCell(string line, int pos, char separator, int lineno) | |
{ | |
bool isInsideLinkScope = false; | |
for (int i = pos; i < line.Length; i++) | |
{ | |
if (isInsideLinkScope) | |
{ | |
if (line[i] == ']' && line.Length > i + 1 && line[i + 1] == ']') | |
{ | |
isInsideLinkScope = false; | |
i++; | |
} | |
continue; | |
} | |
if (line[i] == '[' && line.Length > i + 1 && line[i + 1] == '[') | |
{ | |
isInsideLinkScope = true; | |
i++; | |
continue; | |
} | |
if (line[i] == separator) | |
return line.Substring(pos, i - pos + 1); | |
} | |
if (isInsideLinkScope) | |
throw new Exception(string.Format("Did not find a closing link scope ']]' at line {0}", lineno)); | |
throw new Exception(string.Format("Did not find a separator '{0}' for cell at line {1}", separator, lineno)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment