@@ -218,36 +218,32 @@ async function runCodeInline() {
218218 }
219219 }
220220
221- // Capture stdout - filter tqdm and ensure newlines
221+ // Capture stdout - filter tqdm and ensure newlines after progress bars
222222 let fullOutput = '' ;
223+ let lastHadCarriageReturn = false ;
223224
224225 pyodide . setStdout ( {
225226 batched : ( text ) => {
226227 fullOutput += text ;
227228
228- // Split by actual newlines
229- const lines = fullOutput . split ( '\n' ) ;
229+ // Check if we need to insert newline after previous tqdm line
230+ let processedOutput = fullOutput ;
231+
232+ // Replace any sequence of: stuff \r final_stuff (not followed by \n) with: final_stuff \n
233+ // This ensures tqdm completion is followed by newline
234+ processedOutput = processedOutput . replace ( / [ ^ \n ] * \r ( [ ^ \r \n ] + ) (? ! \n ) / g, '$1\n' ) ;
235+
236+ // Now split by newlines and clean up
237+ const lines = processedOutput . split ( '\n' ) ;
230238 const cleanLines = [ ] ;
231239
232- for ( let i = 0 ; i < lines . length ; i ++ ) {
233- const line = lines [ i ] ;
234-
235- // If this line has \r (tqdm), take only the last part after final \r
236- if ( line . includes ( '\r' ) ) {
237- const parts = line . split ( '\r' ) ;
238- const lastPart = parts [ parts . length - 1 ] . trim ( ) ;
239- if ( lastPart ) {
240- cleanLines . push ( lastPart ) ;
241- }
242- } else {
243- const trimmed = line . trim ( ) ;
244- if ( trimmed ) {
245- cleanLines . push ( trimmed ) ;
246- }
240+ for ( let line of lines ) {
241+ const trimmed = line . trim ( ) ;
242+ if ( trimmed ) {
243+ cleanLines . push ( trimmed ) ;
247244 }
248245 }
249246
250- // Display with explicit newlines between everything
251247 output . innerHTML = `<pre style="margin: 0; color: #d4d4d4; white-space: pre-wrap;">${ escapeHtml ( cleanLines . join ( '\n' ) ) } </pre>` ;
252248 }
253249 } ) ;
0 commit comments