UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

40 lines (39 loc) 1.79 kB
import { renderMarkup } from "../render.js"; import { REACT_ELEMENT_TYPE } from "../util/internal.js"; import { BLOCK_CONTENT_REGEXP, BLOCK_SPACE_REGEXP, getBlockRegExp, LINE_SPACE_REGEXP } from "../util/regexp.js"; import { getMarkupRule } from "../util/rule.js"; const INDENT = /^\t/gm; // Nesting is recognised with tabs only. const NUMBER = "\\d{1,9}[.):]"; // Number for a numbered list, e.g. `1.` or `2)` or `3:` followed by one or more spaces. const ITEM = new RegExp(`(?:^|\n)(${NUMBER})(?:${LINE_SPACE_REGEXP}+(${BLOCK_CONTENT_REGEXP}))?${BLOCK_SPACE_REGEXP}*(?=\n${NUMBER}(?:\\s|$)|$)`, "g"); export const ORDERED_REGEXP = getBlockRegExp(`(?<list>${NUMBER}(?:${LINE_SPACE_REGEXP}+${BLOCK_CONTENT_REGEXP})?)`); /** * Ordered list. * - Line starting with number, followed by `.`, `)` or `:` character, then one or more space characters. * - No spaces can appear before the number character. * - Second-level list can be created by indenting with `\t` one tab. * - Sparse lists are not supported. */ export const ORDERED_RULE = getMarkupRule(ORDERED_REGEXP, ({ groups: { list } }, options, key) => ({ key, $$typeof: REACT_ELEMENT_TYPE, type: "ol", props: { children: Array.from(_getOrderedItems(list, options)), }, }), ["block", "list"]); /** Parse a markdown list into a set of items elements. */ function* _getOrderedItems(list, options) { let key = 0; for (const [_unused, number = "", item = ""] of list.matchAll(ITEM)) { yield { $$typeof: REACT_ELEMENT_TYPE, type: "li", props: { value: Number.parseInt(number, 10), children: renderMarkup(item.replace(INDENT, ""), options, "list"), }, key: key.toString(), }; key++; } }