program CvtHelp; { Input files: HTML file created from WinHelp .rtf file by saving it in Word's "Web Page, Filtered" format. Also looks for WinHelp .hpj file with same name as HTML input file. Output file: HTML file that can be used with LCL apps that use HelpUtil unit's THelpUtilManager class. Author: Phil Hess. Copyright: Copyright (C) 2007 Phil Hess. All rights reserved. License: Modified LGPL. } uses SysUtils, Classes; const ProgramName = 'CvtHelp'; ProgramVersion = '0.01'; var OldFileName : string; HpjFileName : string; NewFileName : string; OldFileVar : TextFile; HpjFileVar : TextFile; NewFileVar : TextFile; {$IFNDEF FPC} MatchFound : TFilenameCaseMatch; {$ENDIF} MapSection : TStringList; TitleStr : string; CopyrightStr: string; Footnotes : TStringList; InStr : string; FnStr : string; FnPos : Integer; FnRef : string; PrevInStr : string; TopicStr : string; TopicMapped : Boolean; FootIdx : Integer; LinkPos : Integer; UnlinkPos : Integer; begin if ParamCount < 2 then {List program useage?} begin WriteLn(ProgramName, ', version ', ProgramVersion, ' - converts WinHelp/RTF-based HTML file to help HTML file.'); WriteLn('Usage: ', ProgramName, ' infile outfile'); Halt; end; {Get name of HTML file to convert from command line} OldFileName := ParamStr(1); {$IFNDEF FPC} OldFileName := ExpandFileNameCase(OldFileName, MatchFound); {$ELSE} OldFileName := ExpandFileName(OldFileName); {$ENDIF} HpjFileName := ChangeFileExt(OldFileName, '.hpj'); {Get name of HTML file to create from command line} NewFileName := ParamStr(2); {$IFNDEF FPC} NewFileName := ExpandFileNameCase(NewFileName, MatchFound); {$ELSE} NewFileName := ExpandFileName(NewFileName); {$ENDIF} if (OldFileName = NewFileName) or (HpjFileName = NewFileName) then begin WriteLn('Can''t use input file name for output file'); Halt; end; {Open input HTML file} AssignFile(OldFileVar, OldFileName); try Reset(OldFileVar); except on EInOutError do begin WriteLn('Can''t open input file ', OldFileName); Halt; end; end; {Open WinHelp project file} AssignFile(HpjFileVar, HpjFileName); try Reset(HpjFileVar); except on EInOutError do begin WriteLn('Can''t open WinHelp project file ', HpjFileName); Halt; end; end; MapSection := TStringList.Create; while not Eof(HpjFileVar) do begin ReadLn(HpjFileVar, InStr); if CompareText(InStr, '[OPTIONS]') = 0 then begin repeat ReadLn(HpjFileVar, InStr); if CompareText(Copy(InStr, 1, 6), 'TITLE=') = 0 then TitleStr := Copy(InStr, 7, MaxInt) else if CompareText(Copy(InStr, 1, 10), 'COPYRIGHT=') = 0 then CopyrightStr := Copy(InStr, 11, MaxInt); until Copy(InStr, 1, 1) = '['; end else if CompareText(InStr, '[MAP]') = 0 then begin repeat ReadLn(HpjFileVar, InStr); if (InStr <> '') and (Copy(InStr, 1, 1) <> '[') then MapSection.Add(Copy(InStr, 1, Pos(' ', InStr)-1) + '=' + Trim(Copy(InStr, Pos(' ', InStr), MaxInt))); until Eof(HpjFileVar) or (Copy(InStr, 1, 1) = '['); end; end; CloseFile(HpjFileVar); {Create output HTML file} AssignFile(NewFileVar, NewFileName); try Rewrite(NewFileVar); except on EInOutError do begin WriteLn('Can''t create output file ', NewFileName); Halt; end; end; Footnotes := TStringList.Create; {Read through entire file, saving footnote topic references and names} while not Eof(OldFileVar) do begin ReadLn(OldFileVar, InStr); if CompareText(InStr, '

') = 0 then {Found footnotes?} begin while not Eof(OldFileVar) do begin ReadLn(OldFileVar, InStr); if Pos('MsoFootnoteText', InStr) > 0 then {Found a footnote?} begin FnStr := InStr; repeat ReadLn(OldFileVar, InStr); if InStr <> '' then FnStr := FnStr + ' ' + InStr; until InStr = ''; TopicStr := Copy(FnStr, Pos('', FnStr) + 5, MaxInt); TopicStr := Copy(TopicStr, 1, Length(TopicStr)-4); if Pos('_', TopicStr) > 0 then begin FnPos := Pos('name=', FnStr) + 6; FnRef := ''; repeat FnRef := FnRef + FnStr[FnPos]; Inc(FnPos); until FnStr[FnPos] = '"'; Footnotes.Add(FnRef + '=' + TopicStr); end; end; end; end; end; Reset(OldFileVar); {Process input file} while not Eof(OldFileVar) do begin ReadLn(OldFileVar, InStr); if CompareText(Copy(InStr, 1, 7), '') = 0 then {Found title?} begin {Replace with title from .hpj file} WriteLn(NewFileVar, '<title>', TitleStr, ''); {Include AppleTitle line so file can be registered as help book on OS X.} Write(NewFileVar, ''); {Include copyright statement from .hpj file} WriteLn(NewFileVar, ''); end else if Pos('class=Topictitle', InStr) > 0 then {Found a topic?} begin {Get footnote number _ftnXX} FnPos := Pos('#_', InStr) + 1; FnRef := ''; repeat FnRef := FnRef + InStr[FnPos]; Inc(FnPos); until InStr[FnPos] = '"'; {Insert anchor} TopicStr := Footnotes.Values[FnRef]; if TopicStr <> '' then begin TopicMapped := False; if MapSection.Values[TopicStr] <> '' then begin WriteLn(NewFileVar, ''); TopicMapped := True; end; if not TopicMapped then {No mapping in project file for topic?} begin {Just use topic name in anchor} Write(NewFileVar, ''); end; end; Write(NewFileVar, Copy(InStr, 1, 20)); {Save part of 1st topic line} repeat {Skip over rest of topic lines} PrevInStr := InStr; ReadLn(OldFileVar, InStr); until InStr = ''; WriteLn(NewFileVar, Copy(PrevInStr, 36, MaxInt)); {Save part of last topic line} end else if CompareText(InStr, '

') = 0 then {Found footnotes?} begin repeat {Skip over footnotes} ReadLn(OldFileVar, InStr); until CompareText(InStr, '') = 0; WriteLn(NewFileVar, InStr); end else {Found normal line} begin {See if it contains link to topic} LinkPos := Pos('', InStr); if LinkPos > 0 then {Line contains link?} begin PrevInStr := InStr; ReadLn(OldFileVar, InStr); {Get next line too} InStr := PrevInStr + ' ' + InStr; {Combine} for FootIdx := 0 to Footnotes.Count -1 do begin TopicStr := Footnotes.ValueFromIndex[FootIdx]; if Pos(TopicStr, InStr) > 0 then begin UnlinkPos := Pos('', InStr); Write(NewFileVar, Copy(InStr, 1, LinkPos-1), '', Copy(InStr, LinkPos+3, UnlinkPos-LinkPos-3), '', Copy(InStr, UnlinkPos+4, MaxInt)); end; end; end else WriteLn(NewFileVar, InStr); end; end; MapSection.Free; Footnotes.Free; CloseFile(OldFileVar); CloseFile(NewFileVar); end.