[Odin] Char by char, tracking state[Odin] Char by char, tracking state
🔠🔡
Toggle Case
Week 30, 2026
package main
import "core:fmt"
import "core:strings"
import "core:unicode"
main :: proc () {
quote := `"They couldn't hit an elephant at this distance." - John Sedgwick, moments before being fatally shot`
fmt.println(toggle_case(quote, true, 1, true, true))
fmt.println(toggle_case(quote, true, 1, false, true))
fmt.println(toggle_case(quote, true, 1, true, false))
fmt.println(toggle_case(quote, true, 1, false, false))
fmt.println(toggle_case(quote, true, 2, true, true))
fmt.println(toggle_case(quote, true, 2, false, true))
fmt.println(toggle_case(quote, true, 2, true, false))
fmt.println(toggle_case(quote, true, 2, false, false))
}
toggle_case :: proc (
input : string,
start_upper : bool,
consecutive_same_case : int,
ignore_non_letters_ha : bool,
reset_after_space : bool,
allocator := context.allocator,
) -> string {
sb := strings.builder_make(allocator)
counter := consecutive_same_case
is_upper := start_upper
for r in input {
strings.write_rune(&sb, is_upper ? unicode.to_upper(r) : unicode.to_lower(r))
if unicode.is_alpha(r) || (!ignore_non_letters_ha && r != '-' && r != '\'') {
counter -= 1
if counter == 0 {
counter = consecutive_same_case
is_upper ~= true
}
}
if reset_after_space && r == ' ' {
counter = consecutive_same_case
is_upper = start_upper
}
}
return strings.to_string(sb)
}