@@ -220,7 +220,64 @@ document.addEventListener("DOMContentLoaded", function () {
220220 } ) ;
221221 }
222222
223- const sampleMarkdown = `# Welcome to Markdown Viewer
223+ function parseFrontmatter ( markdown ) {
224+ const match = markdown . match ( / ^ - - - \r ? \n ( [ \s \S ] * ?) \r ? \n - - - ( \r ? \n | $ ) / ) ;
225+ if ( ! match ) return { frontmatter : null , body : markdown } ;
226+ try {
227+ const data = jsyaml . load ( match [ 1 ] ) || { } ;
228+ return { frontmatter : data , body : markdown . slice ( match [ 0 ] . length ) } ;
229+ } catch ( e ) {
230+ console . warn ( 'Frontmatter YAML parse error:' , e ) ;
231+ return { frontmatter : null , body : markdown } ;
232+ }
233+ }
234+
235+ function renderFrontmatterValue ( value ) {
236+ if ( value === null || value === undefined ) return '' ;
237+ if ( value instanceof Date ) {
238+ const y = value . getUTCFullYear ( ) ;
239+ const m = String ( value . getUTCMonth ( ) + 1 ) . padStart ( 2 , '0' ) ;
240+ const d = String ( value . getUTCDate ( ) ) . padStart ( 2 , '0' ) ;
241+ return `${ y } -${ m } -${ d } ` ;
242+ }
243+ if ( Array . isArray ( value ) ) {
244+ const allPrimitive = value . every ( v => v === null || typeof v !== 'object' ) ;
245+ if ( allPrimitive ) {
246+ return value
247+ . map ( v => `<span class="fm-tag">${ escapeHtml ( String ( v ?? '' ) ) } </span>` )
248+ . join ( '' ) ;
249+ }
250+ return `<pre class="fm-complex">${ escapeHtml ( jsyaml . dump ( value ) . trimEnd ( ) ) } </pre>` ;
251+ }
252+ if ( typeof value === 'object' ) {
253+ return `<pre class="fm-complex">${ escapeHtml ( jsyaml . dump ( value ) . trimEnd ( ) ) } </pre>` ;
254+ }
255+ return escapeHtml ( String ( value ) ) ;
256+ }
257+
258+ function renderFrontmatterTable ( data ) {
259+ const rows = Object . entries ( data ) . map ( ( [ key , value ] ) =>
260+ `<tr><th>${ escapeHtml ( key ) } </th><td>${ renderFrontmatterValue ( value ) } </td></tr>`
261+ ) ;
262+ return `<table class="frontmatter-table"><tbody>${ rows . join ( '' ) } </tbody></table>` ;
263+ }
264+
265+ function escapeHtml ( str ) {
266+ return str
267+ . replace ( / & / g, '&' )
268+ . replace ( / < / g, '<' )
269+ . replace ( / > / g, '>' )
270+ . replace ( / " / g, '"' ) ;
271+ }
272+
273+ const sampleMarkdown = `---
274+ title: Welcome to Markdown Viewer
275+ description: A GitHub-style Markdown renderer with live preview, math, diagrams, and export support.
276+ author: ThisIs-Developer
277+ tags: ["markdown", "preview", "mermaid", "latex", "open-source"]
278+ ---
279+
280+ # Welcome to Markdown Viewer
224281
225282## ✨ Key Features
226283- **Live Preview** with GitHub styling
@@ -853,8 +910,9 @@ This is a fully client-side application. Your content never leaves your browser
853910
854911 function renderMarkdown ( ) {
855912 try {
856- const markdown = markdownEditor . value ;
857- const html = marked . parse ( markdown ) ;
913+ const { frontmatter, body } = parseFrontmatter ( markdownEditor . value ) ;
914+ const tableHtml = frontmatter ? renderFrontmatterTable ( frontmatter ) : '' ;
915+ const html = tableHtml + marked . parse ( body ) ;
858916 const sanitizedHtml = DOMPurify . sanitize ( html , {
859917 ADD_TAGS : [ 'mjx-container' ] ,
860918 ADD_ATTR : [ 'id' , 'class' , 'style' ]
0 commit comments