matpri.red 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. module matpri; % Matrix printing routines.
  2. % Author: Anthony C. Hearn.
  3. % Modified by Arthur C. Norman.
  4. fluid '(!*nat obrkp!* orig!* pline!* posn!* ycoord!* ymax!* ymin!*);
  5. symbolic procedure setmatpri(u,v);
  6. matpri1(cdr v,u);
  7. put('mat,'setprifn,'setmatpri);
  8. symbolic procedure matpri u;
  9. matpri1(cdr u,nil);
  10. symbolic procedure matpri1(u,x);
  11. % Prints a matrix canonical form U with name X.
  12. % Tries to do fancy display if nat flag is on.
  13. begin scalar m,n,r,l,w,e,ll,ok,name,nw,widths,firstflag,toprow,lbar,
  14. rbar,realorig;
  15. if !*fort
  16. then <<m := 1;
  17. if null x then x := "MAT";
  18. for each y in u do
  19. <<n := 1;
  20. for each z in y do
  21. <<assgnpri(z,list list(x,m,n),'only);
  22. n := n+1>>;
  23. m := m+1>>;
  24. return nil>>;
  25. terpri!* t;
  26. if x and !*nat then <<
  27. name := layout!-formula(x, 0, nil);
  28. if name then <<
  29. nw := cdar name + 4;
  30. ok := !*nat >>>>
  31. else <<nw := 0; ok := !*nat>>;
  32. ll := linelength nil - spare!* - orig!* - nw;
  33. m := length car u;
  34. widths := mkvect(1 + m);
  35. for i := 1:m do putv(widths, i, 1);
  36. % Collect sizes for all elements to see if it will fit in
  37. % displayed matrix form.
  38. % We need to compute things wrt a zero orig for the following
  39. % code to work properly.
  40. realorig := orig!*;
  41. orig!* := 0;
  42. if ok then for each y in u do
  43. <<n := 1;
  44. l := nil;
  45. w := 0;
  46. if ok then for each z in y do if ok then <<
  47. e := layout!-formula(z, 0, nil);
  48. if null e then ok := nil
  49. else begin
  50. scalar col;
  51. col := max(getv(widths, n), cdar e);
  52. % this allows for 2 blanks between cols, and also 2 extra chars, one
  53. % for the left-bar and one for the right-bar.
  54. if (w := w + col + 2) > ll then ok := nil
  55. else <<
  56. l := e . l;
  57. putv(widths, n, col) >> end;
  58. n := n+1>>;
  59. r := (reverse l) . r >>;
  60. if ok then <<
  61. % Matrix will fit in displayed representation.
  62. % Compute format with respect to 0 posn.
  63. firstflag := toprow := t;
  64. r := for each py on reverse r collect begin
  65. scalar y, ymin, ymax, pos, pl, k, w;
  66. ymin := ymax := 0;
  67. pos := 1; % Since "[" is of length 1.
  68. k := 1;
  69. pl := nil;
  70. y := car py;
  71. for each z in y do <<
  72. w := getv(widths, k);
  73. pl := append(update!-pline(pos+(w-cdar z)/2,0,caar z),
  74. pl); % Centre item in its field
  75. pos := pos + w + 2; % 2 blanks between cols
  76. k := k + 1;
  77. ymin := min(ymin, cadr z);
  78. ymax := max(ymax, cddr z) >>;
  79. k := nil;
  80. if firstflag then firstflag := nil
  81. else ymax := ymax + 1; % One blank line between rows
  82. for h := ymax step -1 until ymin do <<
  83. if toprow then <<
  84. lbar := symbol 'mat!-top!-l;
  85. rbar := symbol 'mat!-top!-r;
  86. toprow := nil >>
  87. else if h = ymin and null cdr py then <<
  88. lbar := symbol 'mat!-low!-l;
  89. rbar := symbol 'mat!-low!-r >>
  90. % else lbar := rbar := symbol 'vbar;
  91. else <<lbar := symbol 'mat!-low!-l;
  92. rbar := symbol 'mat!-low!-r>>;
  93. pl := ((((pos - 2) . (pos - 1)) . h) . rbar) . pl;
  94. k := (((0 . 1) . h) . lbar) . k >>;
  95. return (append(pl, k) . pos) . (ymin . ymax) end;
  96. orig!* := realorig;
  97. w := 0;
  98. for each y in r do w := w + (cddr y - cadr y + 1);
  99. % Total height.
  100. n := w/2; % Height of mid-point.
  101. u := nil;
  102. for each y in r do <<
  103. u := append(update!-pline(0, n - cddr y, caar y), u);
  104. n := n - (cddr y - cadr y + 1) >>;
  105. if x then <<maprin x; oprin 'setq >>;
  106. pline!* := append(update!-pline(posn!*,ycoord!*,u),
  107. pline!*);
  108. ymax!* := max(ycoord!* + w/2, ymax!*);
  109. ymin!* := min(ycoord!* + w/2 - w, ymin!*);
  110. terpri!*(not !*nat)>>
  111. else <<if x then <<maprin x; oprin 'setq>>; matpri2 u>>
  112. end;
  113. symbolic procedure matpri2 u;
  114. begin scalar y;
  115. prin2!* 'mat;
  116. prin2!* "(";
  117. obrkp!* := nil;
  118. y := orig!*;
  119. orig!* := if posn!*<18 then posn!* else orig!*+3;
  120. while u do
  121. <<prin2!* "(";
  122. orig!* := orig!*+1;
  123. inprint('!*comma!*,0,car u);
  124. prin2!* ")";
  125. if cdr u
  126. then <<oprin '!*comma!*; orig!* := orig!*-1;
  127. terpri!* !*nat>>;
  128. u := cdr u>>;
  129. obrkp!* := t;
  130. orig!* := y;
  131. prin2!* ")";
  132. if null !*nat then prin2!* "$";
  133. terpri!* t
  134. end;
  135. endmodule;
  136. end;