use of com.vladsch.flexmark.util.html.CellAlignment 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();
}
}
use of com.vladsch.flexmark.util.html.CellAlignment 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);
}
}
}
}
}
Aggregations