in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/ascii/NCAsciiTable.scala [312:478]
private def mkStyledCell(style: String, lines: Any*): Cell =
val st = Style(style)
val strLines = lines.map(x)
Cell(
st,
if breakUpByWords then
breakUpByNearestSpace(st.maxWidth, strLines)
else
(for (str <- strLines) yield str.grouped(st.maxWidth)).flatten
)
/**
* Adds single header cell with the default style..
*
* @param lines One or more cell lines.
*/
def addHeaderCell(lines: Any*): NCAsciiTable =
hdr :+= mkStyledCell(
defaultHeaderStyle,
lines: _*
)
this
/**
* Adds single row cell with the default style.
*
* @param lines One or more row cells. Multiple lines will be printed on separate lines.
*/
def addRowCell(lines: Any*): NCAsciiTable =
curRow :+= mkStyledCell(
defaultRowStyle,
lines: _*
)
this
/**
* Adds single header cell with the default style..
*
* @param style Style to use.
* @param lines One or more cell lines.
*/
def addStyledHeaderCell(style: String, lines: Any*): NCAsciiTable =
hdr :+= mkStyledCell(
if style.trim.isEmpty then defaultHeaderStyle else style,
lines: _*
)
this
/**
* Adds single row cell with the default style.
*
* @param style Style to use.
* @param lines One or more row cells. Multiple lines will be printed on separate lines.
*/
def addStyledRowCell(style: String, lines: Any*): NCAsciiTable =
curRow :+= mkStyledCell(
if style.trim.isEmpty then defaultRowStyle else style,
lines: _*
)
this
/**
*
* @param txt Text to align.
* @param width Width already accounts for padding.
* @param sty Style.
*/
private def aligned(txt: String, width: Int, sty: Style): String =
val d = width - txt.length
sty.align match
case "center" => s"${space(d / 2)}$txt${space(d / 2 + d % 2)}"
case "left" => s"${space(sty.leftPad)}$txt${space(d - sty.leftPad)}"
case "right" => s"${space(d - sty.rightPad)}$txt${space(sty.rightPad)}"
case _ => throw new AssertionError(s"Invalid align option: $sty")
override def toString: String = mkString()
/**
* Prepares output string.
*/
private def mkString(): String =
// Make sure table is not empty.
if hdr.isEmpty && rows.isEmpty then return ""
var colsNum = -1
val isHdr = hdr.nonEmpty
if isHdr then colsNum = hdr.size
// Calc number of columns and make sure all rows are even.
for (r <- rows)
if colsNum == -1 then colsNum = r.size
else if colsNum != r.size then assert(assertion = false, "Table with uneven rows.")
assert(colsNum > 0, "No columns found.")
// At this point all rows in the table have the
// the same number of columns.
val colWidths = new Array[Int](colsNum) // Column widths.
val rowHeights = new Array[Int](rows.length) // Row heights.
// Header height.
var hdrH = 0
// Initialize column widths with header row (if any).
for (i <- hdr.indices)
val c = hdr(i)
colWidths(i) = c.width
hdrH = math.max(hdrH, c.height)
// Calculate row heights and column widths.
for (i <- rows.indices; j <- 0 until colsNum)
val c = rows(i)(j)
rowHeights(i) = math.max(rowHeights(i), c.height)
colWidths(j) = math.max(colWidths(j), c.width)
// Table width without the border.
val tableW = colWidths.sum + colsNum - 1
val tbl = new StringBuilder
// Top margin.
for (_ <- 0 until margin.top)
tbl ++= " \n"
/**
*
* @param crs
* @param cor
*/
def mkAsciiLine(crs: String, cor: String): String =
s"${space(margin.left)}$crs${dash(cor, tableW)}$crs${space(margin.right)}\n"
// Print header, if any.
if isHdr then
tbl ++= mkAsciiLine(HDR_CRS, HDR_HOR)
for (i <- 0 until hdrH)
// Left margin and '|'.
tbl ++= s"${space(margin.left)}$HDR_VER"
for (j <- hdr.indices)
val c = hdr(j)
if i >= 0 && i < c.height then
tbl ++= aligned(c.lines(i), colWidths(j), c.style)
else
tbl ++= space(colWidths(j))
tbl ++= s"$HDR_VER" // '|'
// Right margin.
tbl ++= s"${space(margin.right)}\n"
tbl ++= mkAsciiLine(HDR_CRS, HDR_HOR)
else
tbl ++= mkAsciiLine(ROW_CRS, ROW_HOR)
val tblWidthLine = s"${space(margin.left)}$ROW_CRS${dash(ROW_HOR, tableW)}$ROW_CRS${space(margin.right)}\n"
// Print rows, if any.
if rows.nonEmpty then
val addHorLine = (i: Int) => {
// Left margin and '+'
tbl ++= s"${space(margin.left)}$ROW_CRS"
for (k <- rows(i).indices)
tbl ++= s"${dash(ROW_HOR, colWidths(k))}$ROW_CRS"
// Right margin.
tbl ++= s"${space(margin.right)}\n"
}