Skip to content

runeh/pote-parse

Repository files navigation

pote-parse

Parser and normalizer for Portable Text

The module can perform two tasks:

  1. Parse blocks of Portable Text into typed objects.
  2. Normalize Portable Text into a richer representation that can be useful for tools consuming or converting Portable Text.

The module is similar to block-content-tree. This module uses typescript, so it tries to provide type-safe versions of the parsed data. It also differs a bit in how lists are represented.

To install:

npm install pote-parse

# or

yarn add pote-parse

Parsing

See the type definitions for the output from parse at the top of the ./src/parser.ts file

Example

import { parse } from 'pote-parse';

const rawPortableText = [
  {
    _key: '07255f9a8e82',
    _type: 'block',
    children: [
      {
        _key: '432ab17c670d',
        _type: 'span',
        marks: [],
        text: 'Hello world!',
      },
      {
        _key: '2c01f20ff18d',
        _type: 'span',
        marks: ['c2586df86f96'],
        text: 'Link here!',
      },
    ],
    markDefs: [
      {
        _key: 'c2586df86f96',
        _type: 'link',
        href: 'http://example.org/',
      },
    ],
    style: 'h2',
  },
  {
    _key: '461abbd2c0fa',
    _type: 'block',
    children: [
      {
        _key: '061f2f58c404',
        _type: 'span',
        marks: [],
        text: 'First bullet point',
      },
    ],
    level: 1,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    _key: '46b3264f5aaa',
    _type: 'block',
    children: [
      {
        _key: '38376c2e9d32',
        _type: 'span',
        marks: [],
        text: 'Nested bullet point',
      },
    ],
    level: 2,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    _key: 'e64fe4340412',
    _type: 'image',
    asset: {
      _ref: 'my-image.jpg',
      _type: 'reference',
    },
  },
];

const parsed = parse(rawPortableText);

The value of parsed will be identical to the input, except that the blocks have a kind field:

[
  {
    kind: 'text',
    _key: '07255f9a8e82',
    _type: 'block',
    children: [
      {
        _key: '432ab17c670d',
        _type: 'span',
        marks: [],
        text: 'Hello world!',
      },
      {
        _key: '2c01f20ff18d',
        _type: 'span',
        marks: ['c2586df86f96'],
        text: 'Link here!',
      },
    ],
    markDefs: [
      {
        _key: 'c2586df86f96',
        _type: 'link',
        href: 'http://example.org/',
      },
    ],
    style: 'h2',
  },
  {
    kind: 'list',
    _key: '461abbd2c0fa',
    _type: 'block',
    children: [
      {
        _key: '061f2f58c404',
        _type: 'span',
        marks: [],
        text: 'First bullet point',
      },
    ],
    level: 1,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    kind: 'list',
    _key: '46b3264f5aaa',
    _type: 'block',
    children: [
      {
        _key: '38376c2e9d32',
        _type: 'span',
        marks: [],
        text: 'Nested bullet point',
      },
    ],
    level: 2,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    kind: 'custom',
    _key: 'e64fe4340412',
    _type: 'image',
    asset: {
      _ref: 'my-image.jpg',
      _type: 'reference',
    },
  },
];

Normalization

See the type definitions for the output from parse at the top of the ./src/normalizer.ts file

import { normalize, parse } from 'pote-parse';

const rawPortableText = [
  {
    _key: '07255f9a8e82',
    _type: 'block',
    children: [
      {
        _key: '432ab17c670d',
        _type: 'span',
        marks: [],
        text: 'Hello world!',
      },
      {
        _key: '2c01f20ff18d',
        _type: 'span',
        marks: ['c2586df86f96'],
        text: 'Link here!',
      },
    ],
    markDefs: [
      {
        _key: 'c2586df86f96',
        _type: 'link',
        href: 'http://example.org/',
      },
    ],
    style: 'h2',
  },
  {
    _key: '461abbd2c0fa',
    _type: 'block',
    children: [
      {
        _key: '061f2f58c404',
        _type: 'span',
        marks: [],
        text: 'First bullet point',
      },
    ],
    level: 1,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    _key: '46b3264f5aaa',
    _type: 'block',
    children: [
      {
        _key: '38376c2e9d32',
        _type: 'span',
        marks: [],
        text: 'Nested bullet point',
      },
    ],
    level: 2,
    listItem: 'bullet',
    markDefs: [],
    style: 'normal',
  },
  {
    _key: 'e64fe4340412',
    _type: 'image',
    asset: {
      _ref: 'my-image.jpg',
      _type: 'reference',
    },
  },
];

const parsed = parse(rawPortableText);
const normalized = normalize(parsed);

The normalized output is an array of blocks. Each block can be a text block, a custom block or a list block. List blocks can have children that are text blocks or list blocks, when there are nested lists.

In addition, all marks are represented as objects with a type field, and an optional options field that contains all metadata from a markDef.

The markDefs array is removed, and the markDef info moved into the marks objects.

Normalized Portable Text:

[
  {
    kind: 'text',
    key: '07255f9a8e82',
    style: 'h2',
    spans: [
      {
        key: '432ab17c670d',
        type: 'span',
        text: 'Hello world!',
        marks: [],
      },
      {
        key: '2c01f20ff18d',
        type: 'span',
        text: 'Link here!',
        marks: [
          {
            type: 'link',
            options: {
              href: 'http://example.org/',
            },
          },
        ],
      },
    ],
  },
  {
    kind: 'list',
    level: 1,
    type: 'bullet',
    children: [
      {
        kind: 'text',
        key: '461abbd2c0fa',
        style: 'normal',
        spans: [
          {
            key: '061f2f58c404',
            type: 'span',
            text: 'First bullet point',
            marks: [],
          },
        ],
      },
      {
        kind: 'list',
        level: 2,
        type: 'bullet',
        children: [
          {
            kind: 'text',
            key: '46b3264f5aaa',
            style: 'normal',
            spans: [
              {
                key: '38376c2e9d32',
                type: 'span',
                text: 'Nested bullet point',
                marks: [],
              },
            ],
          },
        ],
      },
    ],
  },
  {
    kind: 'custom',
    type: 'image',
    key: 'e64fe4340412',
    fields: {
      asset: {
        _ref: 'my-image.jpg',
        _type: 'reference',
      },
    },
  },
];

About

Parser for Portable Text

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published