function remarkCustomTags(customTags) {
	return ast =>
		visit(ast, 'html', node => {
			if (node.value.startsWith('<x-')) {
				// Parse tag’s HTML
				const dom = parse5.parseFragment(unescapeMarkdown(node.value));
				const tagNode = dom.childNodes[0];
				if (!tagNode) {
					throw new Error('Cannot parse custom tag:', node.value);
				}
				let { tagName, attrs } = tagNode;
				const childNode = tagNode.childNodes[0];
				attrs.push({
					name: 'children',
					value: childNode ? childNode.value.trim() : null,
				});
				tagName = tagName.replace(/^x-/, '');

				// Check tag function
				const tagFunction = customTags[tagName];
				if (!tagFunction || !_.isFunction(tagFunction)) {
					throw new Error(
						`Custom tag "${tagName}" is not defined or is not a function.`
					);
				}

				// Unzip attributes
				attrs = attrs.reduce((attrsObj, attr) => {
					attrsObj[attr.name] = attr.value;
					return attrsObj;
				}, {});

				// Render
				let result;
				try {
					result = tagFunction(attrs) || '';
				} catch (exception) {
					result = errorInlineHtml(
						`Error while rendering custom tag <x-${tagName}>: ${
							exception.message
						}`,
						{ block: true }
					);
				}
				node.value = result.toString().trim();
			}
		});
}
function remarkCustomTags(customTags) {
	return ast =>
		visit(ast, 'html', node => {
			if (node.value.startsWith('<x-')) {
				
				const dom = parse5.parseFragment(unescapeMarkdown(node.value));
				const tagNode = dom.childNodes[0];
				if (!tagNode) {
					throw new Error('Cannot parse custom tag:', node.value);
				}
				let { tagName, attrs } = tagNode;
				const childNode = tagNode.childNodes[0];
				attrs.push({
					name: 'children',
					value: childNode ? childNode.value.trim() : null,
				});
				tagName = tagName.replace(/^x-/, '');

				
				const tagFunction = customTags[tagName];
				if (!tagFunction || !_.isFunction(tagFunction)) {
					throw new Error(
						`Custom tag "${tagName}" is not defined or is not a function.`
					);
				}

				
				attrs = attrs.reduce((attrsObj, attr) => {
					attrsObj[attr.name] = attr.value;
					return attrsObj;
				}, {});

				
				let result;
				try {
					result = tagFunction(attrs) || '';
				} catch (exception) {
					result = errorInlineHtml(
						`Error while rendering custom tag <x-${tagName}>: ${
							exception.message
						}`,
						{ block: true }
					);
				}
				node.value = result.toString().trim();
			}
		});
}
function remarkCustomTags ( customTags ) { return ast => visit ( ast , 'html' , node => { if ( node . value . startsWith ( '<x-' ) ) { // Parse tag’s HTML const dom = parse5 . parseFragment ( unescapeMarkdown ( node . value ) ) ; const tagNode = dom . childNodes [ 0 ] ; if ( ! tagNode ) { throw new Error ( 'Cannot parse custom tag:' , node . value ) ; } let { tagName , attrs } = tagNode ; const childNode = tagNode . childNodes [ 0 ] ; attrs . push ( { name : 'children' , value : childNode ? childNode . value . trim ( ) : null , } ) ; tagName = tagName . replace ( / ^x- / , '' ) ; // Check tag function const tagFunction = customTags [ tagName ] ; if ( ! tagFunction || ! _ . isFunction ( tagFunction ) ) { throw new Error ( ` ${ tagName } ` ) ; } // Unzip attributes attrs = attrs . reduce ( ( attrsObj , attr ) => { attrsObj [ attr . name ] = attr . value ; return attrsObj ; } , { } ) ; // Render let result ; try { result = tagFunction ( attrs ) || '' ; } catch ( exception ) { result = errorInlineHtml ( ` ${ tagName } ${ exception . message } ` , { block : true } ) ; } node . value = result . toString ( ) . trim ( ) ; } } ) ; }
Remark plugin for custom tags: <x-foo data-value="42"/>

@param {Object} customTags
@return {Function}
Remark plugin for custom tags : <x - foo data - value = 42 / >