// Uncolored, plain source file:  fancy.java
//    fancy.java by Steven R. Brandt
//    <p>
//    An example file explaining how to use
//    com.stevesoft.pat, com.stevesoft.pat.wrap,
//    and com.stevesoft.pat.apps
//    <p>
//    This software comes without express or implied warranty.
//    No claim is made about the suitability of this software for
//    any purpose and neither I nor SteveSoft shall be liable for
//    damages suffered by the user of this software.
import com.stevesoft.pat.*;
import java.util.*;

// Here we define 3 java functions that carry out the function
// of replacing text using a user defined function.  You can
// tell a Regex to use your ReplaceRule simply by writing code
// like this:
//
//    // First define your rule.
//    class myRule extends ReplaceRule {
//      ...
//      public void apply(StringBufferLike sb,RegRes rr) {
//        ...
//      }
//    }
//
//    ...
//    Regex r = ...
//    ...
//    // Now tell a Regex to use it!
//    r.setReplaceRule(new myRule());

// Example Rule 1: Convert to upper case...
// We don't really need to do this because pat
// has a \U ... \E sequence -- see below.
class UpperCaseRule extends ReplaceRule {
    public void apply(StringBufferLike sb,RegRes rr) {
        sb.append(rr.stringMatched().toUpperCase());
    }
}

// Example Rule 2: Number the matches...
class NumberRule extends ReplaceRule {
    int cnt = 1;
    public void apply(StringBufferLike sb,RegRes rr) {
        sb.append("#"+(cnt++));
    }
}

// Example Rule 3: Substitute variables...
// The variables are name value pairs stored in a hastable.
// Whenever the Regex matches on one of the names, this rule
// adds the appropriate value to the StringBuffer.
class VarRule extends ReplaceRule {
    Hashtable h;
    VarRule(Hashtable h) { this.h = h; }
    public void apply(StringBufferLike sb,RegRes rr) {
        Object o=h.get(rr.stringMatched());
        if(o == null)
            sb.append(rr.stringMatched());
        else
            sb.append(o.toString());
    }
    // Needed if we are to clone this rule.  This
    // class is a singly linked list, the super class's
    // method clone() makes sure the whole list is
    // cloned if it just knows how to clone this one
    // extension.
    public Object clone1() { return new VarRule(h); }
}

public class fancy {
    public static void main(String[] unused) {
        String s = null,txt = "$a is a var, $xx, $foo, and $bar are too.";
        // Remember to write \\$ not just $ in this rule!
        Regex r = new Regex("\\$\\w+\\b");

        r.setReplaceRule(new UpperCaseRule());
        // We could've done this same thing by saying
        // r = Regex.perlCode("s/\\$\\w+\\b/\\U$&\\E/");
        s = r.replaceAll(txt);
        System.out.println("result 1 => "+s);

        r.setReplaceRule(new NumberRule());
        s = r.replaceAll(txt);
        System.out.println("result 2 => "+s);

        Hashtable var = new Hashtable();
        var.put("$a","Apple");
        var.put("$bar","Baloney");
        // Give this rule a name...
        ReplaceRule.define("var_rule",new VarRule(var));
        // Obtain a Regex that uses VarRule by building
        // it from a String.  Note that the clone1() method
        // must be defined since ReplaceRule will convert
        // the String to an instance of VarRule by cloning.
        r = Regex.perlCode("s/\\$\\w+\\b/${var_rule}/");

        s = r.replaceAll(txt);
        System.out.println("result 3 => "+s);
    }
}
/* The output:

result 1 => $A is a var, $XX, $FOO, and $BAR are too.
result 2 => #1 is a var, #2, #3, and #4 are too.
result 3 => Apple is a var, $xx, $foo, and Baloney are too.
*/