Search in sources :

Example 1 with Ref

use of com.vladsch.flexmark.util.Ref in project flexmark-java by vsch.

the class Table method appendTable.

public void appendTable(final FormattingAppendable out) {
    // we will prepare the separator based on max columns
    int formatterOptions = out.getOptions();
    out.setOptions(formatterOptions & ~FormattingAppendable.COLLAPSE_WHITESPACE);
    Ref<Integer> delta = new Ref<Integer>(0);
    if (heading.rows.size() > 0) {
        for (TableRow row : heading.rows) {
            int j = 0;
            int jSpan = 0;
            delta.value = 0;
            for (TableCell cell : row.cells) {
                if (j == 0) {
                    if (options.leadTrailPipes) {
                        out.append('|');
                        if (options.spaceAroundPipes)
                            out.append(' ');
                    }
                } else {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                }
                CellAlignment cellAlignment = cell.alignment != CellAlignment.NONE ? cell.alignment : alignments[jSpan];
                out.append(cellText(cell.text, true, spanWidth(jSpan, cell.columnSpan) - options.spacePad - options.pipeWidth * cell.columnSpan, cellAlignment, delta));
                j++;
                jSpan += cell.columnSpan;
                if (j < alignments.length) {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan);
                } else if (options.leadTrailPipes) {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan);
                } else {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan - 1);
                }
            }
            if (j > 0)
                out.line();
        }
    }
    {
        int j = 0;
        delta.value = 0;
        for (CellAlignment alignment : alignments) {
            CellAlignment alignment1 = adjustCellAlignment(alignment);
            int colonCount = alignment1 == CellAlignment.LEFT || alignment1 == CellAlignment.RIGHT ? 1 : alignment1 == CellAlignment.CENTER ? 2 : 0;
            int dashCount = (columnWidths[j] - colonCount * options.colonWidth - options.pipeWidth) / options.dashWidth;
            int dashesOnly = Utils.minLimit(dashCount, options.minSeparatorColumnWidth - colonCount, options.minSeparatorDashes);
            if (dashCount < dashesOnly)
                dashCount = dashesOnly;
            if (delta.value * 2 >= options.dashWidth) {
                dashCount++;
                delta.value -= options.dashWidth;
            }
            if (options.leadTrailPipes && j == 0)
                out.append('|');
            if (alignment1 == CellAlignment.LEFT || alignment1 == CellAlignment.CENTER)
                out.append(':');
            out.repeat('-', dashCount);
            if (alignment1 == CellAlignment.RIGHT || alignment1 == CellAlignment.CENTER)
                out.append(':');
            j++;
            if (options.leadTrailPipes || j < alignments.length)
                out.append('|');
        }
        out.line();
    }
    if (body.rows.size() > 0) {
        for (TableRow row : body.rows) {
            int j = 0;
            int jSpan = 0;
            delta.value = 0;
            for (TableCell cell : row.cells) {
                if (j == 0) {
                    if (options.leadTrailPipes) {
                        out.append('|');
                        if (options.spaceAroundPipes)
                            out.append(' ');
                    }
                } else {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                }
                out.append(cellText(cell.text, false, spanWidth(jSpan, cell.columnSpan) - options.spacePad - options.pipeWidth * cell.columnSpan, alignments[jSpan], delta));
                j++;
                jSpan += cell.columnSpan;
                if (j < alignments.length) {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan);
                } else if (options.leadTrailPipes) {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan);
                } else {
                    if (options.spaceAroundPipes)
                        out.append(' ');
                    out.repeat('|', cell.columnSpan - 1);
                }
            }
            if (j > 0)
                out.line();
        }
    }
    out.setOptions(formatterOptions);
    if (caption != null && !options.removeCaption) {
        out.line().append('[').append(caption).append(']').line();
    }
}
Also used : Ref(com.vladsch.flexmark.util.Ref) CellAlignment(com.vladsch.flexmark.util.html.CellAlignment)

Example 2 with Ref

use of com.vladsch.flexmark.util.Ref in project flexmark-java by vsch.

the class Table method finalizeTable.

public void finalizeTable() {
    // remove null cells
    heading.cleanup();
    body.cleanup();
    if (options.fillMissingColumns) {
        int minColumns = getMinColumns();
        int maxColumns = getMaxColumns();
        if (minColumns < maxColumns) {
            // add empty cells to rows that have less
            TableCell empty = new TableCell("", 1, 1);
            for (TableRow row : heading.rows) {
                row.expandTo(maxColumns - 1, empty);
            }
            for (TableRow row : body.rows) {
                row.expandTo(maxColumns - 1, empty);
            }
        }
    }
    int sepColumns = getMaxColumns();
    alignments = new CellAlignment[sepColumns];
    columnWidths = new int[sepColumns];
    BitSet spanAlignment = new BitSet(sepColumns);
    List<ColumnSpan> columnSpans = new ArrayList<ColumnSpan>();
    Ref<Integer> delta = new Ref<Integer>(0);
    if (separator.rows.size() > 0) {
        TableRow row = separator.rows.get(0);
        int j = 0;
        int jSpan = 0;
        delta.value = 0;
        for (TableCell cell : row.cells) {
            // set alignment if not already set or was set by a span and this column is not a span
            if ((alignments[jSpan] == null || cell.columnSpan == 1 && spanAlignment.get(jSpan)) && cell.alignment != CellAlignment.NONE) {
                alignments[jSpan] = cell.alignment;
                if (cell.columnSpan > 1)
                    spanAlignment.set(jSpan);
            }
            j++;
            jSpan += cell.columnSpan;
        }
    }
    if (heading.rows.size() > 0) {
        int i = 0;
        for (TableRow row : heading.rows) {
            int j = 0;
            int jSpan = 0;
            delta.value = 0;
            for (TableCell cell : row.cells) {
                // set alignment if not already set or was set by a span and this column is not a span
                if ((alignments[jSpan] == null || cell.columnSpan == 1 && spanAlignment.get(jSpan)) && cell.alignment != CellAlignment.NONE) {
                    alignments[jSpan] = cell.alignment;
                    if (cell.columnSpan > 1)
                        spanAlignment.set(jSpan);
                }
                BasedSequence cellText = cellText(cell.text, true, 0, null, delta);
                int width = options.charWidthProvider.charWidth(cellText) + options.spacePad + options.pipeWidth * cell.columnSpan;
                if (cell.columnSpan > 1) {
                    columnSpans.add(new ColumnSpan(j, cell.columnSpan, width));
                } else {
                    if (columnWidths[jSpan] < width)
                        columnWidths[jSpan] = width;
                }
                j++;
                jSpan += cell.columnSpan;
            }
            i++;
        }
    }
    if (body.rows.size() > 0) {
        int i = 0;
        delta.value = 0;
        for (TableRow row : body.rows) {
            int j = 0;
            int jSpan = 0;
            for (TableCell cell : row.cells) {
                BasedSequence cellText = cellText(cell.text, false, 0, null, delta);
                int width = options.charWidthProvider.charWidth(cellText) + options.spacePad + options.pipeWidth * cell.columnSpan;
                if (cell.columnSpan > 1) {
                    columnSpans.add(new ColumnSpan(jSpan, cell.columnSpan, width));
                } else {
                    if (columnWidths[jSpan] < width)
                        columnWidths[jSpan] = width;
                }
                j++;
                jSpan += cell.columnSpan;
            }
            i++;
        }
    }
    // add separator column widths to the calculation
    if (separator.rows.size() == 0 || body.rows.size() > 0 || heading.rows.size() > 0) {
        int j = 0;
        delta.value = 0;
        for (CellAlignment alignment : alignments) {
            CellAlignment alignment1 = adjustCellAlignment(alignment);
            int colonCount = alignment1 == CellAlignment.LEFT || alignment1 == CellAlignment.RIGHT ? 1 : alignment1 == CellAlignment.CENTER ? 2 : 0;
            int dashCount = 0;
            int dashesOnly = Utils.minLimit(dashCount, options.minSeparatorColumnWidth - colonCount, options.minSeparatorDashes);
            if (dashCount < dashesOnly)
                dashCount = dashesOnly;
            int width = dashCount * options.dashWidth + colonCount * options.colonWidth + options.pipeWidth;
            if (columnWidths[j] < width)
                columnWidths[j] = width;
            j++;
        }
    } else {
        // keep as is
        int j = 0;
        delta.value = 0;
        for (TableCell cell : separator.rows.get(0).cells) {
            CellAlignment alignment = adjustCellAlignment(cell.alignment);
            int colonCount = alignment == CellAlignment.LEFT || alignment == CellAlignment.RIGHT ? 1 : alignment == CellAlignment.CENTER ? 2 : 0;
            int dashCount = cell.text.trim(":").length();
            int dashesOnly = Utils.minLimit(dashCount, options.minSeparatorColumnWidth - colonCount, options.minSeparatorDashes);
            if (dashCount < dashesOnly)
                dashCount = dashesOnly;
            int width = dashCount * options.dashWidth + colonCount * options.colonWidth + options.pipeWidth;
            if (columnWidths[j] < width)
                columnWidths[j] = width;
            j++;
        }
    }
    if (!columnSpans.isEmpty()) {
        // now need to distribute extra width from spans to contained columns
        int[] additionalWidths = new int[sepColumns];
        BitSet unfixedColumns = new BitSet(sepColumns);
        List<ColumnSpan> newColumnSpans = new ArrayList<ColumnSpan>(columnSpans.size());
        for (ColumnSpan columnSpan : columnSpans) {
            int spanWidth = spanWidth(columnSpan.startColumn, columnSpan.columnSpan);
            if (spanWidth < columnSpan.width) {
                // not all fits, need to distribute the remainder
                unfixedColumns.set(columnSpan.startColumn, columnSpan.startColumn + columnSpan.columnSpan);
                newColumnSpans.add(columnSpan);
            }
        }
        // we now distribute additional width equally between columns that are spanned to unfixed columns
        while (!newColumnSpans.isEmpty()) {
            columnSpans = newColumnSpans;
            BitSet fixedColumns = new BitSet(sepColumns);
            newColumnSpans.clear();
            // remove spans that already fit into fixed columns
            for (ColumnSpan columnSpan : columnSpans) {
                int spanWidth = spanWidth(columnSpan.startColumn, columnSpan.columnSpan);
                int fixedWidth = spanFixedWidth(unfixedColumns, columnSpan.startColumn, columnSpan.columnSpan);
                if (spanWidth <= fixedWidth) {
                    fixedColumns.set(columnSpan.startColumn, columnSpan.startColumn + columnSpan.columnSpan);
                } else {
                    newColumnSpans.add(columnSpan);
                }
            }
            // reset fixed columns
            unfixedColumns.andNot(fixedColumns);
            columnSpans = newColumnSpans;
            newColumnSpans.clear();
            for (ColumnSpan columnSpan : columnSpans) {
                int spanWidth = spanWidth(columnSpan.startColumn, columnSpan.columnSpan);
                int fixedWidth = spanFixedWidth(unfixedColumns, columnSpan.startColumn, columnSpan.columnSpan);
                if (spanWidth > fixedWidth) {
                    // not all fits, need to distribute the remainder to unfixed columns
                    int distributeWidth = spanWidth - fixedWidth;
                    int unfixedColumnCount = unfixedColumns.get(columnSpan.startColumn, columnSpan.startColumn + columnSpan.columnSpan).cardinality();
                    int perSpanWidth = distributeWidth / unfixedColumnCount;
                    int extraWidth = distributeWidth - perSpanWidth * unfixedColumnCount;
                    for (int i = 0; i < columnSpan.columnSpan; i++) {
                        if (unfixedColumns.get(columnSpan.startColumn + i)) {
                            columnWidths[columnSpan.startColumn + i] += perSpanWidth;
                            if (extraWidth > 0) {
                                columnWidths[columnSpan.startColumn + i]++;
                                extraWidth--;
                            }
                        }
                    }
                    newColumnSpans.add(columnSpan);
                }
            }
        }
    }
}
Also used : BasedSequence(com.vladsch.flexmark.util.sequence.BasedSequence) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) CellAlignment(com.vladsch.flexmark.util.html.CellAlignment) Ref(com.vladsch.flexmark.util.Ref)

Aggregations

Ref (com.vladsch.flexmark.util.Ref)2 CellAlignment (com.vladsch.flexmark.util.html.CellAlignment)2 BasedSequence (com.vladsch.flexmark.util.sequence.BasedSequence)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1