UNPKG

@portabletext/toolkit

Version:

Toolkit of handy utility functions for dealing with Portable Text

51 lines (43 loc) 1.61 kB
import type {ArbitraryTypedObject, PortableTextBlock} from '@portabletext/types' import {isPortableTextBlock, isPortableTextSpan} from './asserters' const leadingSpace = /^\s/ const trailingSpace = /\s$/ /** * Takes a Portable Text block (or an array of them) and returns the text value * of all the Portable Text span nodes. Adds whitespace when encountering inline, * non-span nodes to ensure text flow is optimal. * * Note that this only accounts for regular Portable Text blocks - any text inside * custom content types are not included in the output. * * @param block - Single block or an array of blocks to extract text from * @returns The plain-text content of the blocks */ export function toPlainText( block: PortableTextBlock | ArbitraryTypedObject[] | PortableTextBlock[], ): string { const blocks = Array.isArray(block) ? block : [block] let text = '' blocks.forEach((current, index) => { if (!isPortableTextBlock(current)) { return } let pad = false current.children.forEach((span) => { if (isPortableTextSpan(span)) { // If the previous element was a non-span, and we have no natural whitespace // between the previous and the next span, insert it to give the spans some // room to breathe. However, don't do so if this is the first span. text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? ' ' : '' text += span.text pad = false } else { pad = true } }) if (index !== blocks.length - 1) { text += '\n\n' } }) return text }