home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_GEN
/
INTER40D.ZIP
/
INTWHLP1.ZIP
/
INTWHLP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-02-16
|
20KB
|
697 lines
(*
Interrupt List -> WinHelp converter V1.01 (c) 1994 by Christian Müller-Planitz
-----------------------------------------------------------------------------
Author: cmuelle@eos.ncsu.edu, cmueller@techfak.uni-bielefeld.de
The source and the compiled EXE-file can be freely distributed as long as
no changes are made without my knowledge.
--------------------------------
Notes:
The program was tested with INTLIST38 and INTLIST39 and its output
was successfully compiled with the MS-Help-compiler "HC31.EXE" V3.10.445.
The program needs the file "INTWHLP.DAT" in the 'source' directory.
The program converted all sourcefiles (INTERRUP.* and *.LST) to
13 RTF files which needed 11MB on my harddrive.
Compiling the RTF-files without compression took 13 minutes in
a DOS-Window under Win/NT on a 486-50 (if you run it under DOS
and if you have a fast hardrive cache, it might be faster).
The (uncompressed) compiled HLP-File was approximately 7MB large.
If you want to create a compressed HLP-file, you have to exchange the
comments in the generated help-project file ("RB.HPJ"). Compressing
reduces the size of the HLP-file to 3MB but it takes
*more* (?? 28MB ??) space on your harddrive while compiling.
In order to speed up compiling the compressed file, I've included a
temporary file ("RB.PH") of the helpcompiler in this archive.
Copy this file into the directory containing all the RTF files
before starting the compiler. This file is specific for INTERLIST39, so
if you want to get maximal compression in future versions, remove it.
After the compilation finishes, you will find the file "RB.HLP".
Start Windows, create an icon in the program manager and double-click on it.
--------------------------------
If you find this program usefull, if it does not work or if you have ideas
how to expand its functionality, feel fee to write an e-mail to me.
As usual, I do not take any responsibility for possible damages done by
this program.
Two questions and their answers :
---------------------------------
WHY is the HLP-file so large ?
In contrast to other programs that convert the interrupt list to
DOS-based hypertext systems, this program generates a large
index file that allows you to search for keywords.
WHY did I wrote this program in Pascal and not in C ?
I think Pascal is a pretty nice language for small projects.
Another reason is the availability of efficient string handling under Pascal.
*)
{$A+,B-,D-,E-,F-,G+,I+,L-,N-,O-,P-,Q-,R-,S-,T-,V+,X+,Y+}
{$DEFINE ProcessIntList}
{$DEFINE ProcessPorts}
{$DEFINE ProcessMemory}
{$DEFINE ProcessBugs}
{$DEFINE ProcessCMOS}
Program RB2HLP;
CONST InPath : String = 'd:\tmp\';
OutPath : String = 'd:\tmp\out\';
CONST IncludeFile = 'INTWHLP.DAT';
Var OutFileCounter : Word;
IndexFile : Text; { stores *all* section names }
IntFile : Text; { stores one entry per int-number }
SubIntFile : Text; { stores all subfunctions of an int per page }
HPJ : Text; { hlep compiler project file }
TopicNo : Word;
LastSection : String; { stores number of last processed int }
IntTopicStr : String; { stores handle to page with subfunctions of the int's}
Const InvalidClassification = '-';
procedure CreateHPJ;
begin
assign(HPJ, OutPath + 'RB.HPJ');
rewrite(HPJ);
writeln(HPJ, '[OPTIONS]'#10'CONTENTS=CONTENTS'#10'COMPRESS=NO'#10';COMPRESS=YES'#10);
writeln(HPJ, '[CONFIG]'#10'BrowseButtons()'#10);
writeln(HPJ, '[FILES]'#10'index.rtf');
{$IFDEF ProcessIntList}
writeln(HPJ, 'int.rtf'#10'subint.rtf');
{$ENDIF}
end;
Procedure NewHlpPage(VAR F : Text; S, ID : String; Classification : Char);
VAR q : Word;
BrowseID : STring;
Procedure FootNote(Note: Char; ID : String);
begin
writeln(F, '{\up6 ',Note,'{\footnote \pard\plain \s2\f0\fs20\cf0\qj\lotusoutlinelevel0');
writeln(F, '{\up6 ',Note,'}{\field{\*\fldinst SYMBOL 16 \\f "" \\s 10 \\h}}', ID, '}}');
end;
Procedure StoreKeyWords(SS: String);
VAR p : Word;
begin
repeat
p := POS(' - ', ss);
if p <> 0 then
begin
ss[p+1] := ' ';
ss[p+2] := ';';
end;
until p=0;
FootNote('K', SS);
end;
begin
BrowseID := ID;
while Length(BrowseID) < 6 do
insert('0', BrowseID, 1);
write(F, '\page ');
FootNote('#', ID);
FootNote('$', S);
FootNote('+', BrowseID);
if (Classification = InvalidClassification)
then StoreKeyWords(s)
else StoreKeyWords(Classification + ';' + s);
writeln(F, '\pard\plain \s3\f0\fs28\cf1\b\sb144\sa72\lotusoutlinelevel1\keep\keepn {\up6 ', S, '}');
writeln(F, '\par \pard\plain \s4\f1\fs20\cf1\lotusoutlinelevel0 \tx855\tx1710\tx2565\tx3420\tx4275' +
'\tx5130\tx5985\tx6840\tx7695');
end;
Procedure Out(VAR F: Text; S : String);
begin
write(F, S);
end;
{Note: The table is not complete. But for it is sufficient for this purpose * }
Function OEMtoANSI(q: Byte) : Byte;
Const Tab : Array[0..127] of Byte =
( 199,252,233,226,228,224,225,231,234,235,232,239,238,236,196,197,
201,230,198,244,246,242,251,249,253,214,220,162,163,165,182,131,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128);
begin
if q < 128
then OEMtoANSI := q
else OEMtoANSI := Tab[q-128];
end;
Function HEX(b:byte):string;
Const h : array [0..15] of char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
begin
Hex := h[b shr 4]+h[b and 15];
end;
Procedure ReadLine(VAR F: Text; VAR S: String);
VAR q: Word;
c: Byte;
begin
readln(F, S);
q:= 1;
while q <= Length(s) do { duplicate all '\' }
begin
if s[q] = '\' then
begin
insert('\', s, q);
Inc(q);
end;
Inc(q);
end;
q:= 1;
while q <= Length(s) do
begin
c := ord(s[q]);
if c = 9 then
begin
s[q] := '\';
insert('tab ', s, q+1);
Inc(q, 4);
end;
if c >= 128 then { escape all 'Umlaute' }
begin
insert(#39+HEX( OEMtoANSI(ord(s[q])) ), s, q+1);
s[q] := '\';
Inc(q,2);
end;
Inc(q);
end;
end;
Procedure OutLN(VAR F: Text; S : String);
begin
write(F, '\par ');
Out(F, S);
writeln(F);
end;
Procedure AddTopic(VAR F: Text; S, ID : String);
begin
write(F, '\par {\uldb ');
Out(F, s);
write(F, '}{\v ');
Out(F, ID);
writeln(F, '}');
end;
Procedure CopyHeader(VAR F: Text);
VAR F3 : Text;
c : Char;
begin
{$I-}
assign(F3, InPath + 'INTWHLP.DAT');
reset(F3);
{$I+}
if IOResult <> 0 then
begin
writeln('Error opening ', InPath + IncludeFile);
HALT;
end;
{ this is certainly slow, but simple }
while not EOF(F3) do
begin
read(F3, c);
write(F, c);
end;
close(F3);
end;
Procedure OpenRTF(VAR F: Text; Name: String);
begin
{$I-}
assign(F, OutPath + Name);
rewrite(F);
{$I+}
if IOResult <> 0 then
begin
writeln('Error craeting ', InPath + Name);
HALT;
end;
CopyHeader(F);
end;
Procedure CloseRTF(VAR F: Text);
begin
writeln(F, '}');
close(F);
end;
Procedure OpenOutFile(VAR FData: Text);
VAR Name : String;
begin
STR(OutFileCounter, Name);
Name := 'RB' + Name + '.RTF';
OpenRTF(FData, Name);
writeln(HPJ, Name);
Inc(OutFileCounter);
end;
Procedure CheckKeyWords(VAR s : STring);
CONST KeyWords = 9;
CONST Keys : Array[1..KeyWords] of String[10] = ('Desc:', 'Notes:', 'Note:', 'Warning:', 'Index:', 'SeeAlso:',
'Return:', 'BUG:', 'Program:');
CONST IStr = '\par {\b ';
VAR q,p : Word;
begin
for q:= 1 to KeyWords do
begin
p := POS(Keys[q], S);
if p <> 0 then
begin
insert(IStr, S, p);
insert('}', S, p+Length(Keys[q]) + Length(IStr));
end;
end;
end;
{this function has to be changed or expanded if new flags are added by R.Brown }
{reading in the flags would be neat }
Function GetSpecialNote(Note : Char) : String;
VAR s: STring;
begin
case Note of
'U' : s:= 'undocumented function ';
'u' : s:= 'partially documented function ';
'P' : s:= 'available only in protected mode ';
'R' : s:= 'available only in real or V86 mode ';
'C' : s:= 'callout or callback (usually hooked rather than called) ';
'O' : s:= 'obsolete (no longer present in current versions) ';
else s:= '<unknown note in header> ';
end;
GetSpecialNote := s;
end;
Function ProcessIntList(FName : String) : Boolean;
LABEL STOP;
VAR s : String;
q : Word;
NewSection : Boolean;
SS : String;
Section : String;
SubFunc : String;
TopicStr : String;
SpecialNote : String;
Title : String;
Classification : Char;
F1, F2 : Text;
begin
{$I-}
assign(F1, InPath + FName);
reset(F1);
{$I+}
if IOResult <> 0 then
begin
ProcessIntList := FALSE;
EXIT;
end;
writeln('Processing : ', InPath + FName);
OpenOutFile(F2);
readLine(F1, s); { ignore copyright in 1st two lines }
readLine(F1, s);
SpecialNote := '';
while not(EOF(F1)) do
begin
readLine(F1, s);
NewSection := (s[1]= '-') and (Pos('--------', s) <> 0);
if NewSection then
begin
if IntTopicStr <> '' then
begin
AddTopic(F2, 'INT ' + Section, IntTopicStr);
end;
Inc(TopicNo);
str(TopicNo, TopicStr);
Section := copy(s, 11, 2);
SubFunc := copy(s, 13, 2);
Classification := s[9];
if Classification = '!' then
begin
s := copy(s, 13, 255);
q:=0;
while (s[q] <> '-') and (q < Length(s)) do
Inc(q);
s[0] := chr(q-1); { remove '-' chars at the end }
if s = '' then s:= 'Note'; { shit ! }
if EOF(F1) then { last line of document ?}
goto STOP;
end
else
begin
readLine(F1, s);
while (s[8] <> '-') do { special flags in titel-line ? }
begin
if s[8] <> ' ' then
SpecialNote := SpecialNote + GetSpecialNote(s[8]);
delete(s, 8, 1);
end;
Insert(subFunc+' ', S, 8);
end;
if LastSection <> Section then
begin
IntTopicStr := 'S' + TopicStr;
if LastSection = ''
then begin
AddTopic(IntFile, 'Notes', IntTopicStr)
end
else AddTopic(IntFile, s, IntTopicStr);
NewHlpPage(SubIntFile, s, IntTopicStr, InvalidClassification);
LastSection := Section;
end;
NewHlpPage(F2, s, TopicStr, Classification);
if SpecialNote <> '' then
begin
OutLN(F2, '\par {\f1\fs20\cf0 '+ SpecialNote + '}');
SpecialNote := '';
end;
OutLN(F2, '\par {\f1\fs20\cf0 Categorie : '+ Classification + '}');
OutLN(F2, '\par {\b Inp.:}');
AddTopic(IndexFile, s, TopicStr);
AddTopic(SubIntFile, s, TopicStr);
end
else { no new section }
begin
CheckKeyWords(s);
OutLN(F2, s);
end;
end;
STOP:
close(F1);
closeRTF(F2);
ProcessIntList := TRUE;
end;
Procedure NewPage(VAR F: Text; Title : String);
VAR TopicStr : String;
begin
Inc(TopicNo);
str(TopicNo, TopicStr);
AddTopic(IndexFile, Title, TopicStr);
NewHlpPage(F, Title, TopicStr, InvalidClassification);
end;
Procedure ProcessPorts(FName : String);
LABEL STOP;
VAR s : String;
TopicStr : String;
NewSection : Boolean;
F1, F2 : Text;
begin
{$I-}
assign(F1, InPath + FName);
reset(F1);
{$I+}
if IOResult <> 0 then
begin
writeln('Unable to open ', InPath + FName);
EXIT;
end;
writeln('Processing : ', InPath + FName);
OpenOutFile(F2);
NewPage(F2, 'Port : Note');
while not(EOF(F1)) do
begin
readLine(F1, s);
NewSection := (s[1]= '-') and (Pos('---------', s) <> 0);
if NewSection then
begin
{Changed!} readLine(F1, s);
if EOF(F1) then { last line of document ?}
goto STOP;
if s <> '' then { why does this happend }
NewPage(F2, s);
end
else
begin
CheckKeyWords(s);
OutLN(F2, s);
end;
end;
STOP:
close(F1);
closeRTF(F2);
end;
Procedure ProcessFile(FName : String; Title : String);
VAR s : String;
F1, F2 : Text;
begin
{$I-}
assign(F1, InPath + FName);
reset(F1);
{$I+}
if IOResult <> 0 then
begin
writeln('Unable to open ', InPath + FName);
EXIT;
end;
writeln('Processing : ', InPath + FName);
while not(EOF(F1)) do
begin
readLine(F1, s);
OutLN(IndexFile, s);
end;
close(F1);
end;
Procedure Credits;
begin
OutLn(IndexFile, '\par');
AddTopic(IndexFile, 'Credits', 'IDCredit');
NewHlpPage(IndexFile, 'Credits', 'IdCredit', InvalidClassification);
OutLN(IndexFile, '\par Interrupt List (c) by R.Brown \par');
OutLn(IndexFile, '\par This list was converted from the released ASCII file');
OutLn(IndexFile, '\par to the Windows Help-Format by \par \par' +
'\par {\b Christian M\''FCller-Planitz}');
OutLn(IndexFile, '\par cmuelle@eos.ncsu.edu' +
'\par cmueller@techfak.uni-bielefeld.de');
end;
Procedure Intro;
begin
writeln(#10'Int-WinHelp preprocessor V1.01 (c) 1994 by Christian Müller-Planitz'#10);
writeln('This program converts the Interrupt List written by Ralf Brown');
writeln('to a RTF-Format that is used as an input format by the Microsoft');
writeln('WinHelp compiler.');
writeln('In order to generate a Windows 3.1 helpfile you need the WinHelp compiler');
writeln('"HC31.EXE", which is distributed with almost all Windows compilers and');
writeln('which is also available on many Internet sites and FIDO BBS systems.'#10);
writeln('Please note that you also need a fast computer and a *lot* of free space on');
writeln('your harddrive (18 MB at least).');
writeln('If you want to find out whether you are able to compile a RTF file, I recomend');
writeln('to put only a few source files (e.g. only "INTERRUP.A") in the source directory');
writeln('After this program finishes, you have to invoke the WinHelp compiler with');
writeln('the command "HC31.EXE RB.HPJ".'#10);
writeln('Have fun ! --CMP'#10);
writeln('P.S. If you have problems building the helpfile or if you simply want to write');
writeln(' an e-mail to me, please write to:');
writeln(' "cmuelle@eos.ncsu.edu" or "cmueller@techfak.uni-bielefeld.de"'#10);
end;
VAR ch : Char;
begin
TopicNo := 0;
LastSection := '';
IntTopicStr := '';
OutFileCounter := 0;
Intro;
write('Source directory: ');
readln(InPath);
InPath := InPath + '\';
write('Dest. directory (has to be created in advance) : ');
readln(OutPath);
OutPath := OutPath + '\';
CreateHPJ;
OpenRTF(IndexFile, 'INDEX.RTF');
NewHlpPage(IndexFile, 'Interrupt List Contents', 'CONTENTS', InvalidClassification);
{$IFDEF ProcessIntList}
OpenRTF(IntFile, 'INT.RTF');
OpenRTF(SubIntFile,'SUBINT.RTF');
AddTopic(IndexFile, 'Interrupt Index', 'IdIndex');
AddTopic(IndexFile, 'Interrupt Functions', 'IDInterrupts');
{$ENDIF}
{$IFDEF ProcessPorts}
AddTopic(IndexFile, 'Ports', 'IdPorts');
{$ENDIF}
{$IFDEF ProcessMemory}
AddTopic(IndexFile, 'Memory', 'IdMemory');
{$ENDIF}
{$IFDEF ProcessBugs}
AddTopic(IndexFile, 'CPU', 'IdCPU');
{$ENDIF}
{$IFDEF ProcessCMOS}
AddTopic(IndexFile, 'CMOS', 'IdCMOS');
{$ENDIF}
Credits;
{$IFDEF ProcessIntList}
NewHlpPage(IndexFile, 'Interrupt Index', 'IdIndex', InvalidClassification); { the program adds all following entries }
NewHlpPage(IntFile, 'Interrupts', 'IDInterrupts', InvalidClassification);
ch := 'a';
while ProcessIntList('interrup.'+ch) do
ch := chr (ord(ch)+1);
closeRTF(IntFile);
closeRTF(SubIntFile);
{$ENDIF}
{$IFDEF ProcessPorts}
NewHlpPage(IndexFile, 'Ports', 'IdPorts', InvalidClassification); { the program adds all following entries }
ProcessPorts('ports.lst');
{$ENDIF}
{$IFDEF ProcessMemory}
NewHlpPage(IndexFile, 'Memory', 'IdMemory', InvalidClassification); { the program adds all following entries }
ProcessFile('memory.lst', 'Memory');
{$ENDIF}
{$IFDEF ProcessBugs}
NewHlpPage(IndexFile, 'CPU', 'IdCPU', InvalidClassification); { the program adds all following entries }
ProcessFile('86bugs.lst', 'CPU');
{$ENDIF}
{$IFDEF ProcessCMOS}
NewHlpPage(IndexFile, 'CMOS', 'IdCMOS', InvalidClassification); { the program adds all following entries }
ProcessFile('cmos.lst', 'CMOS');
{$ENDIF}
closeRTF(IndexFile);
close(HPJ);
end.