PigLatin.java

Download PigLatin.java

  1: import java.io.*;
  2: 
  3: /** Java utility class to convert text into Pig-latin.
  4:  * The main task is performed by the <code>encrypt</code> method.
  5:  * <p>
  6:  * Pig-latin words are formed by shifting leading consonants of
  7:  * a word to the end, and adding "ay".  If the word begins with
  8:  * a vowel, just add "way" (no shifting).  So "Java" becomes
  9:  * "Avajay" while "out" becomes "outway".  There are extra rules
 10:  * for dealing with "u" and "y".  For simplicity this code treats
 11:  * hyphens and apostrophes as consonants, so words such as "I'll"
 12:  * and "Q-Tip" don't come out quite right.
 13: 
 14:  * @author Wayne Pollock, Tampa, FL USA
 15:  * @version 1.0
 16:  */
 17: 
 18: public class PigLatin
 19: {
 20: private PigLatin () {}  // Nobody can construct objects of this class.
 21: 
 22: /** This main method is used only as a test driver for the
 23:  * {@link #encrypt(String) encrypt(String)} method.
 24:  */
 25: public static void main ( String [] args )
 26: {
 27:     String testString = "Java is very simple!";
 28:     System.out.println( "Testing PigLatin.encrypt() method:" );
 29:     String result = encrypt( testString );
 30:     System.out.println( "Input:  " + testString );
 31:     System.out.println( "Output: " + result );
 32: }
 33: 
 34: /** Encrypts text into Pig-latin.
 35:  *  @param text The plain-text to be encrypted.
 36:  *  @return The encrypted text.
 37:  */
 38: public static String encrypt ( String text )
 39: {
 40:    if ( text.length() == 0 )
 41:       return "";
 42:    StringReader sr = new StringReader( text );
 43:    StringWriter sw = new StringWriter();
 44: 
 45:    for ( ;; )
 46:    {
 47:       String word = getNextWord( sr, sw );
 48:       if ( word.equals("") )
 49:           break;  // End of text reached, all done.
 50: 
 51:       // Write the "pig latin"-ized word:
 52:       sw.write( xlateWord(word) );
 53:    }
 54:    try
 55:    {  sr.close();
 56:       sw.close();
 57:    } catch ( Exception ignored ) {}
 58:    return sw.toString();
 59: }
 60: 
 61: 
 62: // getNextWord is a kind of String tokenizer, but it correctly
 63: // handles punctuation symbols:
 64: private static String getNextWord (StringReader sr, StringWriter sw)
 65: {
 66:    char c = ' ';  // Initialize to avoid annoying javac warnings!
 67:    int ch = 0;
 68: 
 69:    // Read the input, writting the characters read, until
 70:    // the start of a word is found:
 71: 
 72:    try
 73:    {
 74:       while ( ( ch=sr.read() ) !=  -1 )
 75:       {
 76:          c = (char) ch;
 77:          if ( Character.isLetter(c) ) break;
 78:          sw.write( c );
 79:       }
 80:    } catch ( IOException ignored ) {}
 81: 
 82:    if ( ch == -1 )  return "";   // All done; return an empty string.
 83: 
 84:    // Now collect all the letters in the word, and return it:
 85:    StringBuffer word = new StringBuffer();
 86:    do
 87:    {  try
 88:       {  word.append( c );
 89:          sr.mark(1);
 90:          ch = sr.read();
 91:          c = (char) ch;
 92:       } catch (IOException ignored) {}
 93:    } while ( (ch !=  -1) && ( c == '-' || c == '\'' || Character.isLetter(c) ) );
 94: 
 95:    if ( ch != -1 ) try {
 96:       sr.reset();  // rewind to the last mark, i.e., back up one character.
 97:    }  catch ( IOException ignored ) {}
 98: 
 99:    return word.toString();
100: }
101: 
102: 
103: // xlateWord implements the Pig Latin rules and translates its arg.
104: private static String xlateWord ( String inWord )
105: {
106:    StringBuffer word = new StringBuffer( inWord );
107:    char let = word.charAt( 0 );
108:    boolean isUpCase = Character.isUpperCase( let );
109:    boolean allCaps = inWord.equals( inWord.toUpperCase() );
110:    boolean containsHyphen = ( inWord.indexOf( '-' ) != -1 );
111:    let = Character.toLowerCase( let );
112: 
113:    // Words not begining with a consonant have "way" appended:
114: 
115:    if ( let == 'a' || let == 'e' || let == 'i' || let == 'o' || let == 'u'
116:         || ( ! Character.isLetter(let) )  )
117:    {
118:       if ( allCaps )
119:          word.append( "WAY" );
120:       else
121:          word.append( "way" );
122:       return word.toString();
123:    }
124: 
125:    // Words begining with a consonant have the leading consonants
126:    // (including a "u" preceeded by a "q") shifted to the end,
127:    // and the suffix "ay" is then added:
128: 
129:    int i;
130:    boolean qFlag = false;     // When true shows the previous letter was a 'q'.
131:    if ( ! allCaps )
132:       word.setCharAt( 0, let );  // Replace original letter with lower-case.
133:    StringBuffer leadingConsonants = new StringBuffer();
134: 
135:    loop:
136:    for ( i=0; i<word.length(); ++i )
137:    {
138:       let = word.charAt( i );
139:       switch ( Character.toLowerCase(let) )
140:       {
141:          case 'a':  case 'e':  case 'i':  case 'o':  case 'y':
142:             break loop;
143: 
144:          case '-':              // Turn "q-tip" into "tip-qay".
145:             word.append( '-' );
146:             ++i;
147:             break loop;
148: 
149:          case 'q':
150:             qFlag = true;
151:             leadingConsonants.append( let );
152:             break;
153: 
154:          case 'u':
155:             if ( qFlag )
156:             {  qFlag = false;
157:                leadingConsonants.append( let );
158:                break;
159:             } else
160:             {  break loop;
161:             }
162: 
163:          default:
164:             qFlag = false;
165:             leadingConsonants.append( let );
166:             break;
167:       }
168:    }
169: 
170:    if ( allCaps )
171:       leadingConsonants.append( "AY" );
172:    else
173:       leadingConsonants.append( "ay" );
174: 
175:    if ( i >= word.length() )  // Then the word has no vowels!
176:       return leadingConsonants.toString();
177: 
178:    if ( isUpCase )   // If original word was capitalized, so is result.
179:    {  let = word.charAt( i );
180:       word.setCharAt( i, Character.toUpperCase(let) );
181:    }
182: 
183:    StringBuffer outWord = new StringBuffer();
184:    outWord.append( word.toString().substring(i) );
185:    outWord.append( leadingConsonants.toString() );
186:    return outWord.toString();
187: }
188: 
189: } // End of class PigLatin