@@ -19,30 +19,50 @@ export function parseFrontmatter(frontmatter: string): Record<string, string> {
1919 * @returns Line with YAML inline comment removed when applicable.
2020 */
2121 function stripInlineComment ( line : string ) : string {
22- let inSingleQuote = false ;
23- let inDoubleQuote = false ;
24- let escaped = false ;
22+ const quoteState = { inSingleQuote : false , inDoubleQuote : false , escaped : false } ;
23+ const characters = Array . from ( line ) ;
2524
26- for ( let index = 0 ; index < line . length ; index += 1 ) {
27- const char = line [ index ] ;
28- const previous = index > 0 ? line [ index - 1 ] : "" ;
25+ /**
26+ * Determines whether a single-character token should count as whitespace.
27+ *
28+ * @param value - Single-character token.
29+ * @returns True when the token is whitespace.
30+ */
31+ function isWhitespace ( value : string ) : boolean {
32+ return value . trim ( ) . length === 0 ;
33+ }
34+
35+ // Walk the line left-to-right so we can stop at the first valid inline comment marker.
36+ for ( const [ index , char ] of characters . entries ( ) ) {
37+ const previous = index > 0 ? characters [ index - 1 ] : "" ;
2938
30- if ( char === "\\" && inDoubleQuote && ! escaped ) {
31- escaped = true ;
39+ // Track escapes only inside double-quoted strings so escaped quotes do not toggle quote state.
40+ if ( char === "\\" && quoteState . inDoubleQuote && ! quoteState . escaped ) {
41+ quoteState . escaped = true ;
3242 continue ;
3343 }
3444
35- if ( char === "'" && ! inDoubleQuote ) {
36- inSingleQuote = ! inSingleQuote ;
37- } else if ( char === '"' && ! inSingleQuote && ! escaped ) {
38- inDoubleQuote = ! inDoubleQuote ;
45+ // Toggle quote tracking so # inside quoted text is preserved as literal content.
46+ if ( char === "'" && ! quoteState . inDoubleQuote ) {
47+ quoteState . inSingleQuote = ! quoteState . inSingleQuote ;
48+ }
49+
50+ // Toggle double-quote tracking so escaped quotes do not prematurely end quoted text.
51+ if ( char === '"' && ! quoteState . inSingleQuote && ! quoteState . escaped ) {
52+ quoteState . inDoubleQuote = ! quoteState . inDoubleQuote ;
3953 }
4054
41- if ( char === "#" && ! inSingleQuote && ! inDoubleQuote && ( ! previous || / \s / . test ( previous ) ) ) {
55+ // Treat # as an inline comment marker only when it appears outside quotes after whitespace.
56+ if (
57+ char === "#" &&
58+ ! quoteState . inSingleQuote &&
59+ ! quoteState . inDoubleQuote &&
60+ ( ! previous || isWhitespace ( previous ) )
61+ ) {
4262 return line . slice ( 0 , index ) . trimEnd ( ) ;
4363 }
4464
45- escaped = false ;
65+ quoteState . escaped = false ;
4666 }
4767
4868 return line ;
0 commit comments