@@ -85,17 +85,26 @@ if (errors.length > 0) {
8585
8686examples . sort ( ( a , b ) => a . title . localeCompare ( b . title ) ) ;
8787
88+ // Compare the table by content, not formatting, so tools like Prettier
89+ // can reflow it without the check calling it stale.
8890const readme = readFileSync ( readmePath , "utf8" ) ;
89- const updated = withFreshTable ( readme ) ;
91+ const expectedRows = examples . map ( ( example ) => [
92+ `[\`${ example . id } \`](examples/${ example . id } )` ,
93+ example . description ,
94+ example . type
95+ ] ) ;
96+ const inSync = JSON . stringify ( tableRows ( readme ) ) === JSON . stringify ( expectedRows ) ;
9097
9198if ( checkOnly ) {
92- if ( updated !== readme ) {
99+ if ( ! inSync ) {
93100 console . error ( "README.md example table is out of date. Run: node scripts/validate-examples.mjs" ) ;
94101 process . exit ( 1 ) ;
95102 }
96103 console . log ( `OK: ${ examples . length } example(s) validated, README table in sync.` ) ;
104+ } else if ( inSync ) {
105+ console . log ( `Validated ${ examples . length } example(s), README table already up to date.` ) ;
97106} else {
98- writeFileSync ( readmePath , updated ) ;
107+ writeFileSync ( readmePath , withFreshTable ( readme ) ) ;
99108 console . log ( `Validated ${ examples . length } example(s) and updated README.md.` ) ;
100109}
101110
@@ -105,7 +114,21 @@ function asList(value) {
105114 return [ ] ;
106115}
107116
108- function withFreshTable ( text ) {
117+ function tableRows ( text ) {
118+ const [ startAt , endAt ] = markerPositions ( text ) ;
119+ const rows = [ ] ;
120+ for ( const line of text . slice ( startAt , endAt ) . split ( "\n" ) ) {
121+ const trimmed = line . trim ( ) ;
122+ if ( ! trimmed . startsWith ( "|" ) ) continue ;
123+ const cells = trimmed . split ( "|" ) . slice ( 1 , - 1 ) . map ( ( cell ) => cell . trim ( ) ) ;
124+ if ( cells . length === 0 || cells [ 0 ] === "Example" ) continue ;
125+ if ( / ^ : ? - + : ? $ / . test ( cells [ 0 ] ) ) continue ;
126+ rows . push ( cells ) ;
127+ }
128+ return rows ;
129+ }
130+
131+ function markerPositions ( text ) {
109132 const start = "<!-- examples:start -->" ;
110133 const end = "<!-- examples:end -->" ;
111134 const startAt = text . indexOf ( start ) ;
@@ -114,11 +137,14 @@ function withFreshTable(text) {
114137 console . error ( `README.md is missing the ${ start } / ${ end } markers.` ) ;
115138 process . exit ( 1 ) ;
116139 }
140+ return [ startAt + start . length , endAt ] ;
141+ }
117142
143+ function withFreshTable ( text ) {
144+ const [ startAt , endAt ] = markerPositions ( text ) ;
118145 const rows = examples . map (
119146 ( example ) => `| [\`${ example . id } \`](examples/${ example . id } ) | ${ example . description } | ${ example . type } |`
120147 ) ;
121148 const table = [ "| Example | Description | Type |" , "| --- | --- | --- |" , ...rows ] . join ( "\n" ) ;
122-
123- return text . slice ( 0 , startAt + start . length ) + "\n" + table + "\n" + text . slice ( endAt ) ;
149+ return text . slice ( 0 , startAt ) + "\n" + table + "\n" + text . slice ( endAt ) ;
124150}
0 commit comments