@@ -3,64 +3,100 @@ import { useEffect, useState, useMemo, useRef } from 'react';
33type TerminalExample = {
44 name : string ;
55 lines : string [ ] ;
6- delay : number ; // Delay before starting next example
76} ;
87
98interface AnimatedTerminalProps {
109 version ?: string | null ;
1110}
1211
12+ /**
13+ * Dedent a multiline string by removing common leading whitespace
14+ * and split it into lines
15+ */
16+ function dedentAndSplit ( text : string ) : string [ ] {
17+ const lines = text . split ( '\n' ) ;
18+
19+ // Trim leading and trailing empty lines
20+ while ( lines . length > 0 && lines [ 0 ] . trim ( ) . length === 0 ) {
21+ lines . shift ( ) ;
22+ }
23+ while ( lines . length > 0 && lines [ lines . length - 1 ] . trim ( ) . length === 0 ) {
24+ lines . pop ( ) ;
25+ }
26+
27+ // Find the minimum indentation (excluding empty lines)
28+ let minIndent = Infinity ;
29+ for ( const line of lines ) {
30+ if ( line . trim ( ) . length > 0 ) {
31+ const indent = line . match ( / ^ ( \s * ) / ) ?. [ 1 ] . length || 0 ;
32+ minIndent = Math . min ( minIndent , indent ) ;
33+ }
34+ }
35+
36+ // If no indentation found, return lines as-is
37+ if ( minIndent === Infinity ) {
38+ return lines ;
39+ }
40+
41+ // Remove the common indentation from all lines
42+ return lines . map ( line => {
43+ if ( line . trim ( ) . length === 0 ) {
44+ return '' ;
45+ }
46+ return line . slice ( minIndent ) ;
47+ } ) ;
48+ }
49+
1350const getExamples = ( version : string = '9.8.0' ) : TerminalExample [ ] => [
1451 {
1552 name : 'NumPy Basics' ,
16- lines : [
17- '$ ipython' ,
18- `IPython ${ version } -- An enhanced Interactive Python` ,
19- "Type 'copyright', 'credits' or 'license' for more information" ,
20- '' ,
21- 'In [1]: import numpy as np' ,
22- '' ,
23- 'In [2]: data = np.array([1, 2, 3, 4, 5])' ,
24- '' ,
25- 'In [3]: data.mean()' ,
26- 'Out[3]: 3.0' ,
27- ] ,
28- delay : 4000 ,
53+ lines : dedentAndSplit ( `
54+ $ ipython
55+ IPython ${ version } -- An enhanced Interactive Python
56+ Type 'copyright', 'credits' or 'license' for more information
57+
58+ In [1]: import numpy as np
59+
60+ In [2]: data = np.array([1, 2, 3, 4, 5])
61+
62+ In [3]: data.mean()
63+ Out[3]: 3.0
64+ ` ) ,
2965 } ,
3066 {
3167 name : 'Performance & Plotting' ,
32- lines : [
33- '$ ipython' ,
34- `IPython ${ version } -- An enhanced Interactive Python` ,
35- '' ,
36- 'In [1]: %timeit sum(range(1000))' ,
37- '14.2 µs ± 245 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)' ,
38- '' ,
39- 'In [2]: %matplotlib inline' ,
40- '' ,
41- 'In [3]: import matplotlib.pyplot as plt' ,
42- ] ,
43- delay : 4000 ,
68+ lines : dedentAndSplit ( `
69+ $ ipython
70+ IPython ${ version } -- An enhanced Interactive Python
71+
72+ In [1]: %timeit sum(range(1000))
73+ 14.2 µs ± 245 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
74+
75+ In [2]: %matplotlib inline
76+
77+ In [3]: import matplotlib.pyplot as plt
78+ ` ) ,
4479 } ,
4580 {
4681 name : 'Functions' ,
47- lines : [
48- '$ ipython' ,
49- `IPython ${ version } -- An enhanced Interactive Python` ,
50- '' ,
51- 'In [1]: def fibonacci(n):' ,
52- ' ...: if n <= 1:' ,
53- ' ...: return n' ,
54- ' ...: return fibonacci(n-1) + fibonacci(n-2)' ,
55- ' ...: ' ,
56- '' ,
57- 'In [2]: fibonacci(10)' ,
58- 'Out[2]: 55' ,
59- ] ,
60- delay : 4000 ,
82+ lines : dedentAndSplit ( `
83+ $ ipython
84+ IPython ${ version } -- An enhanced Interactive Python
85+
86+ In [1]: def fibonacci(n):
87+ ...: if n <= 1:
88+ ...: return n
89+ ...: return fibonacci(n-1) + fibonacci(n-2)
90+ ...:
91+
92+ In [2]: fibonacci(10)
93+ Out[2]: 55
94+ ` ) ,
6195 } ,
6296] ;
6397
98+ const EXAMPLE_DELAY = 4000 ; // Delay before starting next example
99+
64100export default function AnimatedTerminal ( { version } : AnimatedTerminalProps ) {
65101 const examples = useMemo ( ( ) => getExamples ( version || undefined ) , [ version ] ) ;
66102 const [ currentExample , setCurrentExample ] = useState ( 0 ) ;
@@ -139,7 +175,7 @@ export default function AnimatedTerminal({ version }: AnimatedTerminalProps) {
139175 setCurrentLineIndex ( 0 ) ;
140176 setDisplayedLines ( [ ] ) ;
141177 }
142- } , example . delay ) ;
178+ } , EXAMPLE_DELAY ) ;
143179
144180 return ( ) => clearTimeout ( timer ) ;
145181 }
0 commit comments