TrySmalltalk.st 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. Widget subclass: #TrySmalltalkWidget
  2. instanceVariableNames: 'workspace'
  3. category: 'TrySmalltalk'!
  4. !TrySmalltalkWidget methodsFor: 'not yet classified'!
  5. renderOn: html
  6. html h1
  7. id: 'title';
  8. with: 'Try Smalltalk!!!!'.
  9. html div id: 'profStefWorkspace'.
  10. self appendWorkspace.
  11. !
  12. workspace
  13. ^ workspace ifNil: [
  14. workspace := ProfStefWorkspace new.
  15. ProfStef default widget: self.
  16. workspace]
  17. !
  18. appendWorkspace
  19. self workspace appendToJQuery: '#profStefWorkspace' asJQuery.
  20. ProfStef default showCurrentLesson.
  21. ! !
  22. Object subclass: #AbstractTutorial
  23. instanceVariableNames: ''
  24. category: 'TrySmalltalk'!
  25. !AbstractTutorial methodsFor: 'not yet classified'!
  26. indexOfLesson: aSelector
  27. ^self tableOfContents indexOf: aSelector.
  28. !
  29. tableOfContents
  30. ^ #(
  31. 'welcome'
  32. 'testLesson'
  33. 'theEnd'
  34. )
  35. !
  36. welcome
  37. ^ Lesson
  38. title: 'Welcome'
  39. contents: '"Hi, this is a test tutorial."'
  40. !
  41. testLesson
  42. ^ Lesson
  43. title: 'Test Lesson'
  44. contents: '"This lesson is a test"'
  45. !
  46. theEnd
  47. ^ Lesson
  48. title: 'The End'
  49. contents: '"And that''d be pretty much it :)"'
  50. !
  51. lessonAt: anInteger
  52. | lessonSelector |
  53. lessonSelector := self tableOfContents at: anInteger.
  54. ^ self perform: lessonSelector.
  55. !
  56. size
  57. ^ self tableOfContents size
  58. ! !
  59. Object subclass: #Lesson
  60. instanceVariableNames: 'title contents'
  61. category: 'TrySmalltalk'!
  62. !Lesson methodsFor: 'not yet classified'!
  63. contents
  64. ^ contents ifNil: [contents := '']
  65. !
  66. contents: aString
  67. contents := aString
  68. !
  69. title: aString
  70. title := aString
  71. !
  72. title
  73. ^ title ifNil: [title := '']
  74. ! !
  75. !Lesson class methodsFor: 'not yet classified'!
  76. title: aTitle contents: someContents
  77. ^ (self new)
  78. title: aTitle;
  79. contents: someContents
  80. ! !
  81. Object subclass: #TutorialPlayer
  82. instanceVariableNames: 'tutorialPosition tutorial'
  83. category: 'TrySmalltalk'!
  84. !TutorialPlayer methodsFor: 'not yet classified'!
  85. currentLesson
  86. ^ self tutorial lessonAt: self tutorialPosition.
  87. !
  88. first
  89. self rewind.
  90. ^ self currentLesson
  91. !
  92. last
  93. tutorialPosition := self size.
  94. ^ self currentLesson
  95. !
  96. next
  97. self tutorialPosition < self size
  98. ifTrue: [tutorialPosition := tutorialPosition + 1].
  99. ^ self currentLesson
  100. !
  101. previous
  102. tutorialPosition > 1 ifTrue: [tutorialPosition := tutorialPosition - 1].
  103. ^ self currentLesson
  104. !
  105. rewind
  106. tutorialPosition := 1.
  107. !
  108. size
  109. ^ self tutorial size
  110. !
  111. tutorial
  112. ^ tutorial ifNil: [tutorial := SmalltalkSyntaxTutorial new]
  113. !
  114. tutorial: aTutorial
  115. tutorial := aTutorial
  116. !
  117. tutorialPosition
  118. ^ tutorialPosition ifNil: [
  119. self rewind.
  120. tutorialPosition.
  121. ].
  122. !
  123. tutorialPosition: aTutorialPosition
  124. tutorialPosition := aTutorialPosition
  125. ! !
  126. Object subclass: #ProfStef
  127. instanceVariableNames: 'tutorialPlayer widget'
  128. category: 'TrySmalltalk'!
  129. !ProfStef methodsFor: 'not yet classified'!
  130. tutorialPlayer
  131. ^ tutorialPlayer ifNil: [tutorialPlayer := TutorialPlayer new]
  132. !
  133. first
  134. self tutorialPlayer first.
  135. ^ self showCurrentLesson.
  136. !
  137. progress
  138. ^ '(', self tutorialPositionString, '/', self tutorialSizeString, ')'.
  139. !
  140. tutorialPositionString
  141. ^ self tutorialPlayer tutorialPosition asString.
  142. !
  143. tutorialSizeString
  144. ^ self tutorialPlayer size asString
  145. !
  146. next
  147. self tutorialPlayer next.
  148. ^ self showCurrentLesson.
  149. !
  150. previous
  151. self tutorialPlayer previous.
  152. ^ self showCurrentLesson.
  153. !
  154. widget: aWidget
  155. widget := aWidget
  156. !
  157. showCurrentLesson
  158. | lesson |
  159. lesson := self tutorialPlayer currentLesson.
  160. widget workspace contents: lesson contents.
  161. widget workspace title: lesson title , ' ' , self progress.
  162. ! !
  163. ProfStef class instanceVariableNames: 'instance'!
  164. !ProfStef class methodsFor: 'not yet classified'!
  165. first
  166. ^ self default first.
  167. !
  168. default
  169. ^ instance ifNil: [instance := self new]
  170. !
  171. previous
  172. ^ self default previous.
  173. !
  174. next
  175. ^ self default next.
  176. !
  177. go
  178. self first.
  179. ! !
  180. AbstractTutorial subclass: #SmalltalkSyntaxTutorial
  181. instanceVariableNames: ''
  182. category: 'TrySmalltalk'!
  183. !SmalltalkSyntaxTutorial methodsFor: 'not yet classified'!
  184. tableOfContents
  185. ^ #( 'welcome'
  186. 'doingVSPrinting'
  187. 'printing'
  188. 'basicTypesNumbers'
  189. "'basicTypesCharacters'"
  190. 'basicTypesString'
  191. "'basicTypesSymbol'"
  192. 'basicTypesArray'
  193. "'basicTypesDynamicArray'"
  194. 'messageSyntaxUnary'
  195. 'messageSyntaxBinary'
  196. 'messageSyntaxKeyword'
  197. 'messageSyntaxExecutionOrder'
  198. 'messageSyntaxExecutionOrderParentheses'
  199. 'mathematicalPrecedence'
  200. 'messageSyntaxCascade'
  201. 'messageSyntaxCascadeShouldNotBeHere'
  202. 'blocks'
  203. 'blocksAssignation'
  204. 'conditionals'
  205. 'loops'
  206. 'iterators'
  207. 'instanciation'
  208. 'reflection'
  209. 'reflectionContinued'
  210. "'pharoEnvironment'"
  211. 'debugger'
  212. 'theEnd' )
  213. !
  214. basicTypesArray
  215. ^ Lesson
  216. title: 'Basic types: Array'
  217. contents:
  218. '"Literal arrays are created at parse time:"
  219. #(1 2 3).
  220. #( 1 2 3 #(4 5 6)) size.
  221. #(1 2 4) isEmpty.
  222. #(1 2 3) first.
  223. #(''hello'' ''Javascript'') at: 2 put: ''Smalltalk''; yourself.
  224. ProfStef next.'
  225. !
  226. basicTypesCharacters
  227. ^ Lesson
  228. title: 'Basic types: Characters'
  229. contents:
  230. '"A Character can be instantiated using $ operator:"
  231. $A.
  232. $A class.
  233. $B charCode.
  234. Character cr.
  235. Character space.
  236. "You can print all 256 characters of the ASCII extended set:"
  237. Character allByteCharacters.
  238. ProfStef next.'
  239. !
  240. basicTypesDynamicArray
  241. ^ Lesson
  242. title: 'Basic types: Dynamic Array'
  243. contents:
  244. '"Dynamic Arrays are created at execution time:"
  245. { (2+3) . (6*6) }.
  246. { (2+3) . (6*6) . ''hello'', '' Stef''} size.
  247. { ProfStef } first next.'
  248. !
  249. basicTypesNumbers
  250. ^ Lesson
  251. title: 'Basic types: Numbers'
  252. contents:
  253. '"You now know how to execute Smalltalk code.
  254. Now let''s talk about basic objects.
  255. 1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
  256. Evaluate these ones:"
  257. 2.
  258. (1/3).
  259. (1/3) + (4/5).
  260. (18/5) rounded.
  261. 1 class.
  262. 1 negated.
  263. 1 negated negated.
  264. (1 + 3) odd.
  265. ProfStef next.'
  266. !
  267. basicTypesString
  268. ^ Lesson
  269. title: 'Basic types: Strings'
  270. contents:
  271. '"A String is a collection of characters. Use single quotes to create a String object. Print these expressions:"
  272. ''ProfStef''.
  273. ''ProfStef'' size.
  274. ''abc'' asUppercase.
  275. ''Hello World'' reversed.
  276. "You can access each character using at: message"
  277. ''ProfStef'' at: 1.
  278. "String concatenation uses the comma operator:"
  279. ''ProfStef'', '' is cool''.
  280. ProfStef next.'
  281. !
  282. basicTypesSymbol
  283. ^ Lesson
  284. title: 'Basic types: Symbols'
  285. contents:
  286. '"A Symbol is a String which is guaranteed to be globally unique.
  287. There is one and only one Symbol #ProfStef. There may be several ''ProfStef'' String objects.
  288. (Message == returns true if the two objects are the SAME)"
  289. ''ProfStef'' asSymbol.
  290. #ProfStef asString.
  291. (2 asString) == (2 asString).
  292. (2 asString) asSymbol == (2 asString) asSymbol.
  293. (Smalltalk at: #ProfStef) next.'
  294. !
  295. blocks
  296. ^ Lesson
  297. title: 'Blocks'
  298. contents:
  299. '"Cascade is cool !! Let''s talk about blocks.
  300. Blocks are anonymous methods that can be stored into variables and executed on demand.
  301. Blocks are delimited by square brackets: []"
  302. [Transcript open].
  303. "does not open a Transcript because the block is not executed.
  304. Here is a block that adds 2 to its argument (its argument is named x):"
  305. [:x | x+2].
  306. "We can execute a block by sending it value messages."
  307. [:x | x+2] value: 5.
  308. [Transcript open] value.
  309. [:x | x+2] value: 10.
  310. [:x :y| x + y] value:3 value:5.
  311. [ProfStef next] value.'
  312. !
  313. blocksAssignation
  314. ^ Lesson
  315. title: 'Block assignation'
  316. contents:
  317. '"Blocks can be assigned to a variable then executed later.
  318. Note that |b| is the declaration of a variable named ''b'' and that '':='' assigns a value to a variable.
  319. Select the three lines then Print It:"
  320. |b|
  321. b := [:x | x+2].
  322. b value: 12.
  323. ProfStef next.'
  324. !
  325. conditionals
  326. ^ Lesson
  327. title: 'Conditionals'
  328. contents:
  329. '"Conditionals are just messages sent to Boolean objects"
  330. 1 < 2
  331. ifTrue: [100]
  332. ifFalse: [42].
  333. "Here the message is ifTrue:ifFalse
  334. Try this:"
  335. Transcript open.
  336. 3 > 10
  337. ifTrue: [Transcript show: ''maybe there''''s a bug ....'']
  338. ifFalse: [Transcript show: ''No : 3 is less than 10''].
  339. 3 = 3 ifTrue: [ProfStef next].'.
  340. !
  341. debugger
  342. ^ Lesson
  343. title: 'Debugger'
  344. contents: '"The Debugger may be the most famous tool of Smalltalk environments. It will open as soon as an unmanaged Exception occurs.
  345. The following code will open the debugger.
  346. ***This should be rethought completely***"
  347. '
  348. !
  349. doingVSPrinting
  350. ^ Lesson
  351. title: 'Doing VS Printing: Doing'
  352. contents:
  353. '"Cool !! (I like to say Cooool :) ). You''ve just executed a Smalltalk expression. More precisely, you sent the message ''next'' to
  354. ProfStef class (it''s me !!).
  355. Note you can run this tutorial again by evaluating: ''ProfStef go''.
  356. ''ProfStef previous'' returns to the previous lesson.
  357. You can also Do It using the keyboard shortcut ''CTRL d''
  358. Try to evaluate this expression:"
  359. window alert: ''hello world!!''.
  360. "Then go to the next lesson:"
  361. ProfStef next.'
  362. !
  363. instanciation
  364. ^ Lesson
  365. title: 'Instanciation'
  366. contents:
  367. '"Objects are instances of their class. Usually, we send the message #new to a class for creating an instance of this class.
  368. For example, let''s create an instance of the class Array:"
  369. Array new
  370. add: ''Some text'';
  371. add: 3.;
  372. yourself.
  373. "See the array we''ve created? Actually, #(''Some text'' 3) is just a shorthand for instantiating arrays."
  374. "If we use a variable to keep track of this object, we''ll be able to do stuff with it."
  375. "The following code must be ran all at one, as the ''anArray'' variable will cease to exist once the execution finishes:"
  376. |anArray|
  377. anArray := Array new
  378. add: ''Some text'';
  379. add: 3;
  380. yourself;
  381. Transcript show: anArray; cr.
  382. anArray remove: 3.
  383. Transcript show: anArray; cr.
  384. anArray add: ''Some more text!!''.
  385. Transcript show: anArray; cr.
  386. "I''ll put myself in an instance of a class named Dictionary and go to the next lesson:"
  387. ((Dictionary new add: (''move on!!'' -> ProfStef)) at: ''move on!!'') next'
  388. !
  389. iterators
  390. ^ Lesson
  391. title: 'Iterators'
  392. contents:
  393. '"The message do: is sent to a collection of objects (Array, Dictionary, String, etc), evaluating the block for each element.
  394. Here we want to print all the numbers on the Transcript (a console)"
  395. #(11 38 3 -2 10) do: [:each |
  396. Transcript show: each printString; cr].
  397. "Some other really nice iterators"
  398. #(11 38 3 -2 10) collect: [:each | each negated].
  399. #(11 38 3 -2 10) collect: [:each | each odd].
  400. #(11 38 3 -2 10) select: [:each | each odd].
  401. #(11 38 3 -2 10) select: [:each | each > 10].
  402. #(11 38 3 -2 10) reject: [:each | each > 10].
  403. #(11 38 3 -2 10)
  404. do: [:each | Transcript show: each printString]
  405. separatedBy: [Transcript show: ''.''].
  406. (Smalltalk current classes select: [:eachClass | eachClass name = ''ProfStef'']) do: [:eachProfstef | eachProfstef next].'
  407. !
  408. loops
  409. ^ Lesson
  410. title: 'Loops'
  411. contents:
  412. '"Loops are high-level collection iterators, implemented as regular methods."
  413. "Basic loops:
  414. to:do:
  415. to:by:do"
  416. 1 to: 100 do:
  417. [:i | Transcript show: i asString; cr ].
  418. 1 to: 100 by: 3 do: [:i | Transcript show: i asString; cr].
  419. 100 to: 0 by: -2 do:
  420. [:i | Transcript show: i asString; cr].
  421. 1 to: 1 do: [:i | ProfStef next].'
  422. !
  423. mathematicalPrecedence
  424. ^ Lesson
  425. title: 'Mathematical precedence'
  426. contents:
  427. '"Traditional precedence rules from mathematics do not follow in Smalltalk."
  428. 2 * 10 + 2.
  429. "Here the message * is sent to 2, which answers 20, then 20 receive the message +
  430. Remember that all messages always follow a simple left-to-right precedence rule, * without exceptions *."
  431. 2 + 2 * 10.
  432. 2 + (2 * 10).
  433. 8 - 5 / 2.
  434. (8 - 5) / 2.
  435. 8 - (5 / 2).
  436. ProfStef next.'
  437. !
  438. messageSyntaxBinary
  439. ^ Lesson
  440. title: 'Message syntax: Binary messages'
  441. contents:
  442. '"Binary messages have the following form:
  443. anObject + anotherObject"
  444. 3 * 2.
  445. Date today year = 2011.
  446. false | false.
  447. true & true.
  448. true & false.
  449. 10 @ 100.
  450. 10 <= 12.
  451. ''ab'', ''cd''.
  452. ProfStef next.'
  453. !
  454. messageSyntaxCascade
  455. ^ Lesson
  456. title: 'Message syntax: Cascade'
  457. contents:
  458. '"; is the cascade operator. It''s useful to send message to the SAME receiver
  459. Open a Transcript (console):"
  460. Transcript open.
  461. "Then:"
  462. Transcript show: ''hello''.
  463. Transcript show: ''Smalltalk''.
  464. Transcript cr.
  465. "is equivalent to:"
  466. Transcript
  467. show: ''hello'';
  468. show: ''Smalltalk'' ;
  469. cr.
  470. "You can close the development tools by clicking on the red circle with a cross at the bottom left of the website.
  471. Try to go to the next lesson with a cascade of two ''next'' messages:"
  472. ProfStef'.
  473. !
  474. messageSyntaxCascadeShouldNotBeHere
  475. ^ Lesson
  476. title: 'Lost ?'
  477. contents:
  478. '"Hey, you should not be here !!!!
  479. Go back and use a cascade !!"
  480. ProfStef previous.'.
  481. !
  482. messageSyntaxExecutionOrder
  483. ^ Lesson
  484. title: 'Message syntax: Execution order'
  485. contents:
  486. '"Unary messages are executed first, then binary messages and finally keyword messages:
  487. Unary > Binary > Keywords"
  488. 2.5 + 3.8 rounded.
  489. 3 max: 2 + 2.
  490. (0@0) class.
  491. 0@0 x: 100.
  492. (0@0 x: 100) class.
  493. "Between messages of similar precedence, expressions are executed from left to right"
  494. -12345 negated asString reversed.
  495. ProfStef next.'
  496. !
  497. messageSyntaxExecutionOrderParentheses
  498. ^ Lesson
  499. title: 'Message syntax: Parentheses'
  500. contents:
  501. '"Use parentheses to change order of evaluation"
  502. (2.5 + 3.8) rounded.
  503. (3 max: 2) + 2.
  504. (0@0 extent: 100@200) bottomRight.
  505. ProfStef next.'
  506. !
  507. messageSyntaxKeyword
  508. ^ Lesson
  509. title: 'Message syntax: Keyword messages'
  510. contents:
  511. '"Keyword Messages are messages with arguments. They have the following form:
  512. anObject akey: anotherObject akey2: anotherObject2"
  513. ''Web development is a good deal of pain'' copyFrom: 1 to: 30
  514. "The message is copyFrom:to: sent to the String ''Web development is a good deal of pain''"
  515. 1 max: 3.
  516. Array with: ''hello'' with: 2 with: Smalltalk.
  517. "The message is with:with:with: implemented on class Array. Note you can also write"
  518. Array
  519. with: ''Hi there!!''
  520. with: 2
  521. with: Smalltalk.
  522. ProfStef perform: ''next''.'
  523. !
  524. messageSyntaxUnary
  525. ^ Lesson
  526. title: 'Message syntax: Unary messages'
  527. contents:
  528. '"Messages are sent to objects. There are three types of message: Unary, Binary and Keyword.
  529. Unary messages have the following form:
  530. anObject aMessage
  531. You''ve already sent unary messages. For example:"
  532. 1 class.
  533. false not.
  534. Date today.
  535. Number pi.
  536. "And of course: "
  537. ProfStef next.'
  538. !
  539. pharoEnvironment
  540. ^ Lesson
  541. title: 'Pharo environment'
  542. contents:
  543. '"Every Smalltalk system is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.
  544. Every object understands the message ''explore''. As a result, you get an Explorer window that shows details about the object."
  545. Date today explore.
  546. "This shows that the date object consists of a point in time (start) and a duration (one day long)."
  547. ProfStef explore.
  548. "You see, ProfStef class has a lot of objects. Let''s take a look at my code:"
  549. ProfStef browse.
  550. ProfStef next.'
  551. !
  552. printing
  553. ^ Lesson
  554. title: 'Doing VS Printing: Printing'
  555. contents:
  556. '"Now you''re a Do It master !! Let''s talk about printing. It''s a Do It which prints the result next to the expression you''ve selected.
  557. For example, select the text below, and click on ''PrintIt'':"
  558. 1 + 2.
  559. "As with ''DoIt'', there is also a shortcut to execute this command.
  560. Try CTRL-p on the following expressions:"
  561. Date today.
  562. "The result is selected, so you can erase it using the backspace key. Try it !!"
  563. Date today asDateString.
  564. Date today asTimeString.
  565. ProfStef next.'
  566. !
  567. reflection
  568. ^ Lesson
  569. title: 'Reflection'
  570. contents:
  571. '"You can inspect and change the system at runtime.
  572. Take a look at the source code of the method #and: of the class Boolean:"
  573. (Boolean methodDictionary at: ''and:'') source.
  574. "Or all the methods it sends:"
  575. (Boolean methodDictionary at: ''and:'') messageSends.
  576. "Here''s all the methods I implement:"
  577. ProfStef methodDictionary.
  578. "Let''s create a new method to go to the next lesson:"
  579. |newMethod|
  580. newMethod := Compiler new load: ''goToNextLesson ProfStef next.'' forClass: ProfStef.
  581. ProfStef class addCompiledMethod: newMethod
  582. "Wow!! I can''t wait to use my new method!!"
  583. ProfStef goToNextLesson.'
  584. !
  585. reflectionContinued
  586. ^ Lesson
  587. title: 'Reflection continued'
  588. contents:
  589. '"So cool, isn''t it ? Before going further, let''s remove this method:"
  590. ProfStef class methodAt: #goToNextLesson.
  591. ProfStef class removeCompiledMethod: (ProfStef class methodAt: #goToNextLesson).
  592. ProfStef class methodAt: #goToNextLesson.
  593. "Then move forward:"
  594. ProfStef perform:#next'
  595. !
  596. theEnd
  597. ^ Lesson
  598. title: 'Tutorial done !!'
  599. contents:
  600. '"This tutorial is done. Enjoy programming Smalltalk with JTalk.
  601. You can run this tutorial again by evaluating: ProfStef go.
  602. See you soon !!"
  603. '
  604. !
  605. welcome
  606. ^ Lesson
  607. title: 'Welcome'
  608. contents:
  609. ' "Hello!! I''m Professor Stef.
  610. You must want me to help you learn Smalltalk.
  611. So let''s go to the first lesson. Select the text below and click on the ''DoIt'' button"
  612. ProfStef next.'
  613. ! !
  614. Workspace subclass: #ProfStefWorkspace
  615. instanceVariableNames: 'title titleHeader'
  616. category: 'TrySmalltalk'!
  617. !ProfStefWorkspace methodsFor: 'not yet classified'!
  618. contents: aString
  619. self sourceArea val: aString
  620. !
  621. renderTab
  622. div contents: [:html |
  623. title := html h2
  624. id: 'profStefTitle';
  625. with: 'Workspace'.
  626. html div
  627. class: 'jt_box';
  628. with: [self renderBoxOn: html].
  629. html div
  630. class: 'jt_buttons';
  631. with: [self renderButtonsOn: html]]
  632. !
  633. title: aTitle
  634. title contents: [:html |
  635. html h2
  636. id: 'profStefTitle';
  637. with: aTitle ].
  638. ! !