/*
$Id: match.the,v 1.7 2020/03/08 23:52:30 mark Exp $
*/
/***********************************************************************/
/* Description: REXX macro to match pairs of keywords                  */
/* Syntax:      match                                                  */
/* Notes:       This macro will mark a line block enclosing all lines  */
/*              that are enclosed by a matching pair of keywords.      */
/*              Keywords can actually be more than 1 word, like        */
/*              'end if' but are specified as 1 word.                  */
/*              Supported keyword pairs are:                           */
/*               #if      - #endif                                     */
/*               begin    - end;                                       */
/*               do       - end                                        */
/*               if       - endif                                      */
/*               loop     - endloop                                    */
/*               \begin{  - \end{                   (added by A. Pool) */
/* Bugs:        Only keywords that START a line are considered for     */
/*              matching and each keyword must be on separate lines.   */
/***********************************************************************/
Trace o
idx = 0
-- Rexx
idx+=1;string.idx='> DO SELECT	END'
idx+=1;string.idx='< END	DO SELECT'
-- HTML
idx+=1;string.idx='> <TABLE <TABLE>	</TABLE>'
idx+=1;string.idx='< </TABLE>	<TABLE <TABLE>'
idx+=1;string.idx='> <TR <TR>	</TR>'
idx+=1;string.idx='< </TR>	<TR <TR>'
idx+=1;string.idx='> <DIV <DIV>	</DIV>'
idx+=1;string.idx='< </DIV>	<DIV <DIV>'
idx+=1;string.idx='> <FORM <FORM>	</FORM>'
idx+=1;string.idx='< </FORM>	<FORM <FORM>'
idx+=1;string.idx='> <TD <TD>	</TD>'
idx+=1;string.idx='< </TD>	<TD <TD>'
idx+=1;string.idx='> <UL <UL>	</UL>'
idx+=1;string.idx='< </UL>	<UL <UL>'
idx+=1;string.idx='> <SELECT <SELECT>	</SELECT>'
idx+=1;string.idx='< </SELECT>	<SELECT <SELECT>'
-- others
idx+=1;string.idx='> #IF	#ENDIF'
idx+=1;string.idx='< #ENDIF	#IF'
idx+=1;string.idx='> BEGIN	END;'
idx+=1;string.idx='< END;	BEGIN'
idx+=1;string.idx='> IF	ENDIF'
idx+=1;string.idx='< ENDIF	IF'
idx+=1;string.idx='> LOOP	ENDLOOP'
idx+=1;string.idx='< ENDLOOP	LOOP'
idx+=1;string.idx='> \BEGIN{	\END{'                      /* added by A. Pool */
idx+=1;string.idx='< \END{	\BEGIN{'                      /* added by A. Pool */
idx+=1;string.idx= '> #ELSE	#ENDIF'
idx+=1;string.idx= '> #IFDEF	#ENDIF'
num_string = idx
tab = '09'x
'EXTRACT /LINE/CURLINE/'/* get the focus line contents and line number */
save_current_line = line.1
keyword = Word( Translate( Space( curline.3 ) ), 1 )
stridx = 0
Do i = 1 To num_string                             /* find a keyword...*/
/*
   source = Word( string.i, 2 )
   If keyword = source | Abbrev( keyword, source) Then
*/
   Parse Var string.i direction source (tab) target
   If Wordpos(keyword, source) \= 0 Then
      Do
        stridx = i
        Leave
      End
End
If stridx = 0 Then                       /* if no keyword found, error */
   Do
     'EMSG Unknown match string:' keyword
     Exit
   End
/*
 * We have a keyword on the current line, look for its pair
 */
'preserve'
num_source = 1
num_target = 0
--direction = Word( string.stridx, 1 )
--source = Word( string.stridx, 2 )
--target = Word( string.stridx, 3 )
Parse Var string.stridx direction source (tab) target
Do Forever                                  /* find matching keyword...*/
   If direction = '>' Then 'N'
   Else 'U'
   If rc \= 0 Then Leave
   'EXTRACT /CURLINE/'
   keyword = Word( Translate( Space( curline.3 ) ), 1 )
   Select
     When Wordpos(keyword, source) \= 0 Then num_source = num_source + 1
     When Wordpos(keyword, target) \= 0 Then num_target = num_target + 1
     Otherwise Nop
   End
/*
   Select
     When keyword = source | Abbrev( keyword, source) Then num_source = num_source + 1
     When keyword = target | Abbrev( keyword, target) Then num_target = num_target + 1
     Otherwise Nop
   End
*/
   If num_source = num_target Then                 /* if match found...*/
      Do
        'reset block'
        'mark line'                             /*...mark a line block */
        ':'||save_current_line
        'mark line'
        'restore'
        Return
      End
End
'EMSG No matching target' target  'found for' source
':'||save_current_line
'restore'
Return
