import { fromMarkdown } from 'mdast-util-from-markdown'; import { toMarkdown } from 'mdast-util-to-markdown'; import test from 'tape'; import { removePosition } from 'unist-util-remove-position'; import { DirectiveType } from '../src/mdast-util-growi-plugin/consts.js'; import { directiveFromMarkdown, directiveToMarkdown } from '../src/mdast-util-growi-plugin/index.js'; import { directive } from '../src/micromark-extension-growi-plugin/index.js'; test('markdown -> mdast', (t) => { t.deepEqual( fromMarkdown('a $b[c](d) e.', { extensions: [directive()], mdastExtensions: [directiveFromMarkdown], }).children[0], { type: 'paragraph', children: [ { type: 'text', value: 'a ', position: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 3, offset: 2 }, }, }, { type: DirectiveType.Text, name: 'b', attributes: { d: '' }, children: [ { type: 'text', value: 'c', position: { start: { line: 1, column: 6, offset: 5 }, end: { line: 1, column: 7, offset: 6 }, }, }, ], position: { start: { line: 1, column: 3, offset: 2 }, end: { line: 1, column: 11, offset: 10 }, }, }, { type: 'text', value: ' e.', position: { start: { line: 1, column: 11, offset: 10 }, end: { line: 1, column: 14, offset: 13 }, }, }, ], position: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 14, offset: 13 }, }, }, 'should support directives (text)', ); t.deepEqual( fromMarkdown('$a[b](c)', { extensions: [directive()], mdastExtensions: [directiveFromMarkdown], }).children[0], { type: DirectiveType.Leaf, name: 'a', attributes: { c: '' }, children: [ { type: 'text', value: 'b', position: { start: { line: 1, column: 4, offset: 3 }, end: { line: 1, column: 5, offset: 4 }, }, }, ], position: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 9, offset: 8 }, }, }, 'should support directives (leaf)', ); t.deepEqual( removePosition( fromMarkdown('x $a[b *c*\nd]', { extensions: [directive()], mdastExtensions: [directiveFromMarkdown], }), true, ), { type: 'root', children: [ { type: 'paragraph', children: [ { type: 'text', value: 'x ' }, { type: DirectiveType.Text, name: 'a', attributes: {}, children: [ { type: 'text', value: 'b ' }, { type: 'emphasis', children: [{ type: 'text', value: 'c' }] }, { type: 'text', value: '\nd' }, ], }, ], }, ], }, 'should support content in a label', ); t.deepEqual( removePosition( fromMarkdown('x $a(#b.c.d e=f g="h&i&unknown;j")', { extensions: [directive()], mdastExtensions: [directiveFromMarkdown], }), true, ), { type: 'root', children: [ { type: 'paragraph', children: [ { type: 'text', value: 'x ' }, { type: DirectiveType.Text, name: 'a', attributes: { id: 'b', class: 'c d', e: 'f', g: 'h&i&unknown;j', }, children: [], }, ], }, ], }, 'should support attributes', ); t.deepEqual( removePosition( fromMarkdown('$a(b\nc="d\ne")', { extensions: [directive()], mdastExtensions: [directiveFromMarkdown], }), true, ), { type: 'root', children: [ { type: 'paragraph', children: [ { type: DirectiveType.Text, name: 'a', attributes: { b: '', c: 'd\ne' }, children: [], }, ], }, ], }, 'should support EOLs in attributes', ); t.end(); }); test('mdast -> markdown', (t) => { t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, // @ts-expect-error: `children`, `name` missing. { type: DirectiveType.Text }, { type: 'text', value: ' b.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $ b.\n', 'should try to serialize a directive (text) w/o `name`', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, // @ts-expect-error: `children` missing. { type: DirectiveType.Text, name: 'b' }, { type: 'text', value: ' c.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b c.\n', 'should serialize a directive (text) w/ `name`', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', children: [{ type: 'text', value: 'c' }], }, { type: 'text', value: ' d.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b[c] d.\n', 'should serialize a directive (text) w/ `children`', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', children: [{ type: 'text', value: 'c[d]e' }], }, { type: 'text', value: ' f.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b[c\\[d\\]e] f.\n', 'should escape brackets in a directive (text) label', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', children: [{ type: 'text', value: 'c\nd' }], }, { type: 'text', value: ' e.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b[c\nd] e.\n', 'should support EOLs in a directive (text) label', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', // @ts-expect-error: should contain only `string`s attributes: { c: 'd', e: 'f', g: '', h: null, i: undefined, j: 2, }, children: [], }, { type: 'text', value: ' k.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b(c="d" e="f" g j="2") k.\n', 'should serialize a directive (text) w/ `attributes`', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', attributes: { class: 'a b\nc', id: 'd', key: 'value' }, children: [], }, { type: 'text', value: ' k.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b(#d .a.b.c key="value") k.\n', 'should serialize a directive (text) w/ `id`, `class` attributes', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', attributes: { x: 'y"\'\r\nz' }, children: [], }, { type: 'text', value: ' k.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b(x="y"\'\r\nz") k.\n', 'should encode the quote in an attribute value (text)', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', attributes: { x: 'y"\'\r\nz' }, children: [], }, { type: 'text', value: ' k.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b(x="y"\'\r\nz") k.\n', 'should encode the quote in an attribute value (text)', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', attributes: { id: 'c#d' }, children: [], }, { type: 'text', value: ' e.' }, ], }, { extensions: [directiveToMarkdown] }, ), 'a $b(id="c#d") e.\n', 'should not use the `id` shortcut if impossible characters exist', ); t.deepEqual( toMarkdown( { type: 'paragraph', children: [ { type: 'text', value: 'a ' }, { type: DirectiveType.Text, name: 'b', attributes: { class: 'c.d e