@@ -28,22 +28,10 @@ const myTheme = createCssVariablesTheme({
2828 * @param {DataFixture } data - The state object containing the necessary data for HTML generation.
2929 * @returns {Promise<string> } A promise that resolves to the generated HTML content.
3030 */
31- export async function generateHtml ( {
32- stateName,
33- state,
34- languageId : lang ,
35- command,
36- ide,
37- raw
38- } : {
39- stateName : string ;
40- state : TestCaseSnapshot ;
41- languageId : BundledLanguage ;
42- command ?: any ; // Replace `any` with the appropriate type if with
43- ide ?: any ; // Replace `any` with the appropriate type if known
44- raw : any ;
45- } ) {
46- return new HTMLGenerator ( { state, lang, command, ide, raw } ) . generate ( ) ;
31+ export async function generateHtml ( data : DataFixture ) {
32+ const HTMLOBject = await new HTMLGenerator ( data )
33+ const returnObject = HTMLOBject . generateAll ( )
34+ return returnObject ;
4735}
4836
4937const highlighter = createHighlighter ( {
@@ -61,63 +49,146 @@ type ExtendedTestCaseSnapshot = TestCaseSnapshot &
6149} ;
6250
6351class HTMLGenerator {
64- private state : TestCaseSnapshot ;
52+ private testCaseStates : {
53+ before : ExtendedTestCaseSnapshot | undefined ;
54+ during : ExtendedTestCaseSnapshot | undefined ;
55+ after : ExtendedTestCaseSnapshot | undefined ;
56+ }
6557 private lang : Lang ;
66- private command ?: any ;
67- private ide ?: any ;
68- private raw : any ;
69-
70- constructor ( {
71- state,
72- lang,
73- command,
74- ide,
75- raw
76- } : {
77- state : TestCaseSnapshot ,
78- lang : Lang ,
79- command ?: any ,
80- ide ?: any ,
81- raw ?: any
82- } ) {
83- this . state = state ;
84- this . lang = lang ;
58+ private command ?: CommandLatest | Command ;
59+ private raw : TestCaseFixture ;
60+ private rendered : {
61+ before : string ;
62+ during : string ;
63+ after : string ;
64+ }
65+
66+ constructor ( data : DataFixture ) {
67+ const { languageId, command } = data ;
68+ this . lang = languageId as BundledLanguage ;
8569 this . command = command ; // Optional command parameter
86- this . ide = ide ; // Optional ide parameter
87- this . raw = raw
70+ this . raw = data
71+ this . rendered = {
72+ before : "" ,
73+ during : "" ,
74+ after : "" ,
75+ }
76+ this . testCaseStates = {
77+ before : data . initialState ,
78+ during : {
79+ ...(
80+ /**
81+ * Spread the document state with more lines (finalState vs initialState),
82+ * so Shiki decorations stay in bounds and don't go out of range.
83+ */
84+ data . finalState &&
85+ ( data . finalState . documentContents ?. split ( "\n" ) . length > data . initialState . documentContents ?. split ( "\n" ) . length )
86+ ? data . finalState
87+ : data . initialState
88+ ) ,
89+ ...data . ide ,
90+ finalStateMarkHelpers : {
91+ thatMark : data ?. finalState ?. thatMark ,
92+ sourceMark : data ?. finalState ?. sourceMark
93+ }
94+ } ,
95+ after : data . finalState
96+ }
8897 }
8998
99+ async generate ( stepName : StepNameType ) {
100+ const state = this . testCaseStates [ stepName ]
101+
102+ if ( ! state ) {
103+ console . error ( `Error in ${ stepName } ${ this . raw . command . spokenForm } ` )
104+ return "Error"
105+ }
106+
107+ const decorations = await this . getDecorations ( state ) ;
108+
109+ const { documentContents } = state
110+
111+ const htmlArray : string [ ] = [ ]
112+ let codeBody ;
113+
114+ const errorLevels = [
115+ "excludes thatMarks sourceMarks selectionRanges ideFlashes" ,
116+ "excludes thatMarks sourceMarks selectionRanges" ,
117+ "excludes thatMarks sourceMarks" ,
118+ "excludes thatMarks" ,
119+ "success" ,
120+ ]
121+
122+ let errorLevel = errorLevels . length - 1
90123
91- async generate ( ) {
92- const decorations = await this . getDecorations ( ) ;
93- const options = {
94- theme : "css-variables" ,
95- lang : this . lang ,
96- decorations
97- } ;
124+ for ( let i = decorations . length - 1 ; i >= 0 ; i -- ) {
125+ const fallbackDecoration = decorations . slice ( 0 , i ) . flat ( ) ;
126+ errorLevel = i
127+ try {
128+ const marker = await highlighter ;
129+ const options = {
130+ theme : "css-variables" ,
131+ lang : this . lang ,
132+ decorations : fallbackDecoration
133+ } ;
134+ codeBody = marker . codeToHtml ( documentContents , options ) ;
135+ htmlArray . push ( codeBody )
136+ break ; // Exit loop if successful
137+ } catch ( error ) {
138+ console . warn ( "Failed with decorations level:" , fallbackDecoration , error ) ;
139+ // Continue to the next fallback level
140+ }
141+ }
142+
143+ if ( ! codeBody ) {
144+ console . error ( "All fallback levels failed. Unable to generate code body." ) ;
145+ codeBody = "" ; // Provide a default empty string or handle as needed
146+ }
147+
148+ let clipboardRendered = ""
149+ if ( state . clipboard ) {
150+ clipboardRendered = `<pre><code>clipboard: ${ state . clipboard } </pre></code>`
151+ if ( clipboardRendered !== "" ) {
152+ htmlArray . push ( clipboardRendered )
153+ }
154+ }
155+
156+ let error = ""
157+ if ( errorLevel !== errorLevels . length - 1 ) {
158+ error = errorLevels [ errorLevel ]
159+ const errorRendered = `<pre><code>Omitted due to errors: ${ error } </pre></code>`
160+ htmlArray . push ( errorRendered )
161+ }
162+ return htmlArray . join ( "" )
163+ }
164+
165+ async generateAll ( ) {
98166
99- const marker = await highlighter
100- const codeBody = marker . codeToHtml ( this . state . documentContents , options )
101- let clipboard = ""
102- if ( this . state . clipboard ) {
103- clipboard = `<pre><code>clipboard: ${ this . state . clipboard } </pre></code>`
167+ const output = {
168+ before : await this . generate ( "before" ) ,
169+ during : await this . generate ( "during" ) ,
170+ after : await this . generate ( "after" ) ,
104171 }
105- const output = clipboard !== "" ? codeBody + clipboard : codeBody
106172 return output
107173 }
108174
109- async getDecorations ( ) {
110- const potentialMarks = this . state . marks || { }
111- const lines = this . state . documentContents . split ( "\n" )
112- console . log ( "💎" , this . state . thatMark )
113- const decorations = createDecorations ( {
175+ async getDecorations ( testCaseState : ExtendedTestCaseSnapshot ) {
176+ const { messages, flashes, highlights, finalStateMarkHelpers } = testCaseState
177+
178+ const potentialMarks = testCaseState . marks || { }
179+ const lines = testCaseState . documentContents . split ( "\n" )
180+ const obj = {
114181 marks : potentialMarks ,
115- ide : this . ide ,
182+ ide : { messages , flashes , highlights } ,
116183 command : this . command ,
117184 lines,
118- selections : this . state . selections ,
119- thatMark : this . state . thatMark
120- } )
185+ selections : testCaseState . selections ,
186+ thatMark : testCaseState . thatMark ,
187+ sourceMark : testCaseState . sourceMark ,
188+ finalStateMarkHelpers
189+ }
190+
191+ const decorations = createDecorations ( obj )
121192 return decorations
122193 }
123194}
0 commit comments