Giter Site home page Giter Site logo

tablemark's Introduction

tablemark · Version License TypeScript GitHub Actions

Generate markdown tables from JSON data.

Renders arrays of objects as markdown tables, complete with configuration for renaming columns and left, center, or right-aligning them.

installation

yarn add tablemark

# or

npm install tablemark

usage

import tablemark from "tablemark"
tablemark([
  { name: "Bob", age: 21, isCool: false },
  { name: "Sarah", age: 22, isCool: true },
  { name: "Lee", age: 23, isCool: true }
])

// | Name  | Age   | Is cool |
// | :---- | :---- | :------ |
// | Bob   | 21    | false   |
// | Sarah | 22    | true    |
// | Lee   | 23    | true    |

... displays as:

Name Age Is cool
Bob 21 false
Sarah 22 true
Lee 23 true

api

tablemark (input: InputData, options?: TablemarkOptions): string

Arguments

  • InputData input: the data to table-ify

    • an array of objects or iterables
  • TablemarkOptions options:

    key type default description
    columns Array<string | ColumnDescriptor> - Array of column descriptors.
    caseHeaders boolean true Sentence case headers derived from keys.
    toCellText (input: unknown) => string - Provide a custom "toString" function.
    padHeaderSeparator boolean true Whether to pad gutters of the header separator (alignment) row.
    wrapWidth number Infinity Wrap cell text at this length.
    wrapWithGutters boolean false Add sides (| <content> |) to wrapped rows.
    lineEnding string "\n" String used at end-of-line.

The columns array can either contain objects, in which case their name and align properties will be used to alter the display of the column in the table, or any other type which will be coerced to a string if necessary and used as a replacement for the column name.

Returns

string: the resulting markdown formatted table

Throws

TypeError: when input is not iterable (e.g., an array)
TypeError: when an unknown column alignment option is provided

options.columns

tablemark(
  [
    { name: "Bob", age: 21, isCool: false },
    { name: "Sarah", age: 22, isCool: true },
    { name: "Lee", age: 23, isCool: true }
  ],
  {
    columns: [
      "first name",
      { name: "how old", align: "center" },
      "are they cool"
    ]
  }
)

// | first name | how old | are they cool |
// | :--------- | :-----: | :------------ |
// | Bob        |   21    | false         |
// | Sarah      |   22    | true          |
// | Lee        |   23    | true          |

... displays as:

first name how old are they cool
Bob 21 false
Sarah 22 true
Lee 23 true

options.padHeaderSeparator

tablemark(
  [
    { name: "Bob", age: 21, isCool: false },
    { name: "Sarah", age: 22, isCool: true },
    { name: "Lee", age: 23, isCool: true }
  ],
  {
    columns: [{ align: "left" }, { align: "center" }, { align: "right" }]
  }
)

// | first name | how old | are they cool |
// |:-----------|:-------:|--------------:|
// | Bob        |   21    | false         |
// | Sarah      |   22    | true          |
// | Lee        |   23    | true          |

... displays as:

first name how old are they cool
Bob 21 false
Sarah 22 true
Lee 23 true

options.toCellText

tablemark(
  [
    { name: "Bob", pet_owner: true, studying: false },
    { name: "Sarah", pet_owner: false, studying: true },
    { name: "Sarah", pet_owner: true, studying: true }
  ],
  {
    toCellText,
    columns: [{ align: "left" }, { align: "center" }, { align: "center" }]
  }
)

function toCellText(v) {
  if (v === true) return "✔"
  if (!v) return ""
  return v
}

// | Name  | Pet owner | Studying |
// | :---- | :-------: | :------: |
// | Bob   |     ✔︎     |          |
// | Sarah |           |    ✔     |
// | Lee   |     ✔     |    ✔     |

options.wrapWidth

Set options.wrapWidth to wrap any content at that length onto a new adjacent line:

tablemark(
  [
    { star: false, name: "Benjamin" },
    { star: true, name: "Jet Li" }
  ],
  { wrapWidth: 5 }
)

// | Star  | Name  |
// | :---- | :---- |
// | false | Benja |
//           min
// | true  | Jet   |
//           Li

To output valid GitHub Flavored Markdown a cell must not contain newlines. Consider replacing those with <br /> (e.g., using options.toCellText).

options.wrapWithGutters

Enable wrapWithGutters to add pipes on all lines:

tablemark(
  [
    { star: false, name: "Benjamin" },
    { star: true, name: "Jet Li" }
  ],
  { wrapWidth: 5, wrapWithGutters: true }
)

// | Star  | Name  |
// | :---- | :---- |
// | false | Benja |
// |       | min   |
// | true  | Jet   |
// |       | Li    |

see also

contributing

Search the issues if you come across any trouble, open a new one if it hasn't been posted, or, if you're able, open a pull request. Contributions of any kind are welcome in this project.

The following people have already contributed their time and effort:

Thank you!

license

MIT © Bo Lingen / haltcase

tablemark's People

Contributors

haltcase avatar tjconcept avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

tablemark's Issues

Better newlines and long texts

The current method of converting to strings does not take newlines into consideration, which are probably not that uncommon. The current state of "newlines in markdown tables" seems pretty bad from a quick search on the internet.

Current:

echo '{"message":"Wr\nong"}' | tablemark
| Message |
| ------- |
| Wr
ong  |

Some options:

Replacing \n with <br />:

| Message     | Code  |
| ----------- | ----- |
| Wr<br />ong | 2     |
Message Code
Wr
ong
2

Extending the table downwards

Keeping gutters/separators

| Message | Code  |
| ------- | ----- |
| Wr      | 2     |
| ong     |       |
| Good    | 0     |
Message Code
Wr 2
ong
Good 0

Without gutters/separators

| Message | Code  |
| ------- | ----- |
| Wr      | 2     |
  ong
| Good    | 0     |
Message Code
Wr 2
ong
Good 0

Since only the first produces valid markdown (GitHub-usable), I think that should definitely be an option. Apart from that consideration, I'm mostly into the last one (wrapping and aligning but without gutters/separators).

My rough proposal is:
Wrap at newlines and after any 80 characters run. Do not add gutters and separators, but align content. Provide an option to tweak characters per line or disable automatic line wrapping. Provide an option to replace newlines with <br /> and disable any wrapping.

Passing an empty array throws error

Hi,

tablemark([]) will throw:

TypeError: Cannot convert undefined or null to object

Maybe there's a reason for it but IMO it would be more convenient to return an empty string.

Soften or remove `os` module dependency

The os module is only used to retrieve the system EOL, requiring a patch such as the one I commented on here to work in other environments:

plesk@3dbca4b#commitcomment-52865560

I'm thinking maybe make EOL configurable, then either wrap require('os') in a try/catch (would that prevent this error?) to get a default or get rid of it entirely and just default to \n.

vscode extension

Nice tool! Any thoughts how this might be used in VS Code / MD-based note taking environment?

The use case I have in mind is referring to a local JSON file with some kind of tag, and import the the markdown output from tablemark within a markdown file.

Option for compact headers

Hello!

Nice little lib.

Unfortunately, WebStorm complains about the formatting of the headers:

| first name | how old | are they cool |
| :--------- | :-----: | :------------ |

It seems it would prefer:

| first name | how old | are they cool |
|:-----------|:-------:|:--------------|

Could we add an option for that?

Looking at the code, a post-generation regex around line 49 would probably be simplest option:

separator.replace(/ (:?\-+:?) /g, (all, inner) => inner.replace('-', '---'))

I'm happy to PR this.

Params does not affect output

Trying to apply some prams as per example below, but seems does not work

import * as table from "tablemark";

const items = [
  { name: “a”, id: “1” },
  { name: “b”, id: “2” }
]
table(items, { caseHeaders: false, wrap: {width: 1, gutters: false}});

Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.