Anslatortray
anslatortray.hpp
Go to the documentation of this file.
1 /* Anslatortray 0.3.0
2  *
3  * A simple, header-only library to translate from English to Pig Latin.
4  *
5  * MIT License
6  *
7  * Copyright (c) 2018 John Jekel
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15 
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26 */
27 
40 #ifndef ANSLATORTRAY_HPP
41 #define ANSLATORTRAY_HPP
42 
43 #define ANSLATORTRAY_VERSION 0.3.0
44 
45 
46 #if __cplusplus >= 201103L//supports C++11 and later
47 
48 #include <string>
49 #include <sstream>
50 #include <cstdint>
51 #include <algorithm>
52 #include <cctype>
53 //#include <iterator>
54 //#include <cstring>
55 
56 
61 namespace anslatortray//Definitions
62 {
71  inline std::string smartWordToPig(const std::string &englishWord);
72 
80  inline std::string translate(const std::string &englishText);
81 
90  inline std::string wordToPig(const std::string &englishWord);
91 
99  inline std::string wordsToPig(const std::string &englishWords);
100 
109  inline std::string attemptWordToEnglish(const std::string &pig, std::uint64_t numBeginningConosoants = 1);
110 
112  constexpr char VOWEL_START_STYLE[] = {"way"};//sometimes "yay" is used
113 
114 
115  //Features in progress
116  #if __cplusplus >= 201402L
117  //inline constexpr char *wordToPig(char *englishWord);//futile attempt at compile time translation
118  #endif
119 
120  #if __cplusplus >= 201703L
121  //inline std::string_view wordToPigSV(std::string_view englishWord);
122  #endif
123 
124 
125  //Internal use
126  namespace Characters
127  {
128  namespace Letters
129  {
131  constexpr char ALL[] {"aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"};
132 
134  constexpr char VOWELS[] {"aAeEiIoOuU"};
136  constexpr char VOWELS_WITH_Y[] {"aAeEiIoOuUyY"};
138  constexpr char Y[] {"yY"};
139  }
140 
142  constexpr char APOSTROPHE[] {"\'"};//should also have ʼ and ’ but unicode does not play nice with std::string::find_last_of
143  }
144 
151  inline std::string changeWords(const std::string &words, std::string wordChanger (const std::string &word));
152 }
153 
154 //Implementations
155 namespace anslatortray
156 {
157  std::string smartWordToPig(const std::string &englishWord)
158  {
159  //find the actual word in the entire string
160  std::string::size_type wordStartIndex {englishWord.find_first_of(Characters::Letters::ALL)};//after any beginning punctuation
161 
162  std::string::size_type wordEndIndex {englishWord.find_last_of(Characters::APOSTROPHE)};//try to find an ending apostrophe for possesion or a contraction, seperate from translation
163  if (wordEndIndex == std::string::npos)//if there is no apostrophe
164  wordEndIndex = {englishWord.find_last_of(Characters::Letters::ALL) + 1};//find the last letter in the string to use as ending
165 
166 
167  //extract it and translate
168  std::string actualWord = {englishWord.substr(wordStartIndex, wordEndIndex - wordStartIndex)};//2nd param is count between start and end of actual word
169  std::string pig {wordToPig(actualWord)};//translate English word
170 
171 
172  //capatilization handeling
173  if (std::all_of(std::begin(actualWord), std::end(actualWord), isupper))//if entire original word was uppercase//fixme why no std::toupper
174  std::transform(std::begin(pig), std::end(pig), std::begin(pig), toupper);//make entire translated word uppercase
175  else
176  {
177  std::transform(std::begin(pig), std::end(pig), std::begin(pig), tolower);//make entire translated word lowercase//fixme why no std::tolower
178 
179  if (std::isupper(actualWord[0]))//if original word had an uppercase first letter
180  pig[0] = {static_cast<char> (std::toupper(pig[0]))};//new word should have uppercase first letter; have to cast int to char
181  }
182 
183 
184  //prefix punctuation + pigified word + suffix punctuation
185  std::string result {englishWord.substr(0, wordStartIndex)};//up to the start of the word
186  result += {pig};//translated word from earlier
187  result += {englishWord.substr(wordEndIndex)};//from end of the word to the end of the string
188  return result;
189  }
190 
191  std::string translate(const std::string &englishText)
192  {
193  return changeWords(englishText, smartWordToPig);
194  }
195 
196  std::string wordToPig(const std::string &englishWord)
197  {
198  const std::string::size_type firstVowel {englishWord.find_first_of(Characters::Letters::VOWELS_WITH_Y)};//fixme y being a vowel depends on word
199 
200  if (firstVowel != std::string::npos)
201  {
202  if (firstVowel == 0)//word starts with vowel
203  return englishWord + VOWEL_START_STYLE;
204  else
205  {
206  //word without beginning consononts + beginning consononts + "ay"
207  std::string result {englishWord.substr(firstVowel)};
208  result += englishWord.substr(0, firstVowel);
209  result += "ay";
210 
211  return result;
212  }
213  }
214 
215  return englishWord;
216  }
217 
218  std::string wordsToPig(const std::string &englishWords)
219  {
220  return changeWords(englishWords, wordToPig);
221  }
222 
223  std::string attemptWordToEnglish(const std::string &pig, std::uint64_t numBeginningConosoants)
224  {
225  std::string noAy {pig.substr(0, pig.size() - 2)};//try to take off ay
226 
227  std::string withoutBeginningConosoants {noAy.substr(0, noAy.size() - numBeginningConosoants)};
228  std::string beginningConosoants {noAy.substr(noAy.size() - numBeginningConosoants)};
229 
230  return beginningConosoants + withoutBeginningConosoants;
231  }
232 
233 #if __cplusplus >= 201402L
234  /*
235  //futile attempt at compile time translation
236  constexpr char *wordToPig(char *englishWord)
237  {
238  auto wordSize {std::strlen(englishWord)};
239 
240 
241  auto result {std::find_first_of(englishWord[0], englishWord[wordSize], Characters::Letters::VOWELS_WITH_Y[0], Characters::Letters::VOWELS_WITH_Y[std::strlen(Characters::Letters::VOWELS_WITH_Y)])};
242 
243  std::cout << result << std::endl;
244 
245  if (result != '\n')
246  {
247  if (result == 0)
248  return std::strcat(englishWord, "way");
249  else
250  {
251  //std::string noPrefix {englishWord.substr(result)};
252 
253  //std::string suffix {englishWord.substr(0, result)};
254 
255  //suffix += {"ay"};
256 
257  //std::string finished {noPrefix + suffix};
258 
259  //std::transform(std::begin(finished), std::end(finished), std::begin(finished), tolower);
260 
261  return englishWord;
262  }
263  }
264 
265 
266  return englishWord;
267  }
268  */
269 #endif
270 
271  std::string changeWords(const std::string &words, std::string wordChanger (const std::string &word))
272  {
273  std::stringstream wordStream {words};
274  std::string pigWords {""};
275 
276  std::string word {""};
277 
278  while (wordStream >> word)//tokenize words
279  {
280  //preform wordChanger on each word and add space in between
281  pigWords += {wordChanger(word)};
282  pigWords += {" "};
283  }
284 
285  return pigWords;
286 
287 
288  //best way of doing it (if it worked)
289  //std::transform(std::istream_iterator<std::string> {wordStream}, {}, std::begin(pigWords), [](std::string word){return wordToPig(word);});
290 
291 
292  //not worth the hassle
293  //for (auto word : std::istream_iterator<std::string>{wordStream})
294  //{
295  // pigWords += wordToPig(word);
296  //}
297  }
298 }
299 
300 #else
301 #error At the moment, Anslatortray only has support for C++11 and later. Please change your compiliation flags accordinaly
302 #endif
303 
304 #endif //ANSLATORTRAY_HPP
constexpr char ALL[]
Definition: anslatortray.hpp:131
std::string wordsToPig(const std::string &englishWords)
Uses wordToPig and changeWords to perform dumb translation from English to Pig Latin on every word it...
Definition: anslatortray.hpp:218
constexpr char VOWELS_WITH_Y[]
Definition: anslatortray.hpp:136
std::string wordToPig(const std::string &englishWord)
Translates a single English word to Pig Latin.
Definition: anslatortray.hpp:196
std::string changeWords(const std::string &words, std::string wordChanger(const std::string &word))
Helper function to perform an operation on all whitespace-seperated strings given to it...
Definition: anslatortray.hpp:271
constexpr char Y[]
Definition: anslatortray.hpp:138
std::string smartWordToPig(const std::string &englishWord)
Translates a single complex English word to Pig Latin. (more robust)
Definition: anslatortray.hpp:157
Namespace containing functions to translate from English to Pig Latin.
constexpr char VOWELS[]
Definition: anslatortray.hpp:134
constexpr char VOWEL_START_STYLE[]
Definition: anslatortray.hpp:112
constexpr char APOSTROPHE[]
Definition: anslatortray.hpp:142
std::string attemptWordToEnglish(const std::string &pig, std::uint64_t numBeginningConosoants=1)
Tries to translate a word in Pig Latin back to english.
Definition: anslatortray.hpp:223
std::string translate(const std::string &englishText)
Uses smartWordToPig and changeWords to perform translation from English to Pig Latin on every word it...
Definition: anslatortray.hpp:191