Source code for xsdata.utils.text

import re
import string
from typing import Any
from typing import List
from typing import Match
from typing import Tuple

stop_words = {
    "",
    "Decimal",
    "Dict",
    "Enum",
    "False",
    "List",
    "Meta",
    "None",
    "Optional",
    "QName",
    "True",
    "Type",
    "Tuple",
    "Union",
    "and",
    "as",
    "assert",
    "bool",
    "break",
    "class",
    "continue",
    "def",
    "del",
    "dict",
    "elif",
    "else",
    "except",
    "field",
    "finally",
    "float",
    "for",
    "from",
    "global",
    "if",
    "import",
    "in",
    "int",
    "is",
    "lambda",
    "list",
    "nonlocal",
    "not",
    "object",  # py36 specific
    "or",
    "pass",
    "raise",
    "return",
    "self",
    "str",
    "try",
    "while",
    "with",
    "yield",
}

is_reserved = stop_words.__contains__


def prefix(value: str, sep: str = ":") -> str:
    """Return the first part of the string before the separator."""
    return split(value, sep)[0]


def suffix(value: str, sep: str = ":") -> str:
    """Return the last part of the string after the separator."""
    return split(value, sep)[1]


def split(value: str, sep: str = ":") -> Tuple:
    """
    Separate the given string with the given separator and return a tuple of
    the prefix and suffix.

    If the separator isn't present in the string return None as prefix.
    """
    left, _, right = value.partition(sep)
    return (left, right) if right else (None, left)


[docs]def capitalize(value: str, **kwargs: Any) -> str: """Capitalize the given string.""" return value[0].upper() + value[1:]
def original_case(value: str, **kwargs: Any) -> str: """Return the input string without any modifications.""" return value
[docs]def pascal_case(value: str, **kwargs: Any) -> str: """Convert the given string to pascal case.""" return "".join(map(str.title, split_words(value)))
[docs]def camel_case(value: str, **kwargs: Any) -> str: """Convert the given string to camel case.""" result = "".join(map(str.title, split_words(value))) return result[0].lower() + result[1:]
[docs]def mixed_case(value: str, **kwargs: Any) -> str: """Convert the given string to mixed case.""" return "".join(split_words(value))
[docs]def mixed_pascal_case(value: str, **kwargs: Any) -> str: """Convert the given string to mixed pascal case.""" return capitalize(mixed_case(value))
[docs]def mixed_snake_case(value: str, **kwargs: Any) -> str: """Convert the given string to mixed snake case.""" return "_".join(split_words(value))
[docs]def snake_case(value: str, **kwargs: Any) -> str: """Convert the given string to snake case.""" return "_".join(map(str.lower, split_words(value)))
def screaming_snake_case(value: str, **kwargs: Any) -> str: """Convert the given string to screaming snake case.""" return snake_case(value, **kwargs).upper()
[docs]def kebab_case(value: str, **kwargs: Any) -> str: """Convert the given string to kebab case.""" return "-".join(split_words(value))
def split_words(value: str) -> List[str]: """Split a string on new capital letters and not alphanumeric characters.""" words: List[str] = [] buffer: List[str] = [] previous = None def flush(): if buffer: words.append("".join(buffer)) buffer.clear() for char in value: tp = classify(char) if tp == StringType.OTHER: flush() elif not previous or tp == previous: buffer.append(char) elif tp == StringType.UPPER and previous != StringType.UPPER: flush() buffer.append(char) else: buffer.append(char) previous = tp flush() return words class StringType: UPPER = 1 LOWER = 2 NUMERIC = 3 OTHER = 4 def classify(character: str) -> int: """String classifier.""" code_point = ord(character) if 64 < code_point < 91: return StringType.UPPER if 96 < code_point < 123: return StringType.LOWER if 47 < code_point < 58: return StringType.NUMERIC return StringType.OTHER ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') ESCAPE_DCT = { "\\": "\\\\", '"': '\\"', "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t", } for i in range(0x20): ESCAPE_DCT.setdefault(chr(i), f"\\u{i:04x}") def escape_string(value: str) -> str: """ Escape a string for code generation. Source: json.encoder.py_encode_basestring """ def replace(match: Match) -> str: return ESCAPE_DCT[match.group(0)] return ESCAPE.sub(replace, value) __alnum_ascii__ = set(string.digits + string.ascii_letters) def alnum(value: str) -> str: """Return a lower case version of the string only with ascii alphanumerical characters.""" return "".join(filter(__alnum_ascii__.__contains__, value)).lower()