* macrohlp.kex --- Macro Help: the help utility for KEXX macros. * ============ * Version 1.1 * Last update: 31-01-98 (dd-mm-yy) * (C) 1997 AIAP * Golub M.A. * Russia * Moscow * e-mail: golub@aha.ru * Requires KEDIT for Windows 1.5 * ============================== * Displays the header comments of a macro in the message line(s). * The header comments must start with an asterisk. The first nonblank line, * that does not start with an asterisk terminates the output. * Recommended: /* end of built-in help */ * The file contains three portable procedures: * * MacroHelp, MacroPage and Version * ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~ * * To insert the built-in help into your macro automatically: * JUST HIT "I" WHEN THE POP-UP MENU APPEARS! * ========================================== * To insert the built-in help manually: copy the procedures to the end of your * macro and add a line like these at its beginning: * If Arg(1)='?' Then Do; Call MacroHelp; Exit RC; End * or * If \Arg() Then Do; Call MacroPage; Exit RC; End * To extract the file version from the * Features: * ========= * MacroHelp: --- suppresses the leading blank lines and strips * the leading asterisks. * --- allows an argument, which is used as a command * applied to each help text line instead of MSG. * --- may be interrupted with Ctrl-Break. * MacroPage: --- suppresses the leading blank lines and strips * the leading asterisks. * --- shows the comment text with paging capabilities, * implemented with READV KEY command; * --- MAY NOT be interrupted with Ctrl-Break: * some settings may change, use ESC key instead. * --- allows insertion of the help text into the current file * by calling MacroHelp with 'Command Insert' argument. * --- Uses procedure Version to show the version of the macro * exposes the variable MacroName, containing the * no more that 10-character-long macro name and * 3-character-long version (if longer than the leftmost * part). * Version --- Extracts the file version specified in the head * comments in the form * * Version * here stands for any text you wish. * After CALL VERSION the variable ver is set to * the value. * Note: the built-in help must not be very large. Be laconic! * Make sure the help lines are not too long (no more than 80 columns). /* end of built-in help */ If Version.1()<>'KEDIT/WINDOWS' Then Do 'EMsg KEDIT for WINDOWS 1.5 or later required!' Exit 2000 End Call Version Do Forever * NOTE FOR KENT: MacroPage run after MacroHelp outputs the first page into the * message popup window instead of the message line(s) (BUG?). * 'REFRESH' does not solve the problem, though it should do it * by clearing the old messages. I guess that * * 'PopUp Center /~Macro Help Version' ver':/-/Macro&Page/Macro&Help/&Insert subroutines/-/&Exit/' * If PopUp.1='Macro&Help' Then Call MacroHelp * If PopUp.1='Macro&Page' Then Call MacroPage * If PopUp.1='&Insert subroutines' Then Call MakeKEXX 'PopUp Center /~Macro Help Version' ver':/-/&Help on Macro Help/&Insert Subroutines/-/&Exit/' If PopUp.1='&Help on Macro Help' Then Call MacroPage If PopUp.1='&Insert Subroutines' Then Call MakeKEXX If PopUp.1='&Exit' Then Leave End 'Refresh' Exit MakeKEXX: Procedure Expose RC If FExt.1()<>'KEX' Then Do 'Alert /Only KEX-files supported!/ Title /Invalid File Extension!/ IconExclamation' Return End Say 'Wait a bit...'; 'Refresh' Astart='* The following lines added by Macro Help: *****************' Aend='* The end of the insertion. ********************************' upgrade=0 /* upgrade flag */ 'Point .MacroHelp' 'Range -* *'; 'Tr *'; 'Z 1 *'; 'All' ':0 NoMsg Find MacroHelp:' If RC=0 Then Do /* if already installed */ 'Point ._MacroHelp' ':0 NoMsg Find' Astart; If RC<>0 Then Do; Call Alert; Return; End 'Point ._Astart' ':0 NoMsg Find' Aend; If RC<>0 Then Do; Call Alert; Return; End 'Next'; 'Point ._Aend' ':0 Find MacroPage:'; If RC<>0 Then Do; Call Alert; Return; End 'Point ._MacroPage' ':0 Find Version:' /* the first version had no Version routine */ If RC<>0 Then '*'; 'Point ._Version' * Upgrading: '._MacroHelp'; Call ClearProc '._MacroPage'; Call ClearProc '._Version'; Call ClearProc '._Astart'; 'Del ._Aend' upgrade=1 /* upgraded */ End 'Extract /InputMode' 'Set InputMode Off' restinp='Set InputMode' InputMode.1 'Bottom' nl=SourceLine() line=0 Do i=1 to nl ln=SourceLine(i) If Left(Upper(Word(ln, 1)), 10)<>'MACROHELP:' Then Iterate line=i End If line=0 Then Do 'EMsg MacroHlp is damaged---aborting.'; RC=1000 Call ErrExit restinp End Do i=line to nl ln=SourceLine(i) 'Input' ln; If RC<>0 Then Call ErrExit restinp End * This is a SUPER TRICK!!! (C) 1997 AIAP * Single KEXX line of 5 KEDITW commands works as follows. * KEDIT makes the first dispayed line current automatically. * The current line stands current after "ALL". * So, we suppress all *-comments (maybe with leading spaces), * then suppress the blank lines and /*...*/ commens. * Then we see the first executable line of the KEX-file, * go one line up and we are sure that we are entering * the first lines of the macro! 'All R /^~([\x20]@\*)/'; 'Less Blank'; 'Less >/*>&*/' 'All'; 'Up' 'Input' Astart; If RC<>0 Then Call ErrExit 'Input * DO NOT REMOVE THE COMMENTS! THEY ARE USED FOR UPGRADING! '; If RC<>0 Then Call ErrExit 'Input * Swap or comment one of the following two lines to switch '; If RC<>0 Then Call ErrExit 'Input * to another procedure: '; If RC<>0 Then Call ErrExit 'Input Call Version /* The variable VER gets the version value */'; If RC<>0 Then Call ErrExit 'Input If Arg(1)="?"|\Arg() Then Do; Call MacroPage; Exit RC; End'; If RC<>0 Then Call ErrExit 'Input If Arg(1)="?"|\Arg() Then Do; Call MacroHelp; Exit RC; End'; If RC<>0 Then Call ErrExit 'Input' Aend; ; If RC<>0 Then Call ErrExit restinp 'NoMsg .MacroHelp' If upgrade Then 'Alert /Your built-in help routines were upgraded./ Title /Macro Help:/ IconInformation' Else 'Alert /Your macro has got built-in help routines./ Title /Macro Help:/ IconInformation' Exit RC ClearProc: Procedure * Remove the leading 2 blank line if any (otherwise consecutive * upgrades will add a growing range of blank lines). 'Up' If CurLine.3()='' Then Do 'Up'; If CurLine.3()='' Then 'Del'; Else 'Next' End Else 'Next' 'NoMsg Del R /^(\x20)@Return$/' /* Sole RETURN is an END-OF-ROUTINE */ If RC=0 Then 'Del' /* Kill final RETURN if any */ Else Do 'NoMsg Del R /^(\x20)@:i\:/' /* The following routine if any */ If RC<>0 Then 'Del *' /* delete to the end of file */ End Return Alert: Procedure Expose RC 'NoMsg .MacroHelp' LF='0A'x text='This macro was modified after help routines having been built-in.'LF'Remove help-call lines, MacroHelp, MacroPage and Version if any manually'LF'before running MACROHLP again.' 'Alert /'text'/ Title /Macro Help Warning/ IconInformation' RC=1000 Return ErrExit: R=RC; Arg(1); 'NoMsg .MacroHelp'; 'EMsg Macro Help aborted.'; Exit R MacroHelp: Procedure Expose RC Arg cmd; If cmd='' Then cmd='Msg' nl=SourceLine() flag=1 Do i=1 to nl ln=SourceLine(i) blank?=(ln='') If Left(Strip(ln, 'L'), 1)<>'*' & \blank? Then Leave If flag & blank? Then Iterate cmd SubStr(ln, 2); If RC<>0 Then Return flag=0 End If flag Then Do 'EMsg No built-in help available.'; RC=1000; Return End Return MacroPage: Procedure Expose RC ver MacroName 'Extract /LScreen/MsgLine/InputMode' Parse Upper Source . . MacroName MacroName=Strip(MacroName) MacroName=Left(MacroName, Min(10, Length(MacroName))) Left(ver, 3) ps=LScreen.1-3 If ps<1 Then Do 'EMsg No room to display built-in help.'; RC=1001; Return End * Define the range of the header comments nl=SourceLine(); start_no=0; end_no=0 Do i=1 to nl ln=SourceLine(i) blank?=(ln='') If Left(Strip(ln, 'L'), 1)<>'*' & \blank? Then Leave If start_no=0 Then Do If blank? Then Iterate /* ignore leading blank lines */ start_no=i End end_no=i End If start_no=0 Then Do 'EMsg No built-in help available.'; RC=1000; Return End 'Set MsgLine On 1' LScreen.1 'Overlay' np=(end_no-start_no+ps)%ps /* number of pages */ pg=1 /* current page number */ Do Forever p1=(pg-1)*ps+1 pend=pg*ps p2=Min(end_no, pend) sep=pend-p2+1 Do i=p1 to p2; Say SubStr(SourceLine(i), 2); End Do sep; Say; End Say MacroName 'Page:' pg 'PgUp/PgDn=Paging; Home=Top; End=Bottom; ESC=Quit; F10=Insert' 'ReadV Key' If ReadV.1='ESC' Then Leave If ReadV.1='F10' Then Do 'Set InputMode Off'; 'Point .MacroHelp' Call MacroHelp 'Command Input' 'Set InputMode' InputMode.1; 'Locate .MacroHelp' Leave End If ReadV.1='HOME' Then pg=1 If ReadV.1='END' Then pg=np If ReadV.1='PGUP' Then pg=Max(1, pg-1) If ReadV.1='PGDN' Then pg=Min(np, pg+1) End 'Set MsgLine' MsgLine.1 MsgLine.2 MsgLine.3 MsgLine.4 'Refresh' Return Version: Procedure Expose ver nl=SourceLine() ver='' Do i=1 to nl ln=SourceLine(i) blank?=(ln='') If Left(Strip(ln, 'L'), 1)<>'*' & \blank? Then Leave If blank? Then Iterate Parse Value ln With "*" vers ver . If Upper(Strip(vers))='VERSION' Then Leave End ver=Strip(ver) Return