NANOTEXT.BAK 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. MODULE nanotext;
  2. FROM Storage IMPORT ALLOCATE , DEALLOCATE;
  3. IMPORT Lib,Str,IO,Window,FIO;
  4. TYPE t_ptr_t_element = POINTER TO t_element;
  5. t_element = CLASS
  6. ptr_suivant : t_ptr_t_element;
  7. ptr_precedent : t_ptr_t_element;
  8. PROCEDURE affiche_element () ; VIRTUAL;
  9. BEGIN
  10. (* … impl‚menter par les objets fils *)
  11. END affiche_element;
  12. PROCEDURE detruit_element () ; VIRTUAL;
  13. BEGIN
  14. (* … impl‚menter par les objets fils *)
  15. END detruit_element;
  16. END; (* CLASS t_element *)
  17. TYPE t_liste = CLASS
  18. debut : t_ptr_t_element;
  19. ptr_courant : t_ptr_t_element;
  20. PROCEDURE creer() ;
  21. BEGIN
  22. debut := NIL;
  23. ptr_courant := NIL;
  24. END creer;
  25. PROCEDURE premier () : t_ptr_t_element ;
  26. BEGIN
  27. RETURN debut;
  28. END premier;
  29. PROCEDURE au_debut () ;
  30. (* d‚place le pointeur courant au d‚but de la liste *)
  31. BEGIN
  32. ptr_courant := debut;
  33. END au_debut;
  34. PROCEDURE suivant () : t_ptr_t_element;
  35. BEGIN
  36. RETURN ptr_courant^.ptr_suivant;
  37. END suivant;
  38. PROCEDURE a_la_fin ();
  39. (* d‚place le pointeur courant en queue de liste *)
  40. BEGIN
  41. WHILE suivant() <> NIL DO
  42. ptr_courant := ptr_courant^.ptr_suivant;
  43. END;
  44. END a_la_fin;
  45. PROCEDURE au_suivant ();
  46. (* d‚place le pointeur courant au paragraphe suivant si possible *)
  47. BEGIN
  48. IF suivant() <> NIL THEN
  49. ptr_courant := suivant();
  50. END;
  51. END au_suivant;
  52. PROCEDURE precedent () : t_ptr_t_element;
  53. BEGIN
  54. RETURN ptr_courant^.ptr_precedent;
  55. END precedent;
  56. PROCEDURE au_precedent ();
  57. (* d‚place le pointeur courant au paragraphe precedent si possible *)
  58. BEGIN
  59. IF precedent() <> NIL THEN
  60. ptr_courant := precedent();
  61. END;
  62. END au_precedent;
  63. PROCEDURE dernier ():t_ptr_t_element;
  64. BEGIN
  65. au_debut();
  66. WHILE suivant() <> NIL DO
  67. au_suivant();
  68. END;
  69. RETURN ptr_courant;
  70. END dernier;
  71. PROCEDURE liste_vide():BOOLEAN ;
  72. BEGIN
  73. RETURN debut = NIL;
  74. END liste_vide;
  75. PROCEDURE ajouter ( VAR y : t_element);
  76. VAR l_ptr_element : t_ptr_t_element;
  77. (* on ajoute en fin de liste :
  78. 2 cas : liste vide
  79. : liste non vide
  80. *)
  81. BEGIN
  82. ALLOCATE(l_ptr_element,SIZE(y));
  83. Lib.Move(ADR(y),l_ptr_element,SIZE(y));
  84. IF liste_vide() THEN (* cas du debut de liste vide *)
  85. debut := l_ptr_element;
  86. ptr_courant := l_ptr_element ;
  87. ptr_courant^.ptr_precedent := NIL;
  88. ptr_courant^.ptr_suivant := NIL;
  89. ELSE (* ajout en fin de liste *)
  90. l_ptr_element^.ptr_suivant := NIL;
  91. l_ptr_element^.ptr_precedent := ptr_courant;
  92. ptr_courant^.ptr_suivant := l_ptr_element;
  93. ptr_courant := l_ptr_element;
  94. END;
  95. END ajouter;
  96. PROCEDURE inserer (VAR y : t_element);
  97. (* On insŠre AVANT le pointeur courant !!!!!!!!! *)
  98. (* 2 cas : insertion en d‚but de liste
  99. insertion au milieu de liste
  100. *)
  101. VAR l_ptr_element : t_ptr_t_element;
  102. BEGIN
  103. ALLOCATE(l_ptr_element,SIZE(y));
  104. Lib.Move(ADR(y),l_ptr_element,SIZE(y));
  105. IF ptr_courant^.ptr_precedent = NIL THEN (* cas du d‚but de liste non vide *)
  106. debut := l_ptr_element;
  107. l_ptr_element^.ptr_precedent := NIL;
  108. l_ptr_element^.ptr_suivant := ptr_courant;
  109. ptr_courant^.ptr_precedent := l_ptr_element;
  110. ptr_courant := debut^.ptr_suivant;
  111. ELSE (* cas du milieu de liste *)
  112. ptr_courant^.ptr_precedent^.ptr_suivant := l_ptr_element;
  113. l_ptr_element^.ptr_suivant := ptr_courant;
  114. l_ptr_element^.ptr_precedent := ptr_courant^.ptr_precedent;
  115. ptr_courant^.ptr_precedent := l_ptr_element;
  116. ptr_courant := l_ptr_element^.ptr_suivant;
  117. END; (* IF *)
  118. END inserer;
  119. PROCEDURE inserer_liste ( VAR x : t_liste);
  120. BEGIN
  121. END inserer_liste;
  122. PROCEDURE detruire ();
  123. (* on detruit l'element du pointeur courant *)
  124. VAR l_ptr_element,ll_ptr_element : t_ptr_t_element;
  125. BEGIN
  126. ptr_courant^.detruit_element;
  127. IF ptr_courant^.ptr_precedent = NIL THEN
  128. (* cas du premier element de la liste **)
  129. (* 2 cas : liste compos‚e d'un element
  130. : liste composee de plusieurs elements *)
  131. IF ptr_courant^.ptr_suivant = NIL THEN
  132. DEALLOCATE(ptr_courant,SIZE(ptr_courant^));
  133. debut := NIL;
  134. ptr_courant := NIL;
  135. ELSE
  136. ptr_courant := ptr_courant^.ptr_suivant;
  137. ptr_courant^.ptr_precedent := NIL;
  138. DEALLOCATE(debut,SIZE(debut^));
  139. debut := ptr_courant;
  140. END; (* IF *)
  141. ELSIF ptr_courant^.ptr_suivant = NIL THEN
  142. (* cas d'un ‚l‚ment en fin de liste *)
  143. ptr_courant := ptr_courant^.ptr_precedent;
  144. DEALLOCATE(ptr_courant^.ptr_suivant,SIZE(ptr_courant^.ptr_suivant^));
  145. ptr_courant^.ptr_suivant := NIL;
  146. ELSE
  147. (* cas g‚n‚ral d'un ‚l‚ment au milieu de liste *)
  148. l_ptr_element := ptr_courant^.ptr_suivant;
  149. l_ptr_element^.ptr_precedent := ptr_courant^.ptr_precedent;
  150. ptr_courant^.ptr_precedent^.ptr_suivant := l_ptr_element;
  151. DISPOSE(ptr_courant);
  152. ptr_courant := l_ptr_element;
  153. END ; (* IF *)
  154. END detruire;
  155. END; (* CLASS t_liste *)
  156. TYPE t_ptr_t_paragraphe = POINTER TO t_paragraphe;
  157. t_paragraphe = CLASS (t_element)
  158. longueur : CARDINAL;
  159. ptr_chaine : ADDRESS;
  160. nbre_lignes : CARDINAL;
  161. PROCEDURE initialise_element ( VAR x : ARRAY OF CHAR);VIRTUAL;
  162. BEGIN
  163. longueur := Str.Length(x);
  164. ALLOCATE(ptr_chaine,longueur);
  165. Lib.Move(ADR(x),ptr_chaine,longueur);
  166. END initialise_element;
  167. PROCEDURE affiche_element (); VIRTUAL;
  168. VAR l_tampon : ARRAY[0..1023] OF CHAR;
  169. BEGIN
  170. Lib.Move(ptr_chaine,ADR(l_tampon),longueur);
  171. l_tampon[longueur] := CHR(0);
  172. IO.WrStr(l_tampon);
  173. IO.WrLn;
  174. END affiche_element;
  175. PROCEDURE detruit_element () ; VIRTUAL;
  176. BEGIN
  177. DEALLOCATE(ptr_chaine,SIZE(ptr_chaine^));
  178. END detruit_element;
  179. END; (* CLASS t_paragraphe *)
  180. CONST fin_ligne = CHR(10);
  181. fin_para = CHR(13);
  182. TYPE t_fenetre = Window.WinDef;
  183. t_parametres = RECORD
  184. longueur_page : CARDINAL;
  185. largeur_ligne : CARDINAL;
  186. marge_haute : CARDINAL;
  187. marge_basse : CARDINAL;
  188. marge_droite : CARDINAL;
  189. marge_gauche : CARDINAL;
  190. largeur_tabulation : CARDINAL;
  191. entete : BOOLEAN;
  192. bas_de_page : BOOLEAN;
  193. END;
  194. TYPE t_ptr_t_tampon = POINTER TO t_tampon;
  195. TYPE t_ptr_t_texte = POINTER TO t_texte;
  196. t_texte = CLASS (t_liste)
  197. tampon : t_ptr_t_tampon;
  198. fenetre : Window.WinDef;
  199. parametres : t_parametres;
  200. ptr_fenetre : Window.WinType;
  201. curseurx : CARDINAL;
  202. curseury : CARDINAL;
  203. pos_fen_ds_txt : CARDINAL;
  204. PROCEDURE initialise_texte( VAR x : Window.WinDef;
  205. VAR y : t_parametres);
  206. BEGIN
  207. creer();
  208. fenetre := x;
  209. parametres := y;
  210. ptr_fenetre := Window.Open(fenetre);
  211. END initialise_texte;
  212. PROCEDURE transfert_avant(); VIRTUAL;
  213. BEGIN
  214. END transfert_avant;
  215. PROCEDURE transfert_arriere(); VIRTUAL;
  216. BEGIN
  217. END transfert_arriere;
  218. PROCEDURE page_up(); VIRTUAL;
  219. BEGIN
  220. END page_up;
  221. PROCEDURE page_down(); VIRTUAL;
  222. BEGIN
  223. END page_down;
  224. PROCEDURE affiche_page(); VIRTUAL;
  225. BEGIN
  226. END affiche_page;
  227. END; (* CLASS t_texte *)
  228. (* le tampon est notre zone de travail : c'est dans lui que seront
  229. faites toutes les insertions et destructions , recherches ;
  230. donc le test des touches frapp‚es au clavier vont provoquer
  231. le transfert dans le tampon de notre paragraphe, et toutes les
  232. modifications se feront dans celui-ci; ceci nous procure en
  233. plus une fonction UNDO facile car le texte original n'est pas
  234. modifi‚ tant que le transfert inverse n'est pas r‚alis‚.
  235. Nous pourons sauvegarder toutes nos modifications dans une
  236. liste que nous pourrons ‚diter ou sauvegarder … souhait *)
  237. TYPE (* t_ptr_t_tampon = POINTER TO t_tampon;*)
  238. t_tampon = CLASS (t_paragraphe)
  239. position : CARDINAL;
  240. sauve_ptr_suivant : t_ptr_t_element;
  241. suve_ptr_precedent : t_ptr_t_element;
  242. la_liste : t_ptr_t_texte ; (* adresse de la liste *)
  243. PROCEDURE initialise_element ( VAR x : ARRAY OF CHAR ) ; VIRTUAL ;
  244. BEGIN
  245. (* notre tampon est un paragraphe particulier d'une taille
  246. de 32 Kilo-octets *)
  247. longueur := Str.Length(x);
  248. ALLOCATE(ptr_chaine,32*1024-1);
  249. Lib.Fill(ptr_chaine,32*1024-1,0);
  250. Lib.Move(ADR(x),ptr_chaine,longueur);
  251. END initialise_element;
  252. PROCEDURE init_adresse(VAR x : t_ptr_t_texte );
  253. BEGIN
  254. la_liste := x;
  255. END init_adresse;
  256. PROCEDURE insere ( x : ARRAY OF CHAR );
  257. VAR adresse1,adresse2 : ADDRESS;
  258. BEGIN
  259. adresse1 := Lib.AddAddr(ptr_chaine,position-1);
  260. IF position <= longueur THEN
  261. adresse2 := Lib.AddAddr(adresse1,Str.Length(x));
  262. Lib.Move(adresse1,adresse2,longueur-position+1);
  263. INC(longueur,Str.Length(x));
  264. Lib.Move(ADR(x),adresse1,Str.Length(x));
  265. ELSE
  266. adresse2 := Lib.AddAddr(ptr_chaine,longueur);
  267. Lib.Move(ADR(x),adresse1,Str.Length(x));
  268. Lib.Fill(adresse2,position-longueur-1,020H);
  269. longueur := position + Str.Length(x);
  270. END;
  271. END insere;
  272. PROCEDURE remplace ( x : ARRAY OF CHAR );
  273. VAR adresse : ADDRESS;
  274. BEGIN
  275. adresse := Lib.AddAddr(ptr_chaine,position-1);
  276. Lib.Move(ADR(x),adresse,Str.Length(x));
  277. END remplace;
  278. PROCEDURE detruit ( x : CARDINAL );
  279. VAR adresse1,adresse2 : ADDRESS;
  280. BEGIN
  281. adresse1 := Lib.AddAddr(ptr_chaine,position + x - 1);
  282. adresse2 := Lib.AddAddr(ptr_chaine,position-1);
  283. Lib.Move(adresse1,adresse2,longueur-position);
  284. adresse1 := Lib.AddAddr(ptr_chaine,longueur);
  285. Lib.Fill(adresse1,x,0);
  286. DEC(longueur,x);
  287. END detruit;
  288. PROCEDURE affiche_element(); VIRTUAL ;
  289. (* le texte contenu dans notre paragraphe doit ˆtre justifi‚ *)
  290. (* on pourrait le justifier aprŠs coup, mais je pr‚fŠre une *)
  291. (* justification au fur … mesure *)
  292. TYPE l_ptr_tampon = POINTER TO l_t_tampon;
  293. l_t_tampon = ARRAY[0..32*1024-1] OF CHAR;
  294. VAR
  295. l_chaine : ARRAY[0..255] OF CHAR;
  296. i,j ,k : CARDINAL;
  297. mot : ARRAY[0..255] OF CHAR;
  298. (* chaque mot extrait de notre phrase *)
  299. separateur : ARRAY[0..255] OF CHAR;
  300. (* la chaŒne contenant les s‚parateurs initiaux qu'il faut conserver *)
  301. numero_mot : CARDINAL;
  302. (* le num‚ro du mot trait‚ *)
  303. num_mot_ds_ligne: CARDINAL;
  304. (* le numero du mot trait‚ dans la ligne *)
  305. nombre_blancs : CARDINAL;
  306. (* le nombre de blancs … r‚partie entre les mots *)
  307. longueur_phrase : CARDINAL;
  308. (* la longueur de notre phrase ne contenant que des mots entiers *)
  309. nombre_lignes : CARDINAL;
  310. sauve_position : CARDINAL;
  311. sauve_num_mot : CARDINAL;
  312. car : CHAR;
  313. BEGIN
  314. car := CHR(0);
  315. sauve_position := position;
  316. (* et on justifie le texte !!!!! *)
  317. mot := "";
  318. separateur := "";
  319. l_chaine := "";
  320. numero_mot := 0;
  321. nombre_lignes := 0;
  322. num_mot_ds_ligne := 0;
  323. nombre_blancs := 0;
  324. mot := "";
  325. separateur := "";
  326. l_chaine := "";
  327. longueur_phrase := 0;
  328. num_mot_ds_ligne:= 0;
  329. (* si premier caractŠre est un s‚parateur, il ne faut pas modifier
  330. la valeur de ce s‚parateur ( par exemple : une tabulation)
  331. On traite donc cette premiŠre ligne s‚par‚ment. Les lignes
  332. suivantes seront donc trait‚es toutes comme un premiŠre ligne
  333. ne commen‡ant pas par un s‚parateur.
  334. *)
  335. IF l_ptr_tampon(ptr_chaine)^[0] = CHR(32) THEN
  336. INC(nombre_lignes);
  337. LOOP (* on commence par faire les calculs pour une ligne *)
  338. Str.Item(separateur,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{0C..CHAR(255)}-Str.CHARSET{" "},numero_mot);
  339. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},numero_mot);
  340. IF mot[0] = CHR(0) THEN
  341. EXIT
  342. END;
  343. IF (longueur_phrase + Str.Length(separateur) + Str.Length(mot)) < la_liste^.parametres.largeur_ligne THEN
  344. INC(longueur_phrase ,Str.Length(separateur) + Str.Length(mot));
  345. INC(numero_mot);
  346. INC(num_mot_ds_ligne)
  347. ELSE
  348. EXIT (* on ne peut plus mettre de mots dans la largeur impos‚e*)
  349. END; (* IF longu... *)
  350. END; (* LOOP *)
  351. (* calculs du nombre de blancs … ins‚rer *)
  352. nombre_blancs := la_liste^.parametres.largeur_ligne
  353. - longueur_phrase ;
  354. k :=num_mot_ds_ligne-1;
  355. (* et on construit notre texte justifi‚ *)
  356. Str.Item(separateur,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{0C..CHAR(255)}-Str.CHARSET{" "},0);
  357. Str.Append(l_chaine,separateur);
  358. FOR i := numero_mot - num_mot_ds_ligne TO num_mot_ds_ligne - 2 DO
  359. Str.Item(separateur,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{0C..CHAR(255)}-Str.CHARSET{" "},i+1);
  360. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},i);
  361. Str.Append(l_chaine,mot);
  362. Str.Append(l_chaine,separateur);
  363. IF k >= 1 THEN
  364. FOR j := 1 TO nombre_blancs DIV k DO
  365. Str.Append(l_chaine," ");
  366. END; (* FOR *)
  367. END; (* IF *)
  368. DEC(nombre_blancs, nombre_blancs DIV k);
  369. DEC(k);
  370. END (* FOR *) ;
  371. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},i+1);
  372. Str.Append(l_chaine,mot);
  373. Str.Append(l_chaine,fin_ligne);
  374. position := 1 ;
  375. detruit(longueur_phrase+1);
  376. insere(l_chaine);
  377. INC(longueur_phrase);
  378. (* et on traite les lignes suivantes ********)
  379. LOOP (* et on boucle jusqu'… la fin du paragraphe *)
  380. (* on remet … blanc nos variables de lignes ***)
  381. INC(nombre_lignes);
  382. num_mot_ds_ligne := 0;
  383. nombre_blancs := 0;
  384. mot := "";
  385. separateur := "";
  386. l_chaine := "";
  387. longueur_phrase := 0;
  388. num_mot_ds_ligne:= 0;
  389. sauve_num_mot := numero_mot;
  390. LOOP (*calcul pour une ligne *)
  391. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},numero_mot);
  392. IF mot[0] = CHR(0) THEN
  393. EXIT
  394. END;
  395. Str.Item(separateur,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{0C..CHAR(255)}-Str.CHARSET{" "},numero_mot);
  396. IF (longueur_phrase + Str.Length(separateur) + Str.Length(mot)) < la_liste^.parametres.largeur_ligne THEN
  397. INC(longueur_phrase ,Str.Length(separateur) + Str.Length(mot));
  398. INC(numero_mot);
  399. INC(num_mot_ds_ligne)
  400. ELSE
  401. DEC(longueur_phrase,Str.Length(separateur));
  402. EXIT (* on ne peut plus mettre de mots dans la largeur impos‚e*)
  403. END; (* IF longu... *)
  404. END; (* LOOP *)
  405. (* calculs du nombre de blancs … ins‚rer *)
  406. nombre_blancs := la_liste^.parametres.largeur_ligne
  407. - longueur_phrase;
  408. IF num_mot_ds_ligne <1 THEN
  409. EXIT;
  410. END;
  411. k :=num_mot_ds_ligne-1;
  412. (* et on construit notre texte justifi‚ *)
  413. FOR i := sauve_num_mot TO sauve_num_mot + num_mot_ds_ligne - 2 DO
  414. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},i);
  415. Str.Item(separateur,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{0C..CHAR(255)}-Str.CHARSET{" "},i);
  416. Str.Append(l_chaine,mot);
  417. Str.Append(l_chaine,separateur);
  418. IF k >= 1 THEN
  419. FOR j := 1 TO nombre_blancs DIV k DO
  420. Str.Append(l_chaine," ");
  421. END; (* FOR *)
  422. END; (* IF *)
  423. DEC(nombre_blancs, nombre_blancs DIV k);
  424. DEC(k);
  425. END (* FOR *) ;
  426. Str.Item(mot,l_ptr_tampon(ptr_chaine)^,Str.CHARSET{" "},i+1);
  427. INC(numero_mot);
  428. Str.Append(l_chaine,mot);
  429. Str.Append(l_chaine,fin_ligne);
  430. position := 1 + ((nombre_lignes-1) * (la_liste^.parametres.largeur_ligne) + 1);
  431. detruit(longueur_phrase+1);
  432. insere(l_chaine);
  433. INC(longueur_phrase);
  434. END; (* LOOP pour une ligne *)
  435. END; (* LOOP pour tout le reste du paragraphe *)
  436. position := 1 + ((nombre_lignes-1) * la_liste^.parametres.largeur_ligne) + longueur_phrase;
  437. insere(fin_para);
  438. INC(longueur_phrase);
  439. (* notre texte est maintenant justifi‚ *)
  440. i := 0;
  441. LOOP
  442. Str.Slice(l_chaine,l_ptr_tampon(ptr_chaine)^,i,la_liste^.parametres.largeur_ligne);
  443. (* affichage de la marge *)
  444. IF la_liste^.parametres.marge_gauche >= la_liste^.pos_fen_ds_txt THEN
  445. IO.WrCharRep(" ",la_liste^.parametres.marge_gauche - la_liste^.pos_fen_ds_txt) ;
  446. IO.WrStr(l_chaine);
  447. ELSE
  448. Str.Slice(l_chaine,l_chaine,la_liste^.pos_fen_ds_txt-la_liste^.parametres.marge_gauche,
  449. la_liste^.parametres.largeur_ligne - la_liste^.pos_fen_ds_txt);
  450. IO.WrStr(l_chaine);
  451. END;
  452. IO.WrCharRep(" ",la_liste^.parametres.marge_droite);
  453. IO.WrLn;
  454. IF Str.Length(l_chaine)< la_liste^.parametres.largeur_ligne THEN
  455. EXIT
  456. END;
  457. INC(i,30);
  458. END;
  459. position := sauve_position;
  460. END affiche_element;
  461. END; (* CLASS t_tampon *)
  462. TYPE t_ptr_t_paragraf= POINTER TO t_paragraf;
  463. t_paragraf = CLASS (t_paragraphe)
  464. la_liste : t_ptr_t_texte; (* adresse de la liste *)
  465. PROCEDURE init_adresse(VAR x : t_ptr_t_texte );
  466. BEGIN
  467. la_liste := x;
  468. END init_adresse;
  469. PROCEDURE affiche_element(); VIRTUAL ;
  470. (*le texte contenu dans notre paragraphe est d‚j… justifi‚ *)
  471. TYPE l_ptr_tampon = POINTER TO l_t_tampon;
  472. l_t_tampon = ARRAY[0..32*1024-1] OF CHAR;
  473. VAR l_tampon : l_ptr_tampon;
  474. l_chaine : ARRAY[0..255] OF CHAR;
  475. i,j : CARDINAL;
  476. BEGIN
  477. NEW(l_tampon);
  478. Lib.Move(ptr_chaine,l_tampon,longueur);
  479. l_tampon^[longueur] := CHR(0);
  480. i := 0;
  481. LOOP
  482. Str.Slice(l_chaine,l_tampon^,i,la_liste^.parametres.largeur_ligne);
  483. (* affichage de la marge *)
  484. IF la_liste^.parametres.marge_gauche >= la_liste^.pos_fen_ds_txt THEN
  485. IO.WrCharRep(" ",la_liste^.parametres.marge_gauche - la_liste^.pos_fen_ds_txt) ;
  486. IO.WrStr(l_chaine);
  487. ELSE
  488. Str.Slice(l_chaine,l_chaine,la_liste^.pos_fen_ds_txt-la_liste^.parametres.marge_gauche,
  489. la_liste^.parametres.largeur_ligne - la_liste^.pos_fen_ds_txt);
  490. IO.WrStr(l_chaine);
  491. END;
  492. IO.WrCharRep(" ",la_liste^.parametres.marge_droite);
  493. IO.WrLn;
  494. IF Str.Length(l_chaine)< la_liste^.parametres.largeur_ligne THEN
  495. EXIT
  496. END;
  497. INC(i,30);
  498. END;
  499. DISPOSE(l_tampon);
  500. END affiche_element;
  501. END; (* class t_paragraf *)
  502. PROCEDURE attente;
  503. BEGIN
  504. REPEAT UNTIL IO.KeyPressed();
  505. END attente;
  506. VAR mon_texte : t_texte;
  507. ptr_mon_texte : t_ptr_t_texte;
  508. el : t_paragraf;
  509. a : Window.WinDef;
  510. b : t_parametres;
  511. VAR fichier : FIO.File;
  512. buffer : ARRAY[0..10000] OF CHAR;
  513. car : CHAR;
  514. tt : t_tampon;
  515. PROCEDURE affiche;
  516. VAR g : t_ptr_t_paragraphe;
  517. BEGIN
  518. mon_texte.au_debut();
  519. REPEAT
  520. mon_texte.ptr_courant^.affiche_element();
  521. mon_texte.au_suivant();
  522. UNTIL mon_texte.suivant() = NIL;
  523. mon_texte.ptr_courant^.affiche_element();
  524. END affiche;
  525. PROCEDURE message (x : ARRAY OF CHAR);
  526. BEGIN
  527. Lib.Delay(5000);
  528. Window.Clear;
  529. IO.WrStr(x);
  530. IO.WrLn;
  531. END message;
  532. BEGIN (* principal *)
  533. WITH a DO
  534. X1 := 10;
  535. X2 := 65;
  536. Y1 := 1;
  537. Y2 := 25;
  538. Foreground := Window.Brown;
  539. Background := Window.Blue;
  540. CursorOn := TRUE;
  541. WrapOn := FALSE;
  542. Hidden := FALSE;
  543. FrameOn := TRUE;
  544. FrameDef := Window.DoubleFrame;
  545. FrameFore := Window.Blue;
  546. FrameBack := Window.Brown;
  547. END;
  548. WITH b DO
  549. longueur_page := 60;
  550. largeur_ligne := 40;
  551. marge_haute := 3;
  552. marge_basse := 3;
  553. marge_droite := 15;
  554. marge_gauche := 15;
  555. largeur_tabulation := 8;
  556. entete := TRUE;
  557. bas_de_page := TRUE;
  558. END;
  559. (************** CREATION DE LA LISTE ****************)
  560. mon_texte.initialise_texte(a,b);
  561. mon_texte.pos_fen_ds_txt := 20;
  562. ptr_mon_texte := ADR(mon_texte);
  563. (*
  564. (************** on remplit la liste *****************)
  565. message(" ON REMPLIT LA LISTE ");
  566. fichier := FIO.Open("c:\mii\mod.mod\texte1.MOD");
  567. FIO.EOF := FALSE;
  568. FIO.RdStr(fichier,buffer);
  569. WHILE NOT FIO.EOF DO
  570. el.initialise_element(buffer);
  571. el.init_adresse(ptr_mon_texte);
  572. mon_texte.ajouter(el);
  573. FIO.RdStr(fichier,buffer);
  574. END;
  575. (************ on parcoure la liste en avant **********)
  576. message(" ON parcoure LA LISTE en avant");
  577. affiche;
  578. *)
  579. buffer := " Bonjour messieurs-dames, il fait beau et nous pourrions bien aller bavarder quelque part dans la brousse ou la savane";
  580. tt.initialise_element(buffer);
  581. tt.init_adresse(ptr_mon_texte);
  582. tt.affiche_element();
  583. attente;
  584. message(" Fin du programme");
  585. FIO.Close(fichier);
  586. END nanotext.