@portabletext/block-tools 5.0.5 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,22 @@
1
1
  # `@portabletext/block-tools`
2
2
 
3
- > Convert HTML to Portable Text with built-in support for Google Docs, Word, and Notion.
3
+ > Sanity-flavored HTML to Portable Text conversion
4
4
 
5
- **NOTE:** To use `@portabletext/block-tools` in a Node.js script, you will need to provide a `parseHtml` method - generally using `JSDOM`. [Read more](#jsdom-example).
5
+ This package wraps [`@portabletext/html`](../html) for use with Sanity schemas. If you're not using Sanity's schema system, use `@portabletext/html` directly - it has the same features with a simpler API.
6
6
 
7
- ## Example
7
+ ## When to use which
8
8
 
9
- Let's start with a complete example:
9
+ | Package | Use when |
10
+ | --------------------------- | --------------------------------------------------------------- |
11
+ | `@portabletext/html` | Standalone projects, custom schemas, or any non-Sanity context |
12
+ | `@portabletext/block-tools` | Sanity projects where you already have a compiled Sanity schema |
10
13
 
11
- ```js
14
+ ## Usage
15
+
16
+ ```ts
12
17
  import {htmlToBlocks} from '@portabletext/block-tools'
13
18
  import {Schema} from '@sanity/schema'
14
19
 
15
- // Start with compiling a schema we can work against
16
20
  const defaultSchema = Schema.compile({
17
21
  name: 'myBlog',
18
22
  types: [
@@ -36,161 +40,46 @@ const defaultSchema = Schema.compile({
36
40
  ],
37
41
  })
38
42
 
39
- // The compiled schema type for the content type that holds the block array
40
43
  const blockContentType = defaultSchema
41
44
  .get('blogPost')
42
45
  .fields.find((field) => field.name === 'body').type
43
46
 
44
- // Convert HTML to block array
45
47
  const blocks = htmlToBlocks(
46
- '<html><body><h1>Hello world!</h1><body></html>',
48
+ '<html><body><h1>Hello world!</h1></body></html>',
47
49
  blockContentType,
48
50
  )
49
- // Outputs
50
- //
51
- // {
52
- // _type: 'block',
53
- // style: 'h1'
54
- // children: [
55
- // {
56
- // _type: 'span'
57
- // text: 'Hello world!'
58
- // }
59
- // ]
60
- // }
61
- ```
62
-
63
- ## Methods
64
-
65
- ### `htmlToBlocks(html, blockContentType, options)` (html deserializer)
66
-
67
- This will deserialize the input html (string) into blocks.
68
-
69
- #### Params
70
-
71
- ##### `html`
72
-
73
- The stringified version of the HTML you are importing
74
-
75
- ##### `blockContentType`
76
-
77
- A compiled version of the block content schema type.
78
-
79
- The deserializer will respect the schema when deserializing the HTML elements to blocks.
80
-
81
- It only supports a subset of HTML tags. Any HTML tag not in the block-tools [whitelist](https://github.com/portabletext/editor/blob/main/packages/block-tools/src/constants.ts) will be deserialized to normal blocks/spans.
82
-
83
- For instance, if the schema doesn't allow H2 styles, all H2 HTML elements will be output like this:
84
-
85
- ```js
86
- {
87
- _type: 'block',
88
- style: 'normal'
89
- children: [
90
- {
91
- _type: 'span'
92
- text: 'Hello world!'
93
- }
94
- ]
95
- }
96
51
  ```
97
52
 
98
- ##### `options` (optional)
99
-
100
- ###### `parseHtml`
101
-
102
- The HTML-deserialization is done by default by the browser's native DOMParser.
103
- On the server side you can give the function `parseHtml`
104
- that parses the html into a DOMParser compatible model / API.
53
+ ### `htmlToBlocks(html, blockContentType, options?)`
105
54
 
106
- ###### JSDOM example
55
+ Converts HTML to Portable Text blocks using a Sanity block content schema type.
107
56
 
108
- ```js
109
- const {JSDOM} = require('jsdom')
110
- const {htmlToBlocks} = require('@portabletext/block-tools')
57
+ Internally delegates to `@portabletext/html` after converting the Sanity schema. Supports the same `parseHtml`, `rules`, and `keyGenerator` options. See the [`@portabletext/html` README](../html/README.md) for full documentation on rules, whitespace handling, image matchers, and paste source support.
111
58
 
112
- const blocks = htmlToBlocks(
113
- '<html><body><h1>Hello world!</h1><body></html>',
114
- blockContentType,
115
- {
116
- parseHtml: (html) => new JSDOM(html).window.document,
117
- },
118
- )
119
- ```
120
-
121
- ##### `rules`
59
+ **NOTE:** To use in Node.js, you need to provide a `parseHtml` option - generally using `JSDOM`:
122
60
 
123
- You may add your own rules to deal with special HTML cases.
61
+ ```ts
62
+ import {JSDOM} from 'jsdom'
124
63
 
125
- ```js
126
- htmlToBlocks(
127
- '<html><body><pre><code>const foo = "bar"</code></pre></body></html>',
128
- blockContentType,
129
- {
130
- parseHtml: (html) => new JSDOM(html),
131
- rules: [
132
- // Special rule for code blocks
133
- {
134
- deserialize(el, next, block) {
135
- if (el.tagName.toLowerCase() != 'pre') {
136
- return undefined
137
- }
138
- const code = el.children[0]
139
- const childNodes =
140
- code && code.tagName.toLowerCase() === 'code'
141
- ? code.childNodes
142
- : el.childNodes
143
- let text = ''
144
- childNodes.forEach((node) => {
145
- text += node.textContent
146
- })
147
- // Return this as an own block (via block helper function), instead of appending it to a default block's children
148
- return block({
149
- _type: 'code',
150
- language: 'javascript',
151
- text: text,
152
- })
153
- },
154
- },
155
- ],
156
- },
157
- )
64
+ const blocks = htmlToBlocks(html, blockContentType, {
65
+ parseHtml: (html) => new JSDOM(html).window.document,
66
+ })
158
67
  ```
159
68
 
160
- ### `normalizeBlock(block, [options={}])`
69
+ ### `normalizeBlock(block, options?)`
161
70
 
162
- Normalize a block object structure to make sure it has what it needs.
71
+ Normalize a block object structure to ensure it has `_key`, `_type`, `children`, and `markDefs`.
163
72
 
164
- ```js
73
+ ```ts
165
74
  import {normalizeBlock} from '@portabletext/block-tools'
166
75
 
167
- const partialBlock = {
76
+ const normalized = normalizeBlock({
168
77
  _type: 'block',
169
- children: [
170
- {
171
- _type: 'span',
172
- text: 'Foobar',
173
- marks: ['strong', 'df324e2qwe'],
174
- },
175
- ],
176
- }
177
- normalizeBlock(partialBlock, {allowedDecorators: ['strong']})
78
+ children: [{_type: 'span', text: 'Hello', marks: ['strong']}],
79
+ })
80
+ // => { _key: '...', _type: 'block', children: [{ _key: '...', _type: 'span', text: 'Hello', marks: ['strong'] }], markDefs: [] }
178
81
  ```
179
82
 
180
- Will produce
83
+ ## License
181
84
 
182
- ```
183
- {
184
- _key: 'randomKey0',
185
- _type: 'block',
186
- children: [
187
- {
188
- _key: 'randomKey00',
189
- _type: 'span',
190
- marks: ['strong'],
191
- text: 'Foobar'
192
- }
193
- ],
194
- markDefs: []
195
- }
196
- ```
85
+ MIT
package/lib/index.d.ts CHANGED
@@ -1,7 +1,88 @@
1
- import { a as TypedObject, i as HtmlParser, n as DeserializerRule, o as ImageSchemaMatcher, r as HtmlDeserializerOptions, s as SchemaMatchers, t as ArbitraryTypedObject } from "./_chunks-dts/types.js";
2
- import * as _portabletext_schema1 from "@portabletext/schema";
3
- import { PortableTextBlock, PortableTextObject, PortableTextSpan, PortableTextSpan as PortableTextSpan$1, PortableTextTextBlock, PortableTextTextBlock as PortableTextTextBlock$1, Schema } from "@portabletext/schema";
1
+ import { PortableTextBlock, PortableTextBlock as PortableTextBlock$1, PortableTextObject, PortableTextObject as PortableTextObject$1, PortableTextSpan, PortableTextSpan as PortableTextSpan$1, PortableTextTextBlock, PortableTextTextBlock as PortableTextTextBlock$1, Schema } from "@portabletext/schema";
4
2
  import { ArraySchemaType } from "@sanity/types";
3
+ /**
4
+ * Use the current `Schema` as well as the potential element props to determine
5
+ * what Portable Text Object to use to represent the element.
6
+ */
7
+ type ObjectSchemaMatcher<TProps extends Record<string, unknown>> = ({
8
+ context,
9
+ props
10
+ }: {
11
+ context: {
12
+ schema: Schema;
13
+ keyGenerator: () => string;
14
+ };
15
+ props: TProps;
16
+ }) => ArbitraryTypedObject | undefined;
17
+ /**
18
+ * Use the current `Schema` as well as the potential img element props to
19
+ * determine what Portable Text Object to use to represent the image.
20
+ * @beta
21
+ */
22
+ type ImageSchemaMatcher = ObjectSchemaMatcher<{
23
+ src?: string;
24
+ alt?: string;
25
+ [key: string]: string | undefined;
26
+ }>;
27
+ /**
28
+ * @beta
29
+ */
30
+ type SchemaMatchers = {
31
+ /**
32
+ * Called whenever the HTML parsing encounters an `<img>` element that is
33
+ * inferred to be a block element.
34
+ */
35
+ image?: ImageSchemaMatcher;
36
+ /**
37
+ * Called whenever the HTML parsing encounters an `<img>` element that is
38
+ * inferred to be an inline element.
39
+ */
40
+ inlineImage?: ImageSchemaMatcher;
41
+ };
42
+ /**
43
+ * @public
44
+ */
45
+ interface TypedObject {
46
+ _type: string;
47
+ _key?: string;
48
+ }
49
+ /**
50
+ * @public
51
+ */
52
+ interface ArbitraryTypedObject extends TypedObject {
53
+ [key: string]: unknown;
54
+ }
55
+ /**
56
+ * @public
57
+ */
58
+ type HtmlParser = (html: string) => Document;
59
+ /**
60
+ * @public
61
+ */
62
+ type WhiteSpacePasteMode = 'preserve' | 'remove' | 'normalize';
63
+ /**
64
+ * @public
65
+ */
66
+ interface HtmlDeserializerOptions {
67
+ keyGenerator?: () => string;
68
+ rules?: DeserializerRule[];
69
+ parseHtml?: HtmlParser;
70
+ unstable_whitespaceOnPasteMode?: WhiteSpacePasteMode;
71
+ /**
72
+ * Custom schema matchers to use when deserializing HTML to Portable Text.
73
+ * @beta
74
+ */
75
+ matchers?: SchemaMatchers;
76
+ }
77
+ /**
78
+ * @public
79
+ */
80
+ interface DeserializerRule {
81
+ deserialize: (el: Node, next: (elements: Node | Node[] | NodeList) => TypedObject | TypedObject[] | undefined, createBlock: (props: ArbitraryTypedObject) => {
82
+ _type: string;
83
+ block: ArbitraryTypedObject;
84
+ }) => TypedObject | TypedObject[] | undefined;
85
+ }
5
86
  /**
6
87
  * Block normalization options
7
88
  *
@@ -56,7 +137,5 @@ declare function randomKey(length: number): string;
56
137
  * @returns Array of blocks
57
138
  * @public
58
139
  */
59
- declare function htmlToBlocks(html: string, schemaType: ArraySchemaType | Schema, options?: HtmlDeserializerOptions): (Omit<TypedObject | _portabletext_schema1.PortableTextTextBlock<TypedObject | _portabletext_schema1.PortableTextSpan>, "_key"> & {
60
- _key: string;
61
- })[];
140
+ declare function htmlToBlocks(html: string, schemaType: ArraySchemaType | Schema, options?: HtmlDeserializerOptions): PortableTextBlock$1[];
62
141
  export { type ArbitraryTypedObject, type BlockNormalizationOptions, type DeserializerRule, type HtmlDeserializerOptions, type HtmlParser, type ImageSchemaMatcher, type PortableTextBlock, type PortableTextObject, type PortableTextSpan, type PortableTextTextBlock, type SchemaMatchers, type TypedObject, htmlToBlocks, normalizeBlock, randomKey };