import re import string from enum import Enum from typing import List, Union class Cases(Enum): # Reference: https://stackoverflow.com/a/54330161 Camel = 1 Snake = 2 Kebab = 3 Flat = 4 Macro = 5 Cobol = 6 Pascal = 7 Plain = 8 Custom = 9 # Aliases Caterpillar = 3 Hyphen = 3 Spinal = 3 Dash = 3 Lisp = 3 Css = 3 C = 2 Lower = 2 Upper = 5 Train = 6 CapitalCamel = 7 Sentence = 8 class FromCase(list): def __init__(self, text: str, case: Cases, delimiter: str = ' ', preserve_punctuation: bool = False) -> List[str]: removables = string.punctuation if not preserve_punctuation else '' normalizedText = text.translate(str.maketrans('', '', removables.replace(delimiter, ''))) if case in ([Cases.Camel, Cases.Pascal]): wordList = re.findall('^[a-z]+|[A-Z][^A-Z]*', normalizedText) elif case in ([Cases.Snake, Cases.Macro]): wordList = normalizedText.split('_') elif case in ([Cases.Kebab, Cases.Cobol]): wordList = normalizedText.split('-') elif case is Cases.Plain: wordList = normalizedText.split() elif case is Cases.Custom: wordList = normalizedText.split(delimiter) else: raise Exception("Case not supported") super().__init__(wordList) class Convert(str): def __new__(cls, text: Union[str, List[str], FromCase], case: Cases = Cases.Camel, delimiter: Optional[str] = ' ') -> str: if isinstance(text, str): text = FromCase(text, Cases.Plain) # Lowercases string, replaces spaces with nothing, removes element if it is empty words = [word for word in [word.lower().replace(' ', '') for word in text] if word] if case is Cases.Camel: convertedStr = words[0] + ''.join([word.capitalize() for word in words[1:]]) elif case is Cases.Snake: convertedStr = '_'.join(words) elif case is Cases.Kebab: convertedStr = '-'.join(words) elif case is Cases.Flat: convertedStr = ''.join(words) elif case is Cases.Macro: convertedStr = '_'.join(words).upper() elif case is Cases.Cobol: convertedStr = '-'.join(words).upper() elif case is Cases.Pascal: convertedStr = ''.join(words).title() elif case is Cases.Plain: convertedStr = words[0].capitalize() + ' ' + ' '.join(words[1:]) elif case is Cases.Custom: convertedStr = delimiter.join(words) else: raise Exception("Case not recognised") return super().__new__(cls, convertedStr)