#!/home/rebelsky/perl/bin/perl

##########NEW SITEWEAVE
#########VERSION 0.1
#########  .10: -updating rules so they are named..
#########        -Shortening Vappend to Vapp
#########         -adding in V's ability to add to variables..
#########         -adding in V's ability to DUMP its VALUE!!!
#########  .05: new: DMZ tag...

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#############   BUG LIST ######################
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

# V= has problems if its --"Y"-- is on 2+ blocks--which would mean
#       it would have to have a DMZ tag, or <TAG> in it...we could code
#       to get past that...
#     Basically, if you want to have HTML in V or Vapp, put some non-
#  <>ed things that you'll replace later...

#BASIC THING FOR Vapp:  Do not use more than 1 Vapp for
#  1 variable, unless you REALLY know what you're doing.

#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

### Jared Seaman             Last Updated: 7/15/99
### A program for processing blocks of text, according to
###   an @rules array. 
### Begun 7/12/99

1;

#################SITEWEAVE
#This is the program that is used for Siteweave a block of code
#It will also be able to redefine what a Block of code is!

#OK, so far there are the following rules implemented:
# RULE STANDARD: X sometext=#* Y
#      where a space means 1+ spaces
#      # (if present) is a number that indicates the priority of the rule
#         (default = 0; default priority is for earlier rules)
#      * (if present) means "do this inside HTML tags, too.
#          (if it is not there, the thing defaults to ONLY OUTSIDE HTML TAGS)
####
#     REPLACE:    X = Y
#               search for X, replace with Y
#     CONTEXT-INSENSITIVE REPLACE:    X CI= Y
#               search for X case-insensitively, replace with Y
#     BOOLEAN REPLACE:    X c0 Y c1 Z
#    Search for X; if case = 0, replace with Y, if case = 1, replace with Z
#  case starts at 0, and every time you find X, case changes after the replace
#     FILE INCLUDE:  X include= Y
#       This will replace the Chunk X with the contents of the file Y.
#
######NEW (VARIABLE-RELATED) RULES:
#        Variables
#      VARIABLE SET:  X V= Z                Implemented: 7/7  Added to 7/15
#               -When you get X"--"Y"--", you set variable Z to value Y
#               -When you get X"++"Y"++", you add Y to value Z!
#               -When you get X, you replace it with the value of Z!!
              #WHAT IF --"Y"-- APPEAR ON 2 DIFFERENT BLOCKS!!
#      VARIABLE APPEND:  X Vapp= Z          Implemented:  7/8
#               When you get X"--"Y"--", you APPEND value Y to variable Z
#      VARIABLE DUMP:  X Vdump= Z       Implemented: 7/7
#               When you get X, you REPLACE it with the value of variable Z
#      NOW OBSOLETE--one can use V= to do it for Vapp.
#
#########NEWER RULES (7/13+)
#
#      DMZ:  X dmz= Y       Implemented:  7/13 
#             When you see X, we start DMZ.  When you see Y, we stop DMZ.
#             DMZ means 'don't apply any rules between these tags.'
#             You must close the DMZ tag for it to take effect. 
#
#######
#     Is this a good idea?
#       X Vlistapp= Z        Implemented:
#               When you get X"--"Y"--", you put the value Y into the next free 
#                cell of the LIST Z; will have problems if Z is not a list...
sub siteweave ()
  {
    #Variables we have access to because they were called locally:
    #   @block_defs (definitions of what a block is)

    #a useful utility
    use filereaders;

    my $find;
    my $replace;
    my $replace_in;
    my $replace_out;
    my $block = $_[0]; #This is the blok we're editing now
    #this lets us know we're in HTML, so only rules
    #that explicitly state they should work in HTML work.
    my $inHTML = $_[1];
    my $inHTMLok; #returns true if this rule should be applied in HTML
    my $numb_of_rules = @rules;
    my $i; #throwaway variables
    
    for ($i = 0; $i <= $numb_of_rules; $i++)

      {
        #%%%%%%%%%%%%%%%%%%%%%%%%%%
        #VARIABLES-related rules  
        #VARIABLE (generic)   Working again, 7/12, updated 7/15
        # X V= Z            
        # -When you get X followed by "--"Y"--", you set variable Z to value Y
        # -When you get X"++"Y"++", you add Y to value Z!
        # -When you get X, you replace it with the value of Z!!
        if ($rules[$i] =~ /(.*?)\s+V=(-|)(\d*?)(\*?)\s+(.*)/)
          {#here we apply VARIABLE rule it to ALL the blok
            $find = $1;
            $inHTMLok = $4;
            $replace_out = $5; #here, the variable we're writing TO
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we apply the rule.
            if ( (!$inHTML) || ($inHTMLok) )
              {
                #but only write once; if it appears more than once, it will only
                #keep the value of the last time we try to set this variable, for
                #obvious reasons...                
                #If we found the variable, do this stuff...
                #While we can do ANY of these things, you keep going..
                my $j,$k,$l;
                $j = 1;
                while ($j)
                  {#while-loop for processing the variable.
                    #If we don't reset $j, we don't have any $finds left, so we're done
                    $j = 0;
                    #OK, this is a necessary evil.  It says "Take the first $find, &
                    #  if it is a --Y--, record Y, if it is a ++Y++, record Y, if it is neither,
                    #  don't record anything...but we Will reprint $find, so we can 
                    #  replace it's first occurence with its variable if you dump it.
                    if ($block =~ s/$find(?:--(.*?)--|\+\+(.*?)\+\+|)/$find/)
                      {#If we matched at all, it means $find did appear; reset $j.
                        $j = 1;
                        $k = $1;
                        $l = $2;
                        #if $1, then we've matched that pattern, it is a V set..
                        if ($k) 
                          {
                            $replace_in = $k;
                            $var{$replace_out} = $replace_in;
                            #cut out the $find we've been dealing with
                            $block =~ s/$find//;
                            next;
                          }
                        #if $2, it means 'increment'
                        if ($l)
                          {
                            $replace_in = $l;
                            $var{$replace_out} = $var{$replace_out}+$replace_in;
                            #cut out the $find we've been dealing with
                            $block =~ s/$find//;
                            next;
                          }
                        #if neither, it means 'dump'
                        #cut out the $find we've been dealing with
                        $block =~ s/$find/$var{$replace_out}/;
                        next;
                      }
                    
                  }#close while-loop for processing variable.
              }#close in HTML-checking
            next;
          }#VARIABLE (generic) rule closed
        #######################

        #                          working again  7/12
        #VARIABLE APPEND
        # X Vapp= Z      
        # When you get X, it should be followed by "--"Y"--".
        # you set variable Z to value Y
        if ($rules[$i] =~ /(.*?)\s+Vapp=(-|)(\d*?)(\*?)\s+(.*)/)
          {#here we apply it to ALL the block
            $find = $1;
            $inHTMLok = $4;
            $replace_out = $5;
            #here, the variable we're writing TO
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we apply the rule.
            if ( (!$inHTML) || ($inHTMLok) )
              {
                #If we found the X, append its value.
                while ($block =~ s/$find--(.*?)--//)
                  {
                    $replace_in = $1;
                    $var{$replace_out} = $var{$replace_out}.$replace_in;
                  }
              }#close in HTML-checking
            next;
          }#VARIABLE APPEND rule closed
     
        #######################
        #VARIABLE DUMP  Working again 7/12
        # X Vdump= Z            
        # When you get X, you write out the value of the variable Z
        if ($rules[$i] =~ /(.*?)\s+Vdump=(-|)(\d*?)(\*?)\s+(.*)/)
          {
            #here we apply it to ALL the block
            $find = $1;
            $inHTMLok = $4;
            $replace_out = $5; #here, the variable we're reading from
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we apply the rule.
            if ( (!$inHTML) || ($inHTMLok) )
              {
                #let's read the value of the Variable:
                $replace_out = $var{$replace_out};
                $block =~ s/$find/$replace_out/ig; #we replace the value globally
              }#close in HTML-checking
            next;
          }#VARIABLE DUMP rule closed
        
        #RULE 3   Working again 7/12
        #this is a simple boolean-context rule
        if ($rules[$i] =~ /(.*?)\s+c0(-|)(\d*?)(\*?)\s+(.*?)\s*c1\s+(.*)/)
          {#format: stuff out-of-context = thing1 in-context = thing2
            $find = $1;
            $inHTMLok = $4;
            $replace_out = $5;
            $replace_in = $6;
            #If we're not in HTML, or we are in HTML & that's ok, process:
            if ( (!$inHTML) || ($inHTMLok) )
              {
                while ($block)
                  {#process the line
                    if ($context[$i]) #this means you're IN context..
                      {if ($block =~ s/$find/$replace_in/)
                         {#if we found the tag in there..
                           $context[$i] = 0; #now we're OUT of context..
                           next;
                         }
                     }
                    if (!$context[$i]) #this means you're OUT of context...
                      {if ($block =~ s/$find/$replace_out/)
                         {#if we found the tag in there..
                           $context[$i] = 1; #now we're IN context
                           next;
                         }
                     }
                    last;
                  }#close while loop
              }#close ok-circomstances to apply rules
            next;
          }#closes format-context-based
        
        #RULE 4         working again 7/12
        #this should include the contents of a file when it matches.
        if ($rules[$i] =~ /(.*?)\s+include=(-|)(\d*?)(\*?)\s+(.*)/)
          {#rule 4
            $find = $1;
            $inHTMLok = $4;
            $replace = $5;
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we apply the rule.
            if ( (!$inHTML) || ($inHTMLok) )
              {
                #if we haven't read in the data from that file yet...
                if (!$context[$i])
                  {#we read it in now...thus it is only read in once, & only if needed..
                    #we read in all of that file into the $context entry for this #
                    $context[$i] = &read_in_file($replace);
                  }#close read-in-the-file-contents
                $block =~ s/$find/$context[$i]/g;
              } #close HTML-appropriateness of applying rule
            #otherwise, don't apply the rule.
            next;
          }#close rule 4

        #RULE 2    Working again 7/12
        #If we have a simple 'this CI= that' rule, find & apply it,
        #case-insensitively:
        if ($rules[$i] =~ /(.*?)\s+CI=(-|)(\d*?)(\*?)\s+(.*)/)
          {#here we apply it to ALL the block
            $find = $1;
            $inHTMLok = $4;
            $replace = $5;
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we apply the rule.
            if ( (!$inHTML) || ($inHTMLok) )
              {
                $block =~ s/$find/$replace/ig;
              }#close in HTML-checking
            next;
          }#this I= that rule closed

        #RULE 1   Working again 7/12
        #If we have a simple 'this = that' rule, find & apply it:
        if ($rules[$i] =~ /(.*?)\s+=(-|)(\d*?)(\*?)\s+(.*)/)
          {#here we apply it to ALL the block
            $find = $1;
            $inHTMLok = $4;
            $replace = $5;
            #if we're Not in HTML, or we ARE in HTML & we want to apply the rule
            #to HTML, we go.
            if ( (!$inHTML) || ($inHTMLok) )
              {$block =~ s/$find/$replace/g;}
            next;
          }#this = that rule closed

      }#close for-go-through-rules loop
    #returned the processed block of code;
    return $block;
  }



   
# This is a subroutine to check if all open tags are closed in the correct
# order, and if they are not, to close them.
sub action ()
  {
    # Define two variables that are going to be used only in action
    my $currenttag= "";
    my $closedtags= "";
    # Grab the first argument
    my $op = shift;
    # This is a regular expression search to find an open tag
    if ( $op =~ /(.*?<)([^(\/|"!")].*?\b)(.*?>.*?)/)
      {
        # If an open tag is founf it is pushed onto a stack called @tags
        push @tags,$2;
        # The string $op is returned unchanged
        return $op;
      }
    # This is a regular expression search to find a close tag
    if ( $op =~ /(.*?<\/)(.*?)(>.*?)/)
      {
        # Define a variable that will be used only here
        my $tag = $2;
        # Pop the top of the stack and assign the value to the variable $currenttag 
        $currenttag = pop @tags;
        # The following process is run as long as the top of 
        # the stack does not have tbe same value as the close tag found
        while ( !($currenttag eq $tag))
          {
            
            # Append $closedtags with the close tags generated
            $closedtags = $closedtags."</".$currenttag.">";
            # Pop the stack again and assign the values of $currenttag to it
            $currenttag = pop @tags;
          }
        # Append the value of $closedtags to $op
        $op = $closedtags.$op;
        # return the valus of $op
        return $op;
      }
    # if the block is not a tag of any sort then we return $op unchanged
    return $op;
  }#close siteweave
      

