A paginated file viewer similar to Unix more(1)
developed in Turbo Pascal under CP/M-86.
The code is currently just a stub and it's still being written.
To run the program:
A>view filename.txt
{ Paginated file viewer similar to Unix more(1) } | |
program View; | |
type | |
String12 = string[12]; | |
String255 = string[255]; | |
var | |
FileName : String12; | |
Infile : text; | |
Line : String255; | |
function GetFilename: String12; | |
begin | |
if paramcount <> 1 then | |
writeln('INVALID ARGUMENT') | |
else | |
GetFilename := paramstr(1) | |
end; | |
procedure Open(var Stream: text; Name: String12); | |
begin | |
assign(Stream, Name); | |
reset(Stream) | |
end; | |
procedure PrintStatusLine(Filename: String12); | |
begin | |
write(Filename); | |
write(' - Press Q to exit, any other key for next screen.') | |
end; | |
procedure Wait4Keypress; | |
begin | |
end; | |
procedure ViewFile(var Stream: text); | |
const | |
ScreenWidth = 80; | |
ScreenHeight = 24; | |
type | |
Height = 1..ScreenHeight; | |
StrIndex = 0..255; | |
var | |
Line : String255; | |
LineLength : StrIndex; { Length of current line. } | |
LeftoverText : String255; | |
LeftoverLines : integer; | |
LineNo : 1..ScreenHeight; | |
LinesLeft : 1..ScreenHeight; { Number of lines left until last | |
line on screen. } | |
ScreenLines : 1..ScreenHeight; { How many screen lines the current | |
line spans. } | |
begin | |
{ | |
while not eof | |
if text left over from long line | |
print leftover_text | |
read line | |
screen_lines = how many lines line take when printed on screen | |
lines_left=screen_height - lineno - 1 (1 accounts for status line) | |
if len(line) <= screenwidth & lineno < screenheight - 1 | |
print line(stream, line) | |
lineno = lineno + 1 | |
else | |
(* print long line *) | |
if screen_lines > lines_left | |
string_to_print = substr(line, 1, lines_left * screen_width) | |
print string_to_print | |
lineno = lineno + lines_left | |
leftover_text = substr(line, lines_left * screen_width, len(line)) | |
if lineno = screen height - 1 | |
print status line | |
wait for key press | |
} | |
LineNo := 1; | |
LeftoverText := ''; | |
LeftoverLines := 0; | |
ScreenLines := 1; | |
while not eof(Stream) do | |
begin | |
if length(LeftoverText) > 0 then | |
begin | |
writeln(LeftoverText); | |
LineNo := LineNo + LeftoverLines; | |
LeftoverText := ''; | |
LeftoverLines := 0 | |
end; | |
readln(Stream, Line); | |
LineLength := length(Line); | |
ScreenLines := LineLength div ScreenWidth; | |
if (LineLength mod ScreenWidth) > 0 then | |
ScreenLines := ScreenLines + 1; | |
if (LineLength <= ScreenWidth) and | |
(LineNo < ScreenHeight - 1) then | |
begin | |
writeln(Line); | |
LineNo := LineNo + 1; | |
end; | |
{ -1 accounts for status line that spans 1 screen line. } | |
LinesLeft := ScreenHeight - LineNo - 1; | |
{ Current Line is longer than blank lines left on screen. } | |
if ScreenLines > LinesLeft then | |
begin | |
writeln(copy(Line, 1, LinesLeft * ScreenWidth)); | |
LeftoverText := copy(Line, LinesLeft * ScreenWidth, | |
length(Line) - (LinesLeft * ScreenWidth)); | |
LeftoverLines := ScreenLines - LinesLeft; | |
LineNo := LineNo + LinesLeft | |
end | |
end | |
end; | |
BEGIN | |
FileName := GetFilename; | |
Open(Infile, FileName); | |
ViewFile(Infile); | |
close(Infile); | |
END. |