Markdown Table Generator — Java source
Turn pipe, CSV, tab, semicolon, or space-separated data into a clean GitHub-Flavored Markdown table. Auto-detects the delimiter, pads columns, escapes pipes, and supports per-column alignment - all in your browser.
This is the Java implementation — the same logic the interactive tool runs, in a shareable, citable form.
// markdown-table — Java (17+) port: split delimiter-separated rows and render a padded GFM table, ported from src/lib/markdown-table.ts.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
public class MarkdownTable {
enum Align { NONE, LEFT, CENTER, RIGHT }
// splitLine: literal-delimiter split (',', '\t', ';'), each cell trimmed.
static List<String> splitLine(String line, char delim) {
List<String> cells = new ArrayList<>();
for (String c : line.split(String.valueOf(delim), -1)) cells.add(c.trim());
return cells;
}
// parseTable: non-empty lines, each split by the delimiter.
static List<List<String>> parseTable(String input, char delim) {
List<List<String>> rows = new ArrayList<>();
for (String l : input.split("\r?\n", -1)) {
String t = l.trim();
if (!t.isEmpty()) rows.add(splitLine(t, delim));
}
return rows;
}
// escapeCell: newlines collapse to spaces, a literal '|' renders as '\|'.
static String escapeCell(String cell) {
return cell.replaceAll("\r?\n", " ").replace("|", "\\|");
}
// pad: fill to width honoring right/center/left alignment.
static String pad(String cell, int width, Align align) {
int diff = width - cell.length();
if (diff <= 0) return cell;
return switch (align) {
case RIGHT -> " ".repeat(diff) + cell;
case CENTER -> " ".repeat(diff / 2) + cell + " ".repeat(diff - diff / 2);
default -> cell + " ".repeat(diff); // LEFT, NONE -> left-aligned
};
}
// sepCell: ---, :--, --:, :-: — the alignment separator, min width 3.
static String sepCell(Align align, int width) {
int w = Math.max(3, width);
return switch (align) {
case CENTER -> ":" + "-".repeat(w - 2) + ":";
case RIGHT -> "-".repeat(w - 1) + ":";
case LEFT -> ":" + "-".repeat(w - 1);
case NONE -> "-".repeat(w);
};
}
// toMarkdown: pad every column to its widest (escaped) cell and lay rows
// out as '| a | b |', with the separator row under the header row.
static String toMarkdown(List<List<String>> rows, boolean header, List<Align> aligns) {
if (rows.isEmpty()) return "";
int cols = rows.stream().mapToInt(List::size).max().orElse(0); // effectively final
List<List<String>> grid = new ArrayList<>();
for (List<String> r : rows) {
List<String> cells = new ArrayList<>(r.stream().map(MarkdownTable::escapeCell).toList());
while (cells.size() < cols) cells.add("");
grid.add(cells);
}
List<Align> align = new ArrayList<>(Collections.nCopies(cols, Align.NONE));
List<Integer> widths = new ArrayList<>(Collections.nCopies(cols, 3));
for (int c = 0; c < cols; c++) {
if (c < aligns.size()) align.set(c, aligns.get(c));
for (List<String> r : grid) widths.set(c, Math.max(widths.get(c), r.get(c).length()));
}
Function<List<String>, String> line = cells -> {
StringBuilder sb = new StringBuilder("| ");
for (int i = 0; i < cols; i++) {
if (i > 0) sb.append(" | ");
sb.append(pad(cells.get(i), widths.get(i), align.get(i)));
}
return sb.append(" |").toString();
};
StringBuilder separator = new StringBuilder("| ");
for (int c = 0; c < cols; c++) {
if (c > 0) separator.append(" | ");
separator.append(sepCell(align.get(c), widths.get(c)));
}
separator.append(" |");
List<String> out = new ArrayList<>();
out.add(line.apply(header ? grid.get(0) : Collections.nCopies(cols, "")));
out.add(separator.toString());
for (int i = header ? 1 : 0; i < grid.size(); i++) out.add(line.apply(grid.get(i)));
return String.join("\n", out);
}
public static void main(String[] args) {
// Demo: a CSV-ish grid with a literal pipe in one cell (escaped on output).
List<List<String>> rows = parseTable("Name,Price,Qty\nWire | cable,2 m,1\nLED,3 mm,25", ',');
System.out.println(toMarkdown(rows, true, List.of(Align.NONE, Align.RIGHT, Align.CENTER)));
}
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →