toUpperLatinOnly method

String toUpperLatinOnly()

Converts only the Latin alphabetic characters (a-z) in the string to uppercase, leaving other characters unchanged.

This method iterates through the string and converts any Latin lowercase letters to uppercase, while leaving numbers, symbols, whitespace, and non-Latin characters untouched.

Performance: Uses StringBuffer for O(n) time complexity instead of string concatenation which would be O(n²).

Returns: A new string with Latin alphabetic characters converted to uppercase.

Example:

'latincafé123'.toUpperLatinOnly(); // Returns 'LATINcafé123' (only 'latin' part is uppercased)
'UPPERCASE'.toUpperLatinOnly();    // Returns 'UPPERCASE' (already uppercase)
''.toUpperLatinOnly();             // Returns ''

Implementation

// cspell: ignore latincafé123 uppercased
/// Example:
/// ```dart
/// 'latincafé123'.toUpperLatinOnly(); // Returns 'LATINcafé123' (only 'latin' part is uppercased)
/// 'UPPERCASE'.toUpperLatinOnly();    // Returns 'UPPERCASE' (already uppercase)
/// ''.toUpperLatinOnly();             // Returns ''
/// ```
String toUpperLatinOnly() {
  if (isEmpty) {
    return '';
  }

  // Use StringBuffer for O(n) performance instead of O(n²) string concatenation
  final StringBuffer buffer = StringBuffer();

  // ASCII code points for lowercase Latin letters
  const int codeUnitA = 0x61; // 'a'
  const int codeUnitZ = 0x7A; // 'z'

  // Don't iterate over runes because unicode / emoji == multiple runes
  for (int i = 0; i < length; i++) {
    final String s = this[i];
    final int codeUnit = s.codeUnitAt(0);
    if (codeUnit >= codeUnitA && codeUnit <= codeUnitZ) {
      buffer.write(s.toUpperCase());
    } else {
      buffer.write(s);
    }
  }

  // NOTE: If you want toUpperLatinOnly() to perform a more visually "correct" uppercasing of
  // accented Latin characters (transforming 'é' to 'É', 'à' to 'À', etc.), then you'll need to
  // modify the toUpperLatinOnly() method to include special handling for these characters. This
  // would likely involve:
  //
  // Creating a mapping of lowercase accented Latin characters to their uppercase counterparts.
  // You would need to identify the specific accented characters you want to handle.
  //
  // Checking for these lowercase accented characters in your loop.
  //
  // Replacing them with their uppercase equivalents from your mapping if found.
  //
  // For other characters, keep the existing toUpperCase() logic.
  return buffer.toString();
}