///|
fn markdown_escape_cell(text : String) -> String {
  let out = StringBuilder::StringBuilder()
  let mut i = 0
  while i < text.length() {
    match text.get_char(i) {
      Some('|') => out.write_string("\\|")
      Some('\n') => out.write_char(' ')
      Some('\r') => out.write_char(' ')
      Some(c) => out.write_char(c)
      None => ()
    }
    i = i + 1
  }
  out.to_string()
}

///|
fn markdown_write_row(
  out : StringBuilder,
  row : Array[String],
  width : Int,
) -> Unit {
  out.write_char('|')
  let mut c = 0
  while c < width {
    out.write_char(' ')
    let value = match row.get(c) {
      Some(v) => v
      None => ""
    }
    out.write_string(markdown_escape_cell(value))
    out.write_string(" |")
    c = c + 1
  }
  out.write_char('\n')
}

///|
fn markdown_header(table : Table, width : Int) -> Array[String] {
  let header : Array[String] = []
  let mut c = 0
  while c < width {
    header.push(table_column_name(table, c))
    c = c + 1
  }
  header
}

///|
/// Render a small Markdown preview. `max_rows` limits data rows only.
pub fn to_markdown(table : Table, max_rows : Int) -> String {
  let width = table.column_count()
  let out = StringBuilder::StringBuilder()
  if width == 0 {
    return ""
  }
  markdown_write_row(out, markdown_header(table, width), width)
  let separator : Array[String] = []
  let mut c = 0
  while c < width {
    separator.push("---")
    c = c + 1
  }
  markdown_write_row(out, separator, width)
  let rows_to_write = if max_rows < 0 {
    0
  } else {
    min_int(max_rows, table.rows.length())
  }
  let mut r = 0
  while r < rows_to_write {
    markdown_write_row(out, table.rows[r], width)
    r = r + 1
  }
  out.to_string()
}