@@ -114,18 +114,39 @@ function appendTo(element: ParsedSlide | ContentClass, content: ContentItem): vo
114114}
115115
116116function extractProperties ( source : string , properties : Record < string , string > ) : string {
117- const propertyFinder = / ^ \n * ( [ - \w ] + ) : ( [ ^ $ \n ] * ) | \n * (?: < ! - - \s * ) ( [ - \w ] + ) : ( [ ^ $ \n ] * ?) (?: \s * - - > ) / i;
117+ if ( typeof source !== 'string' ) return source as unknown as string ;
118+
119+ // Extract inline HTML comment properties anywhere in the source (they are invisible markers).
120+ const commentFinder = / \n * (?: < ! - - \s * ) ( [ - \w ] + ) : ( [ ^ $ \n ] * ?) (?: \s * - - > ) / gi;
118121 let match : RegExpExecArray | null ;
119- while ( ( match = propertyFinder . exec ( source ) ) !== null ) {
122+ while ( ( match = commentFinder . exec ( source ) ) !== null ) {
120123 source = source . slice ( 0 , match . index ) + source . slice ( match . index + match [ 0 ] . length ) ;
121- if ( match [ 1 ] !== undefined ) {
122- properties [ match [ 1 ] . trim ( ) ] = match [ 2 ] . trim ( ) ;
123- } else {
124- properties [ match [ 3 ] . trim ( ) ] = match [ 4 ] . trim ( ) ;
125- }
126- propertyFinder . lastIndex = match . index ;
124+ properties [ match [ 1 ] . trim ( ) ] = match [ 2 ] . trim ( ) ;
125+ commentFinder . lastIndex = match . index ;
126+ }
127+
128+ // Extract plain `key: value` properties only from the leading front-matter block.
129+ // Stop as soon as a line that is not a property (or blank) is encountered so that
130+ // content lines like "Example: this disappears" are never consumed as properties.
131+ const lines = source . split ( '\n' ) ;
132+ const consumed : number [ ] = [ ] ;
133+ const propertyLine = / ^ ( [ - \w ] + ) : ( [ ^ $ \n ] * ) $ / i;
134+ let i = 0 ;
135+ // Skip leading blank lines.
136+ while ( i < lines . length && lines [ i ] . trim ( ) === '' ) { i ++ ; }
137+ // Consume contiguous property lines.
138+ while ( i < lines . length ) {
139+ const line = lines [ i ] ;
140+ if ( line . trim ( ) === '' ) break ; // blank line ends the front-matter block
141+ const m = propertyLine . exec ( line ) ;
142+ if ( ! m ) break ; // non-property line ends the block
143+ properties [ m [ 1 ] . trim ( ) ] = m [ 2 ] . trim ( ) ;
144+ consumed . push ( i ) ;
145+ i ++ ;
127146 }
128- return source ;
147+ // Remove consumed lines from source.
148+ const remaining = lines . filter ( ( _ , idx ) => ! consumed . includes ( idx ) ) ;
149+ return remaining . join ( '\n' ) ;
129150}
130151
131152function cleanInput ( source : string ) : string {
0 commit comments