All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.logchange.md.table.MarkdownTable Maven / Gradle / Ivy

There is a newer version: 1.12.0
Show newest version
package dev.logchange.md.table;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


class MarkdownTable {

    private static final String SEPARATOR = "|";
    private static final char WHITESPACE = ' ';
    private static final int DEFAULT_MINIMUM_COLUMN_WIDTH = 3;

    private final MarkdownTableRow header;
    private final List rows;
    private final Map tableColumnWidths;

    public static MarkdownTable of(MarkdownTableRow header) {
        checkHeader(header);
        return new MarkdownTable(header);
    }

    private MarkdownTable(MarkdownTableRow header) {
        this.header = header;
        this.tableColumnWidths = new HashMap<>();
        this.rows = new ArrayList<>();
        calculateTableColumnWidths(header);
    }

    private static void checkHeader(MarkdownTableRow header) {
        if (header == null) {
            throw new MarkdownTableValidationException("Table header cannot be null!");
        }
        if (header.getNumberOfCells() == 0) {
            throw new MarkdownTableValidationException("Table header cannot be empty!");
        }
    }

    boolean addRow(MarkdownTableRow tableRow) {
        if (tableRow != null && getNumberOfColumns() == tableRow.getNumberOfCells()) {
            calculateTableColumnWidths(tableRow);
            return this.rows.add(tableRow);
        }
        return false;
    }

    int getNumberOfColumns() {
        return this.header.getNumberOfCells();
    }

    private void calculateTableColumnWidths(MarkdownTableRow row) {
        Map rowCellWidths = row.getCellWidths();
        for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) {
            this.tableColumnWidths.compute(columnIndex, (key, value) ->
                    Math.max((value != null ? value : DEFAULT_MINIMUM_COLUMN_WIDTH),
                            rowCellWidths.getOrDefault(key, DEFAULT_MINIMUM_COLUMN_WIDTH)));
        }
    }

    @Override
    public String toString() {
        return serialize();
    }

    private String serialize() {
        StringBuilder sb = new StringBuilder();
        sb.append(generateCells(this.header));
        sb.append(generateHeaderSeparator());
        for (MarkdownTableRow row : rows) {
            sb.append(System.lineSeparator());
            sb.append(generateCells(row));
        }
        return sb.toString();
    }

    private String generateCells(MarkdownTableRow row) {
        StringBuilder sb = new StringBuilder();

        for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) {
            sb.append(SEPARATOR);
            sb.append(fillUpLeftAligned(
                    surroundWithWhitespace(escapeSeparatorSign(row.getCell(columnIndex))),
                    WHITESPACE,
                    tableColumnWidths.get(columnIndex) + 2));
        }
        return sb.append(SEPARATOR).toString();
    }

    private String fillUpLeftAligned(String value, char fill, int length) {
        return value.length() >= length ? value : String.format("%-" + length + "s", value).replace(' ', fill);
    }

    private String escapeSeparatorSign(Object cell) {
        return String.valueOf(cell).replace(SEPARATOR, "\\" + SEPARATOR);
    }

    private String surroundWithWhitespace(String value) {
        return WHITESPACE + value + WHITESPACE;
    }

    private String generateHeaderSeparator() {
        StringBuilder sb = new StringBuilder();
        sb.append(System.lineSeparator());
        for (int columnIndex = 0; columnIndex < getNumberOfColumns(); columnIndex++) {
            sb.append(SEPARATOR);
            sb.append(surroundWithWhitespace(fillUpLeftAligned("", '-', tableColumnWidths.get(columnIndex))));
        }
        return sb.append(SEPARATOR).toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy