c4spar / deno-cliffy

Command line framework for deno 🦕 Including Commandline-Interfaces, Prompts, CLI-Table, Arguments Parser and more...
https://cliffy.io
MIT License
968 stars 66 forks source link

Table: Possible to enable all borders around headings but only vertical borders around body? #765

Open lionel-rowe opened 3 weeks ago

lionel-rowe commented 3 weeks ago

The effect I want is this:

┌─────────────────────────┬───────────────┬─────────────────────────────┐
│ Browser                 │ Version Added │ Bug Tracker                 │
├─────────────────────────┼───────────────┼─────────────────────────────┤
│ chrome                  │ 122           │                             │
│ chrome_android          │ 122           │                             │
│ deno                    │ 1.42          │                             │
│ edge                    │ 122           │                             │
│ firefox                 │ 131           │                             │
│ firefox_android         │ 131           │                             │
│ nodejs                  │ 22.0.0        │                             │
│ opera                   │ 108           │                             │
│ opera_android           │ 81            │                             │
│ safari                  │ [none]        │ https://webkit.org/b/248650 │
│ safari_ios              │ [none]        │ https://webkit.org/b/248650 │
│ samsunginternet_android │ 26.0          │                             │
│ webview_android         │ 122           │                             │
│ webview_ios             │ [none]        │ https://webkit.org/b/248650 │
└─────────────────────────┴───────────────┴─────────────────────────────┘

I can't see a way of changing the border chars for individual Rows/Cells (only enabling/disabling the border entirely), and in any case that still wouldn't have the desired effect, as I want the body rows to be compact, i.e. no additional newline is inserted between each row.

I'm currently using this hack:

import { Table, border as defaultBorder, type Border } from 'jsr:@cliffy/table@1.0.0-rc.7'
import { regExpEscape } from 'jsr:@li/regexp-escape-polyfill@0.3.4'

const r: typeof String.raw = (s, ...vals) => String.raw(s, ...vals.map(regExpEscape))

function table(header: string[], body: string[][], border: Border = defaultBorder) {
    const { leftMid, mid, midMid, rightMid } = border
    const replacer = new RegExp(r`\n${leftMid}(?:${mid}|${midMid})+${rightMid}`, 'g')
    let rowIdx = 0

    return new Table()
        .chars(border)
        .border()
        .header(header)
        .body(body)
        .toString()
        .replace(replacer, (m) => rowIdx++ ? '' : m)
}

Is there a way of doing this that doesn't involve constructing a custom regex like this though?

c4spar commented 4 days ago

Not yet, but I have a local wip branch where I have started to add some more helper functions, such as: