diff --git a/Luxe/math/stringUtil.wren b/Luxe/math/stringUtil.wren index 0ccb40b..ce10828 100644 --- a/Luxe/math/stringUtil.wren +++ b/Luxe/math/stringUtil.wren @@ -1,6 +1,28 @@ - +//a lot of this is bad and can only handle ASCII +//too bad ¯\_(ツ)_/¯ class StringUtil{ + static directions{ + if(!__directions){ + var step_names = ["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"] + __directions= step_names.map{|short| + var shorts = "NESW" + var base_directions = ["north","east","south","west"] + if(short.count == 1){ + return base_directions[shorts.indexOf(short)] + } else if(short.count == 2) { + return base_directions[shorts.indexOf(short[0])] + + base_directions[shorts.indexOf(short[1])] + } else { //assume 3 + return base_directions[shorts.indexOf(short[0])] + "-" + + base_directions[shorts.indexOf(short[1])] + + base_directions[shorts.indexOf(short[2])] + } + }.toList + } + return __directions + } + static possesive(string){ if(string.endsWith("s")){ return "%(string)'" @@ -20,26 +42,82 @@ class StringUtil{ //todo: this doesnt cover all cases perfectly, add more static a(string){ var firstChar = string[0] - if(isVowel(firstChar)){ + if(is_vowel(firstChar)){ return "an %(string)" } else { return "a %(string)" } } - static isVowel(char){ + static is_vowel(char){ return "aeiou".contains(char) } - //todo: do - static capitalize(string){ - return string + static direction(index){ + return directions[index] } - //todo: ths ignores words that arent preceeded by a space like (this) or "this". maybe fix that? + //checks if a character (as codepoint is lowercase) + static is_lower(char){ + return char >= 97 && char <= 122 + } + + //checks if a character (as codepoint is uppercase) + static is_upper(char){ + return char >= 65 && char <= 90 + } + + static is_letter(char){ + return is_lower(char) || is_upper(char) + } + + static to_upper(string){ + return string.codePoints.map{|c|is_lower(c)?c-32:c}.map{|c|String.fromCodePoint(c)}.join() + } + + static to_lower(string){ + return string.codePoints.map{|c|is_upper(c)?c+32:c}.map{|c|String.fromCodePoint(c)}.join() + } + + static capitalize(string){ + return to_upper(string[0]) + string[1..-1] + } + + //todo: this ignores words that arent preceeded by a space like (this) or "this". maybe fix that? static capitalize_all(string){ - var words = string.split(" ") - words = words.map{|word| capitalize(word)} - return words.join(" ") + //split by words/stuff between words and capitalize everything, + //capitalize function doesnt know what to do with separators so it wont touch them + return WordSequence.new(string).map{|word| capitalize(word)}.join() + } +} + +class WordSequence is Sequence{ + static new(string){ + return new(string) {|c| + return StringUtil.is_letter(c) + } + } + + construct new(string, letterCheck){ + _string = string + _check = letterCheck + } + + iterate(iterator){ + if(!iterator) iterator = [-1, -1, false] //fake value from -1 to -1 + if(iterator[1] >= _string.count-1) return false //abort when at end + var start = iterator[1]+1 + var is_word = StringUtil.is_letter(_string.codePointAt_(start)) + var end = start + 1 + //count up until you find something thats not a word/separator depending on what the first letter was + while(end < _string.count && StringUtil.is_letter(_string.codePointAt_(end)) == is_word){ + end = end + 1 + } + end = end - 1 + return [start, end, is_word] + } + + iteratorValue(iterator){ + return _string[iterator[0]..iterator[1]] } } \ No newline at end of file