-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWRAP.PAS
214 lines (135 loc) · 3.87 KB
/
WRAP.PAS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
{ WRAP.PAS
Description:
Contains routines for writing things out to screen in a word-wrapped
fashion, and also for writing errors that will not interrupt the flow.
}
unit wrap;
interface
uses Crt, misc;
procedure wrapint(i : integer; terminate : boolean);
procedure wrapout(s : string; terminate : boolean);
procedure wraperr(s : string);
function ReadLine(full_line : boolean) : string_ptr;
procedure cursor_reset;
var
Rows : integer; { number of the row in the current "screenful" }
implementation
const
MAXCOLS = 75; { leave room for punctuation }
SAFETY_MARGIN = 3;
MAXROWS = 24;
REVERSE_VID = 3;
BOLDFACE = 8;
var
cursor : integer;
{ wrap_wait
Description:
The built-in "more" function of Archetype.
}
procedure wrap_wait;
var ch: char;
begin
TextColor(BOLDFACE); TextBackground(REVERSE_VID);
write('Hit any key to continue...');
ch := ReadKey;
write(chr(13));
NormVideo;
ClrScr; { or ClrEol if you don't want the whole screen }
Rows := 0
end;
{ wrapint
Description:
When we want to wrap a number.
}
procedure wrapint(i : integer; terminate : boolean);
var s : string;
begin
str(i, s);
wrapout(s, terminate)
end;
{ wrapout
Description:
Given a string, writes it out to screen, making sure that if it exceeds
the screen columns, it is broken at natural word boundaries (i.e.
white space).
}
procedure wrapout(s : string; terminate : boolean);
var
thisline, maxchars, startnext : integer;
begin
{ 'thisline' starts out as the maximum number of characters that can be
written before a newline; it gets trimmed back to being the number of
characters from the string that are actually written on this line. }
maxchars := MAXCOLS - cursor;
if s[1] in ['.', ',', ':', ';', ')', '-', '"'] then
maxchars := maxchars + SAFETY_MARGIN;
thisline := maxchars;
while thisline < length(s) do begin
while (thisline > 0) and (s[thisline] <> ' ') do
dec(thisline);
{ If we were unable to find a wrapping point then it means one of two
things: a) the string is too long to fit on one line, and must be
split unnaturally; or b) we are near the end of a line and must wrap
the entire string; i.e. print nothing, finish the line and go on. }
if (thisline = 0) and (length(s) > MAXCOLS) then
thisline := maxchars + 1;
writeln(Copy(s, 1, thisline - 1));
inc(Rows);
if Rows >= MAXROWS then wrap_wait;
startnext := thisline;
while s[startnext] = ' ' do inc(startnext);
s := Copy(s, startnext, length(s));
cursor := 1;
thisline := MAXCOLS - cursor
end;
write(s);
inc(cursor, length(s));
if terminate then begin
writeln;
inc(Rows);
if Rows >= MAXROWS then wrap_wait;
cursor := 1
end
end; { wrapout }
{ wraperr
Description:
Used for printing run-time errors. It will print the error message on
a line by itself and pick up the next line at the exact same cursor
position.
}
procedure wraperr(s : string);
var i : integer;
begin
if cursor > 1 then writeln;
writeln(s);
for i := 1 to (cursor - 1) do
write(' ')
end;
{ ReadLine
Description:
Hides the extra stack space necessary for performing a readln() so that
it won't affect eval_expr.
}
function ReadLine(full_line : boolean) : string_ptr;
var
s : string;
begin
if full_line then
readln(s)
else
s := ReadKey;
ReadLine := NewDynStr(s)
end;
{ cursor_reset
Description:
Used for directly resetting the cursor position by means other than
physically wrapping it around.
}
procedure cursor_reset;
begin
cursor := 1
end;
begin
cursor_reset;
Rows := 0
end. { unit wrap }