diff --git a/llm.cpp b/llm.cpp index fd56deb..ea2e785 100644 --- a/llm.cpp +++ b/llm.cpp @@ -258,7 +258,10 @@ static void stream_handle_data(StreamCtx *sc, const std::string &data) { if (nl == std::string::npos) break; std::string cur = sc->line_buf.substr(0, nl); sc->line_buf.erase(0, nl + 1); - if (!sc->md.in_code && !is_table_line(cur)) { + /* Inside a code block every line is rendered verbatim as code; only + * outside a code block do table-shaped lines get accumulated for + * box-drawing table rendering. */ + if (sc->md.in_code || !is_table_line(cur)) { flush_tbl(sc); render_md_line_print(cur, sc->md); } else { diff --git a/render.cpp b/render.cpp index d8cab80..8e393dc 100644 --- a/render.cpp +++ b/render.cpp @@ -29,6 +29,22 @@ static bool is_table_sep(const std::vector &cells) { } return true; } +/* A run of lines only counts as a table when it contains a real delimiter + * row (a separator made of '-'/':' columns) and at least one data row. Without + * this, ordinary lists (or prose that merely contains '|') whose items happen + * to start or end with '|' would be mis-rendered as box-drawing tables. */ +static std::vector parse_table_cells(std::string_view line); +static bool looks_like_table(const std::vector &lines) { + if (lines.size() < 2) return false; + bool has_sep = false, has_row = false; + for (auto &line : lines) { + std::vector cells = parse_table_cells(line); + if (is_table_sep(cells)) has_sep = true; + else has_row = true; + } + return has_sep && has_row; +} + static std::vector parse_table_cells(std::string_view line) { std::string_view t = line; while (!t.empty() && (t.front() == ' ' || t.front() == '\t')) t.remove_prefix(1); @@ -350,6 +366,13 @@ static void print_row(int num_cols, const std::vector &col_widths, void render_table_print(const std::vector &lines) { if (lines.empty()) return; + /* Not an actual table (e.g. a list whose items merely contain '|'): render + * the lines as ordinary markdown instead of forcing a box-drawing table. */ + if (!looks_like_table(lines)) { + MdState st; + for (auto &ln : lines) render_md_line_print(ln, st); + return; + } std::vector> rows_cells; std::vector header_cells; bool has_header = false;