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