encode method Null safety

String encode(
  1. String string,
  2. {String? characters = '&<>"\'',
  3. bool defaultToAsciiCode = false,
  4. bool defaultToHexCode = false,
  5. bool checkAmpsForEntities = true}
)

Parses a string and replaces every character included in the characters string with their corresponding character entity.

characters defaults to the 5 characters reserved in both HTML and XML: less-than (<), greater-than (>), ampersand (&), apostrophe or single quote ('), and double-quote (").

If characters is null, every single character included in the characters map will be encoded if found in string.

If defaultToAsciiCode is true, the ASCII number will be used to encode the character, if one exists, otherwise the alphabetical character code will be used.

If defaultToHexCode is true, the hex code will be used to encode the character, if one exists, otherwise the alphabetical character code will be used.

defaultToAsciiCode and defaultToHexCode must not both be true.

If checkAmpsForEntities is true, when encoding string for the & character, each & will be checked to see if it's part of a character entity (RegExp(r'&(#?)\w*;')), and will not be encoded if it is.

Implementation

static String encode(
  String string, {
  String? characters = '&<>"\'',
  bool defaultToAsciiCode = false,
  bool defaultToHexCode = false,
  bool checkAmpsForEntities = true,
}) {
  assert(!(defaultToAsciiCode && defaultToHexCode));

  final encodingMap = <String, String>{};

  final encodingCharacters = characters?.split('') ??
      HtmlCharacterEntities.characters.values.toSet();

  for (var i = 0; i < encodingCharacters.length; i++) {
    final character = encodingCharacters.elementAt(i);
    if (character.isEmpty) continue;

    final hasCharacterEntity = entities.containsKey(character);

    String characterEntity;

    if (defaultToAsciiCode || defaultToHexCode || !hasCharacterEntity) {
      if (defaultToHexCode) {
        characterEntity = hexCodes[character]!;
      } else {
        characterEntity = asciiCodes[character]!;
      }
    } else {
      characterEntity = entities[character]!;
    }

    encodingMap.addAll({
      character: characterEntity,
    });
  }

  final encodedCharacters = string.split('');

  final encodingMapCharacters = encodingMap.keys.toList();

  for (var i = 0; i < encodingMapCharacters.length; i++) {
    final character = encodingMapCharacters[i];

    if (character == '&' && checkAmpsForEntities) {
      var ampIndex = 0;

      while (true) {
        ampIndex = encodedCharacters.indexOf('&', ampIndex);

        if (ampIndex == -1) break;

        final stringAtAmp = string.substring(ampIndex);

        if (!stringAtAmp.startsWith(RegExp(r'&(#?)\w*;'))) {
          encodedCharacters[ampIndex] = encodingMap['&']!;
        }

        ampIndex++;
      }

      continue;
    }

    while (encodedCharacters.contains(character)) {
      encodedCharacters[encodedCharacters.indexOf(character)] =
          encodingMap[character]!;
    }
  }

  return encodedCharacters.join();
}