001    package com.saelist.stx.operators;
002    
003    import java.util.*;
004    import com.saelist.stx.parser.*;
005    import com.saelist.stx.*;
006    
007    
008    /** See {@link com.saelist.stx.Operator} for general description of the Operator
009      * concept in stx. YankOperator replaces the text of the pair with the
010      * concatenated text of its descendants. The text is indented with two
011      * spaces for each generation.
012      * <pre>
013      *
014      *   text
015      *     '
016      *       this is
017      *       a message composed of
018      *         multiple lines.
019      *
020      *
021      *</pre>
022      * into
023      * <pre>
024      *
025      *   text
026      *     this is\na message composed of\n  multiple lines.
027      *
028      *</pre>
029      */
030    public class YankOperator extends AbstractOperator {
031    
032      private Set removed = new HashSet();
033      private String pattern;
034    
035      /** Caches the pattern and replacement settings in variables.
036        */
037      public void init() {
038        pattern = config.eval1("pattern");
039        logger.info("init(): pattern=" + pattern);
040        removed.clear();
041      }
042    
043      /** Replaces the text of pairs that match pattern with the concatenated text
044        * of its descendands and removes the descendants.
045        */
046      public void operate(Pair pair) {
047        if(! pair.getText().matches(pattern) || removed.contains(pair))
048          return;
049        pair.setText(subText(pair, ""));
050      }
051    
052      /** Recursively accumulates the text of the descendants of <code>pair</code>
053        * while removing them from their parents.
054        */
055      public String subText(Pair pair, String indent) {
056        logger.debug("subText(): pair=" + pair + "', indent='" + indent + "'.");
057        StringBuffer text = new StringBuffer();
058        for(Iterator children = pair.getPairs(); children.hasNext(); ) {
059          Pair child = (Pair) children.next();
060          text.append(indent + child.getText() + "\n" + subText(child, indent + "  "));
061          pair.remove(child);
062          removed.add(child);
063        }
064        return text.toString();
065      }
066    
067    
068    }