All files / blocks/markdown frontmatter-parser.js

100% Statements 30/30
96% Branches 24/25
100% Functions 4/4
100% Lines 28/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                1x 14x 4x     10x 10x 2x     8x 8x 7x         1x 1x                     1x 14x   22x           12x   12x 5x   12x 3x   12x 4x   12x 3x 3x 7x   3x     12x 12x    
import yaml from 'js-yaml';
 
/**
 * Parse YAML frontmatter from markdown content
 *
 * @param {string} content - Markdown content with optional frontmatter
 * @returns {Object} Object with frontmatter and body properties
 */
export const parseFrontMatter = (content) => {
	if (!content || typeof content !== 'string') {
		return { frontmatter: {}, body: content || '' };
	}
 
	const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
	if (!match) {
		return { frontmatter: {}, body: content };
	}
 
	try {
		const parsed = yaml.load(match[1]);
		return {
			frontmatter: parsed || {},
			body: match[2]
		};
	} catch (e) {
		console.warn('[WP GFM] YAML parse error:', e);
		return { frontmatter: {}, body: content };
	}
};
 
/**
 * Render frontmatter as HTML header
 *
 * @param {Object} fm - Frontmatter object
 * @param {Object} options - Rendering options
 * @returns {string} HTML string
 */
export const renderFrontmatterHeader = (fm, options = {}) => {
	if (!fm || Object.keys(fm).length === 0) return '';
 
	const escape = (str) => String(str)
		.replace(/&/g, '&')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;')
		.replace(/"/g, '&quot;');
 
	let html = '<header class="gfmr-frontmatter">';
 
	if (fm.title) {
		html += `<h1 class="gfmr-fm-title">${escape(fm.title)}</h1>`;
	}
	if (fm.date) {
		html += `<time class="gfmr-fm-date" datetime="${escape(fm.date)}">${escape(fm.date)}</time>`;
	}
	if (fm.author) {
		html += `<span class="gfmr-fm-author">${escape(fm.author)}</span>`;
	}
	if (fm.tags && Array.isArray(fm.tags)) {
		html += '<div class="gfmr-fm-tags">';
		fm.tags.forEach(tag => {
			html += `<span class="gfmr-fm-tag">${escape(tag)}</span>`;
		});
		html += '</div>';
	}
 
	html += '</header>';
	return html;
};