diff --git a/packages/core/src/asciidoctor-core-api.js b/packages/core/src/asciidoctor-core-api.js index 89e5c9788..860db4057 100644 --- a/packages/core/src/asciidoctor-core-api.js +++ b/packages/core/src/asciidoctor-core-api.js @@ -679,11 +679,157 @@ AbstractBlock.prototype.convert = function () { return this.$convert() } +/** + * @namespace + * @extends BuiltInContext + */ +Opal.Asciidoctor.BuiltInContext = { + /** + * One of five admonition blocks. + */ + Admonition: 'admonition', + /** + * An audio block. + */ + Audio: 'audio', + /** + * A callout list. + */ + CalloutList: 'colist', + /** + * A description list. + */ + DescriptionList: 'dlist', + /** + * The top-level document or the document in an AsciiDoc table cell. + */ + Document: 'document', + /** + * An example block. + */ + Example: 'example', + /** + * A discrete heading. + */ + FloatingTitle: 'floating_title', + /** + * An image block. + */ + Image: 'image', + /** + * An item in an ordered, unordered, or description list (only relevant inside a list or description list block). In a description list, this block is used to represent the term and the description. + */ + ListItem: 'list_item', + /** + * A listing block. + */ + Listing: 'list_item', + /** + * A literal block. + */ + Literal: 'list_item', + /** + * An ordered list. + */ + OrderedList: 'olist', + /** + * An open block. + */ + Open: 'open', + /** + * A page break. + */ + PageBreak: 'page_break', + /** + * A paragraph. + */ + Paragraph: 'paragraph', + /** + * A passthrough block. + */ + Passthrough: 'pass', + /** + * The preamble of the document. + */ + Preamble: 'preamble', + /** + * A quote block (aka blockquote). + */ + Quote: 'quote', + /** + * A section. May also be a part, chapter, or special section. + */ + Section: 'section', + /** + * A sidebar block. + */ + Sidebar: 'sidebar', + /** + * A table block. + */ + Table: 'table', + /** + * A table cell (only relevant inside a table block). + */ + TableCell: 'table_cell', + /** + * A thematic break (aka horizontal rule). + */ + ThematicBreak: 'thematic_break', + /** + * A TOC block. + */ + TableOfContent: 'toc', + /** + * An unordered list. + */ + UnorderedList: 'ulist', + /** + * An unordered list. + */ + Verse: 'verse', + /** + * A video block. + */ + Video: 'video' +} + /** * Query for all descendant block-level nodes in the document tree * that match the specified selector (context, style, id, and/or role). * If a function block is given, it's used as an additional filter. * If no selector or function block is supplied, all block-level nodes in the tree are returned. + * Valid context names include: + * + * @see https://docs.asciidoctor.org/asciidoc/latest/blocks/#summary-of-built-in-contexts * @param {Object} [selector] * @param {function} [block] * @example diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index e6c977fa8..99bfe921f 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -605,7 +605,123 @@ export namespace Asciidoctor { } } + /** + * List of the contexts of all the built-in blocks in AsciiDoc. + * @see https://docs.asciidoctor.org/asciidoc/latest/blocks/#summary-of-built-in-contexts + */ + enum BuiltInContext { + /** + * One of five admonition blocks. + */ + Admonition = "admonition", + /** + * An audio block. + */ + Audio = "audio", + /** + * A callout list. + */ + CalloutList = "colist", + /** + * A description list. + */ + DescriptionList = "dlist", + /** + * The top-level document or the document in an AsciiDoc table cell. + */ + Document = "document", + /** + * An example block. + */ + Example = "example", + /** + * A discrete heading. + */ + FloatingTitle = "floating_title", + /** + * An image block. + */ + Image = "image", + /** + * An item in an ordered, unordered, or description list (only relevant inside a list or description list block). In a description list, this block is used to represent the term and the description. + */ + ListItem = "list_item", + /** + * A listing block. + */ + Listing = "list_item", + /** + * A literal block. + */ + Literal = "list_item", + /** + * An ordered list. + */ + OrderedList = "olist", + /** + * An open block. + */ + Open = "open", + /** + * A page break. + */ + PageBreak = "page_break", + /** + * A paragraph. + */ + Paragraph = "paragraph", + /** + * A passthrough block. + */ + Passthrough = "pass", + /** + * The preamble of the document. + */ + Preamble = "preamble", + /** + * A quote block (aka blockquote). + */ + Quote = "quote", + /** + * A section. May also be a part, chapter, or special section. + */ + Section = "section", + /** + * A sidebar block. + */ + Sidebar = "sidebar", + /** + * A table block. + */ + Table = "table", + /** + * A table cell (only relevant inside a table block). + */ + TableCell = "table_cell", + /** + * A thematic break (aka horizontal rule). + */ + ThematicBreak = "thematic_break", + /** + * A TOC block. + */ + TableOfContent = "toc", + /** + * An unordered list. + */ + UnorderedList = "ulist", + /** + * An unordered list. + */ + Verse = "verse", + /** + * A video block. + */ + Video = "video", + } + interface Selector { + context: BuiltInContext | string [key: string]: any; } @@ -2134,6 +2250,8 @@ export namespace Asciidoctor { * that match the specified selector (context, style, id, and/or role). * If a function block is given, it's used as an additional filter. * If no selector or function block is supplied, all block-level nodes in the tree are returned. + * Valid context names include {@link BuiltInContext}. + * * @example * doc.findBy({'context': 'section'}); * // => { level: 0, title: "Hello, AsciiDoc!", blocks: 0 } @@ -3678,6 +3796,8 @@ export class Asciidoctor { */ getVersion(): string; + BuiltInContext: typeof Asciidoctor.BuiltInContext; + Block: typeof Asciidoctor.Block; Section: typeof Asciidoctor.Section; diff --git a/packages/core/types/tests.ts b/packages/core/types/tests.ts index 2dd8ea428..7335f4dc8 100644 --- a/packages/core/types/tests.ts +++ b/packages/core/types/tests.ts @@ -525,6 +525,7 @@ const result = docWithParagraphs.findBy((candidate) => { } else if (ctx === 'paragraph') { return true; } + return false; }); assert(result.length === 2); assert(result[0].getContext() === 'paragraph'); @@ -1114,10 +1115,10 @@ assert(rowsBySection[2][0] === 'foot'); const docWithParagraph = processor.load(`paragraph`); const paragraphBlock = docWithParagraph.getBlocks()[0]; -assert(paragraphBlock.resolveSubstitutions('attributes+', 'block')[0] === 'attributes'); +assert(paragraphBlock.resolveSubstitutions('attributes+', 'block')?.[0] === 'attributes'); const blockSubs1 = paragraphBlock.resolveBlockSubstitutions('specialchars,attributes,quotes,replacements,macros,post_replacements', 'block'); assert(blockSubs1.length === 6); -assert(blockSubs1[0] === 'specialcharacters'); +assert(blockSubs1?.[0] === 'specialcharacters'); assert(blockSubs1[1] === 'attributes'); assert(blockSubs1[2] === 'quotes'); assert(blockSubs1[3] === 'replacements'); @@ -1125,13 +1126,13 @@ assert(blockSubs1[4] === 'macros'); assert(blockSubs1[5] === 'post_replacements'); const blockSubs2 = paragraphBlock.resolveBlockSubstitutions('attributes+,+replacements,-callouts', ['verbatim', 'quotes', 'callouts']); assert(blockSubs2.length === 4); -assert(blockSubs2[0] === 'attributes'); +assert(blockSubs2?.[0] === 'attributes'); assert(blockSubs2[1] === 'verbatim'); assert(blockSubs2[2] === 'quotes'); assert(blockSubs2[3] === 'replacements'); const blockSubs3 = paragraphBlock.resolveBlockSubstitutions('normal'); assert(blockSubs3.length === 6); -assert(blockSubs3[0] === 'specialcharacters'); +assert(blockSubs3?.[0] === 'specialcharacters'); assert(blockSubs3[1] === 'quotes'); assert(blockSubs3[2] === 'attributes'); assert(blockSubs3[3] === 'replacements'); @@ -1139,10 +1140,10 @@ assert(blockSubs3[4] === 'macros'); assert(blockSubs3[5] === 'post_replacements'); const blockSubs4 = paragraphBlock.resolvePassSubstitutions('macros'); assert(blockSubs4.length === 1); -assert(blockSubs4[0] === 'macros'); +assert(blockSubs4?.[0] === 'macros'); const blockSubs5 = paragraphBlock.resolvePassSubstitutions('verbatim'); assert(blockSubs5.length === 1); -assert(blockSubs5[0] === 'specialcharacters'); +assert(blockSubs5?.[0] === 'specialcharacters'); const docWithImages = processor.load(` [#img-sunset] @@ -1183,6 +1184,7 @@ const outerParagraphs = docWithExample.findBy((candidate) => { } else if (ctx === 'paragraph') { return true; } + return false; }); assert(outerParagraphs.length === 2); assert(outerParagraphs[0].getContext() === 'paragraph'); @@ -1233,7 +1235,7 @@ a| :foo: foo AsciiDoc cell |===`); -const tableWithAsciiDocCell = docWithAsciiDocCell.findBy({context: 'table'})[0] as Asciidoctor.Table; +const tableWithAsciiDocCell = docWithAsciiDocCell.findBy({context: processor.BuiltInContext.Table})[0] as Asciidoctor.Table; const normalCell = tableWithAsciiDocCell.getBodyRows()[0][0]; const asciidocCell = tableWithAsciiDocCell.getBodyRows()[1][0]; assert(typeof normalCell.getInnerDocument() === 'undefined');