mdast-util-gfm-table

mdast extension to parse and serialize GFM tables

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
mdast-util-gfm-table
1102.0.010 months ago4 years agoMinified + gzip package size for mdast-util-gfm-table in KB

Readme

mdast-util-gfm-table
!Buildbuild-badgebuild !Coveragecoverage-badgecoverage !Downloadsdownloads-badgedownloads !Sizesize-badgesize !Sponsorssponsors-badgecollective !Backersbackers-badgecollective !Chatchat-badgechat
mdast extensions to parse and serialize GFM tables.

Contents

*   [`gfmTableFromMarkdown`](#gfmtablefrommarkdown)
*   [`gfmTableToMarkdown(options?)`](#gfmtabletomarkdownoptions)
*   [`Options`](#options)
*   [Example: `stringLength`](#example-stringlength)
*   [Nodes](#nodes)
*   [Enumeration](#enumeration)
*   [Content model](#content-model)

What is this?

This package contains two extensions that add support for GFM table syntax in markdown to mdast. These extensions plug into mdast-util-from-markdownmdast-util-from-markdown (to support parsing tables in markdown into a syntax tree) and mdast-util-to-markdownmdast-util-to-markdown (to support serializing tables in syntax trees to markdown).

When to use this

You can use these extensions when you are working with mdast-util-from-markdown and mdast-util-to-markdown already.
When working with mdast-util-from-markdown, you must combine this package with micromark-extension-gfm-tableextension.
When you don’t need a syntax tree, you can use micromarkmicromark directly with micromark-extension-gfm-table.
When you are working with syntax trees and want all of GFM, use mdast-util-gfmmdast-util-gfm instead.
All these packages are used remark-gfmremark-gfm, which focusses on making it easier to transform content by abstracting these internals away.
This utility does not handle how markdown is turned to HTML. That’s done by mdast-util-to-hastmdast-util-to-hast.

Install

This package is ESM onlyesm. In Node.js (version 16+), install with npm:
npm install mdast-util-gfm-table

In Deno with esm.shesmsh:
import {gfmTableFromMarkdown, gfmTableToMarkdown} from 'https://esm.sh/mdast-util-gfm-table@2'

In browsers with esm.shesmsh:
<script type="module">
  import {gfmTableFromMarkdown, gfmTableToMarkdown} from 'https://esm.sh/mdast-util-gfm-table@2?bundle'
</script>

Use

Say our document example.md contains:
| a | b | c | d |
| - | :- | -: | :-: |
| e | f |
| g | h | i | j | k |

…and our module example.js looks as follows:
import fs from 'node:fs/promises'
import {gfmTable} from 'micromark-extension-gfm-table'
import {fromMarkdown} from 'mdast-util-from-markdown'
import {gfmTableFromMarkdown, gfmTableToMarkdown} from 'mdast-util-gfm-table'
import {toMarkdown} from 'mdast-util-to-markdown'

const doc = await fs.readFile('example.md')

const tree = fromMarkdown(doc, {
  extensions: [gfmTable()],
  mdastExtensions: [gfmTableFromMarkdown()]
})

console.log(tree)

const out = toMarkdown(tree, {extensions: [gfmTableToMarkdown()]})

console.log(out)

…now running node example.js yields (positional info removed for brevity):
{
  type: 'root',
  children: [
    {
      type: 'table',
      align: [null, 'left', 'right', 'center'],
      children: [
        {
          type: 'tableRow',
          children: [
            {type: 'tableCell', children: [{type: 'text', value: 'a'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'b'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'c'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'd'}]}
          ]
        },
        {
          type: 'tableRow',
          children: [
            {type: 'tableCell', children: [{type: 'text', value: 'e'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'f'}]}
          ]
        },
        {
          type: 'tableRow',
          children: [
            {type: 'tableCell', children: [{type: 'text', value: 'g'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'h'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'i'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'j'}]},
            {type: 'tableCell', children: [{type: 'text', value: 'k'}]}
          ]
        }
      ]
    }
  ]
}

| a | b  |  c |  d  |   |
| - | :- | -: | :-: | - |
| e | f  |    |     |   |
| g | h  |  i |  j  | k |

API

This package exports the identifiers gfmTableFromMarkdownapi-gfm-table-from-markdown and gfmTableToMarkdownapi-gfm-table-to-markdown. There is no default export.

gfmTableFromMarkdown

Create an extension for mdast-util-from-markdownmdast-util-from-markdown to enable GFM tables in markdown.
Returns
Extension for mdast-util-from-markdown to enable GFM tables (FromMarkdownExtensionfrom-markdown-extension).

gfmTableToMarkdown(options?)

Create an extension for mdast-util-to-markdownmdast-util-to-markdown to enable GFM tables in markdown.
Parameters
— configuration
Returns
Extension for mdast-util-to-markdown to enable GFM tables (ToMarkdownExtensionto-markdown-extension).

Options

Configuration (TypeScript type).
Fields
  • tableCellPadding (boolean, default: true)
— whether to add a space of padding between delimiters and cells
  • tablePipeAlign (boolean, default: true)
— whether to align the delimiters
  • stringLength (((value: string) => number), default: s => s.length)
— function to detect the length of table cell content, used when aligning
the delimiters between cells

Examples

Example: stringLength

It’s possible to align tables based on the visual width of cells. First, let’s show the problem:
import {gfmTable} from 'micromark-extension-gfm-table'
import {fromMarkdown} from 'mdast-util-from-markdown'
import {gfmTableFromMarkdown, gfmTableToMarkdown} from 'mdast-util-gfm-table'
import {toMarkdown} from 'mdast-util-to-markdown'

const doc = `| Alpha | Bravo |
| - | - |
| 中文 | Charlie |
| 👩‍❤️‍👩 | Delta |`

const tree = fromMarkdown(doc, {
  extensions: [gfmTable],
  mdastExtensions: [gfmTableFromMarkdown]
})

console.log(toMarkdown(tree, {extensions: [gfmTableToMarkdown()]}))

The above code shows how these utilities can be used to format markdown. The output is as follows:
| Alpha    | Bravo   |
| -------- | ------- |
| 中文       | Charlie |
| 👩‍❤️‍👩 | Delta   |

To improve the alignment of these full-width characters and emoji, pass a stringLength function that calculates the visual width of cells. One such algorithm is string-widthstring-width. It can be used like so:
@@ -2,6 +2,7 @@ import {gfmTable} from 'micromark-extension-gfm-table'
 import {fromMarkdown} from 'mdast-util-from-markdown'
 import {gfmTableFromMarkdown, gfmTableToMarkdown} from 'mdast-util-gfm-table'
 import {toMarkdown} from 'mdast-util-to-markdown'
+import stringWidth from 'string-width'

 const doc = `| Alpha | Bravo |
 | - | - |
@@ -13,4 +14,8 @@ const tree = fromMarkdown(doc, {
   mdastExtensions: [gfmTableFromMarkdown()]
 })

-console.log(toMarkdown(tree, {extensions: [gfmTableToMarkdown()]}))
+console.log(
+  toMarkdown(tree, {
+    extensions: [gfmTableToMarkdown({stringLength: stringWidth})]
+  })
+)

The output of our code with these changes is as follows:
| Alpha | Bravo   |
| ----- | ------- |
| 中文  | Charlie |
| 👩‍❤️‍👩    | Delta   |

HTML

This utility does not handle how markdown is turned to HTML. That’s done by mdast-util-to-hastmdast-util-to-hast.

Syntax

See Syntax in micromark-extension-gfm-tablesyntax.

Syntax tree

The following interfaces are added to mdast by this utility.

Nodes

Table

interface Table <: Parent {
  type: 'table'
  align: [alignType]?
  children: [TableContent]
}

Table (Parentdfn-parent) represents two-dimensional data.
Table can be used where flowdfn-flow-content content is expected. Its content model is tabledfn-table-content content.
The head
term-head of the node represents the labels of the columns.
An align field can be present. If present, it must be a list of alignTypes
dfn-enum-align-type. It represents how cells in columns are aligned.
For example, the following markdown:
| foo | bar |
| :-- | :-: |
| baz | qux |

Yields:
{
  type: 'table',
  align: ['left', 'center'],
  children: [
    {
      type: 'tableRow',
      children: [
        {
          type: 'tableCell',
          children: [{type: 'text', value: 'foo'}]
        },
        {
          type: 'tableCell',
          children: [{type: 'text', value: 'bar'}]
        }
      ]
    },
    {
      type: 'tableRow',
      children: [
        {
          type: 'tableCell',
          children: [{type: 'text', value: 'baz'}]
        },
        {
          type: 'tableCell',
          children: [{type: 'text', value: 'qux'}]
        }
      ]
    }
  ]
}

TableRow

interface TableRow <: Parent {
  type: "tableRow"
  children: [RowContent]
}

TableRow (Parentdfn-parent) represents a row of cells in a table.
TableRow can be used where tabledfn-table-content content is expected. Its content model is rowdfn-row-content content.
If the node is a head
term-head, it represents the labels of the columns for its parent Tabledfn-table.
For an example, see
Tabledfn-table.

TableCell

interface TableCell <: Parent {
  type: "tableCell"
  children: [PhrasingContent]
}

TableCell (Parentdfn-parent) represents a header cell in a Tabledfn-table, if its parent is a headterm-head, or a data cell otherwise.
TableCell can be used where row
dfn-row-content content is expected. Its content model is phrasingdfn-phrasing-content content excluding Breakdfn-break nodes.
For an example, see
Tabledfn-table.

Enumeration

alignType

enum alignType {
  'center' | 'left' | 'right' | null
}

alignType represents how phrasing content is aligned (\CSSTEXT\]css-text).
property
CSS property
CSS property
  • null: phrasing content is aligned as defined by the host environment

Content model

FlowContent (GFM table)

type FlowContentGfm = Table | FlowContent

TableContent

type TableContent = TableRow

Table content represent the rows in a table.

RowContent

type RowContent = TableCell

Row content represent the cells in a row.

Types

This package is fully typed with TypeScript. It exports the additional type Optionsapi-options.
The Table, TableRow, and TableCell types of the mdast nodes are exposed from @types/mdast.

Compatibility

Projects maintained by the unified collective are compatible with maintained versions of Node.js.
When we cut a new major release, we drop support for unmaintained versions of Node. This means we try to keep the current release line, mdast-util-gfm-table@^2, compatible with Node.js 16.
This utility works with mdast-util-from-markdown version 2+ and mdast-util-to-markdown version 2+.

Related

— remark plugin to support GFM
— same but all of GFM (autolink literals, footnotes, strikethrough, tables,
tasklists)
— micromark extension to parse GFM tables

Contribute

See contributing.mdcontributing in syntax-tree/.githubhealth for ways to get started. See support.mdsupport for ways to get help.
This project has a code of conductcoc. By interacting with this repository, organization, or community you agree to abide by its terms.

License

MITlicense © Titus Wormerauthor