Created
March 21, 2024 01:32
-
-
Save nijikokun/554df4f35f959f8741d7ff14f168c409 to your computer and use it in GitHub Desktop.
String Template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Map from lowercase to flag emoji | |
const mapLowerUpper = { | |
'a': '🇦', 'b': '🇧', 'c': '🇨', 'd': '🇩', 'e': '🇪', | |
'f': '🇫', 'g': '🇬', 'h': '🇭', 'i': '🇮', 'j': '🇯', | |
'k': '🇰', 'l': '🇱', 'm': '🇲', 'n': '🇳', 'o': '🇴', | |
'p': '🇵', 'q': '🇶', 'r': '🇷', 's': '🇸', 't': '🇹', | |
'u': '🇺', 'v': '🇻', 'w': '🇼', 'x': '🇽', 'y': '🇾', 'z': '🇿' | |
}; | |
// Map for Morse code | |
const mapMorse = { | |
'a': '.-', 'b': '-...', 'c': '-.-.', 'd': '-..', 'e': '.', | |
'f': '..-.', 'g': '--.', 'h': '....', 'i': '..', 'j': '.---', | |
'k': '-.-', 'l': '.-..', 'm': '--', 'n': '-.', 'o': '---', | |
'p': '.--.', 'q': '--.-', 'r': '.-.', 's': '...', 't': '-', | |
'u': '..-', 'v': '...-', 'w': '.--', 'x': '-..-', 'y': '-.--', 'z': '--..' | |
}; | |
// Map for Emoji | |
const mapEmoji = { | |
'a': '🍏', 'b': '🍌', 'c': '🥕', 'd': '🍩', 'e': '🍆', | |
'f': '🍟', 'g': '🍇', 'h': '🍯', 'i': '🍦', 'j': '🍏', | |
'k': '🥝', 'l': '🍋', 'm': '🍈', 'n': '🍉', 'o': '🍊', | |
'p': '🍍', 'q': '🍳', 'r': '🍎', 's': '🍓', 't': '🍅', | |
'u': '🍇', 'v': '🍆', 'w': '🍉', 'x': '🥭', 'y': '🍋', 'z': '🥒' | |
}; | |
// Map for Cyrillic | |
const mapFauxCyrillic = { | |
'a': 'а', 'b': 'в', 'c': 'с', 'e': 'е', 'h': 'н', 'i': 'і', | |
'k': 'к', 'm': 'м', 'n': 'и', 'o': 'о', 'p': 'р', 'r': 'г', | |
's': 'ѕ', 't': 'т', 'u': 'ц', 'x': 'х', 'y': 'у' | |
}; | |
// Map for Superscript | |
const mapSuperscript = { | |
'0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴', '5': '⁵', | |
'6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹', 'a': 'ᵃ', 'b': 'ᵇ', | |
'c': 'ᶜ', 'd': 'ᵈ', 'e': 'ᵉ', 'f': 'ᶠ', 'g': 'ᵍ', 'h': 'ʰ', | |
'i': 'ⁱ', 'j': 'ʲ', 'k': 'ᵏ', 'l': 'ˡ', 'm': 'ᵐ', 'n': 'ⁿ', | |
'o': 'ᵒ', 'p': 'ᵖ', 'q': 'ᵠ', 'r': 'ʳ', 's': 'ˢ', 't': 'ᵗ', | |
'u': 'ᵘ', 'v': 'ᵛ', 'w': 'ʷ', 'x': 'ˣ', 'y': 'ʸ', 'z': 'ᶻ' | |
}; | |
// Map for flipping characters upside down | |
const mapFlip = { | |
'a': 'ɐ', 'b': 'q', 'c': 'ɔ', 'd': 'p', 'e': 'ǝ', | |
'f': 'ɟ', 'g': 'ƃ', 'h': 'ɥ', 'i': 'ᴉ', 'j': 'ɾ', | |
'k': 'ʞ', 'l': 'l', 'm': 'ɯ', 'n': 'u', 'o': 'o', | |
'p': 'd', 'q': 'b', 'r': 'ɹ', 's': 's', 't': 'ʇ', | |
'u': 'n', 'v': 'ʌ', 'w': 'ʍ', 'x': 'x', 'y': 'ʎ', | |
'z': 'z', ' ': ' ', '.': '˙', ',': "'", "'": ',', | |
'?': '¿', '!': '¡', '[': ']', ']': '[', '(': ')', ')': '(', | |
'{': '}', '}': '{' | |
}; | |
// Map for transforming letters to mathematical bold | |
const mapMathBold = { | |
'a': '𝐚', 'b': '𝐛', 'c': '𝐜', 'd': '𝐝', 'e': '𝐞', | |
'f': '𝐟', 'g': '𝐠', 'h': '𝐡', 'i': '𝐢', 'j': '𝐣', | |
'k': '𝐤', 'l': '𝐥', 'm': '𝐦', 'n': '𝐧', 'o': '𝐨', | |
'p': '𝐩', 'q': '𝐪', 'r': '𝐫', 's': '𝐬', 't': '𝐭', | |
'u': '𝐮', 'v': '𝐯', 'w': '𝐰', 'x': '𝐱', 'y': '𝐲', | |
'z': '𝐳' | |
}; | |
// Map for transforming letters to cursive | |
const mapCursive = { | |
'a': '𝒶', 'b': '𝒷', 'c': '𝒸', 'd': '𝒹', 'e': 'ℯ', | |
'f': '𝒻', 'g': 'ℊ', 'h': '𝒽', 'i': '𝒾', 'j': '𝒿', | |
'k': '𝓀', 'l': '𝓁', 'm': '𝓂', 'n': '𝓃', 'o': 'ℴ', | |
'p': '𝓅', 'q': '𝓆', 'r': '𝓇', 's': '𝓈', 't': '𝓉', | |
'u': '𝓊', 'v': '𝓋', 'w': '𝓌', 'x': '𝓍', 'y': '𝓎', 'z': '𝓏' | |
}; | |
// Map for transforming letters to space invader style | |
const mapInvader = { | |
'a': '▒', 'b': '▓', 'c': '░', 'd': '▄', 'e': '█', | |
'f': '▀', 'g': '▌', 'h': '▐', 'i': '┼', 'j': '─', | |
'k': '╞', 'l': '╘', 'm': '┴', 'n': '╫', 'o': '═', | |
'p': '╪', 'q': '┘', 'r': '┌', 's': '└', 't': '├', | |
'u': '┤', 'v': '┬', 'w': '┴', 'x': '┼', 'y': '┤', 'z': '▒' | |
}; | |
// Map for transforming letters to pirate speak | |
const mapPirate = { | |
'a':'arr','e':'arr','i':'arr','o':'arr','u':'arr' | |
} | |
// Map for Zalgo text components | |
const mapZalgo = { | |
up: ['̍', '̎', '̄', '̅'], | |
middle: ['̂', '̈', '̊'], | |
down: ['̖', '̗', '̘', '̙'] | |
}; | |
// Define transformation and argument-taking functions | |
const transformFunctions = { | |
// Converts a string to lowercase | |
lower: (s) => typeof s === 'string' ? s.toLowerCase() : s, | |
// Converts a string to uppercase | |
upper: (s) => typeof s === 'string' ? s.toUpperCase() : s, | |
// Converts a string to snake case | |
'snake': (s) => typeof s === 'string' ? s.replace(/\s+/g, '_').toLowerCase() : s, | |
// Converts a string to kebab case | |
'kebab': (s) => typeof s === 'string' ? s.replace(/\s+/g, '-').toLowerCase() : s, | |
// Capitalizes the first letter of each word in a string | |
'capitalize-words': (s) => typeof s === 'string' ? s.replace(/\b\w/g, char => char.toUpperCase()) : s, | |
// Reverses the characters in a string | |
reverse: (s) => typeof s === 'string' ? [...s].reverse().join('') : s, | |
// Encodes a string into Base64 | |
'base64-encode': (s) => typeof s === 'string' ? window.btoa(s) : s, | |
// Decodes a string from Base64 | |
'base64-decode': (s) => typeof s === 'string' ? window.atob(s) : s, | |
// Removes all spaces from a string | |
'remove-spaces': (s) => typeof s === 'string' ? s.replace(/\s+/g, '') : s, | |
// Converts a string to Title Case | |
'title': (s) => typeof s === 'string' ? s.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()) : s, | |
// Converts a string to camelCase | |
'camel': (s) => typeof s === 'string' ? s.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase()).replace(/\s+/g, '') : s, | |
// Inserts hyphens between words and lowercases all | |
'hyphenate': (s) => typeof s === 'string' ? s.replace(/\s+/g, '-').toLowerCase() : s, | |
// Replaces vowels with asterisk | |
'vowel-asterisk': (s) => typeof s === 'string' ? s.replace(/[aeiou]/ig, '*') : s, | |
// Repeats the string twice | |
'double-repeat': (s) => typeof s === 'string' ? s.repeat(2) : s, | |
// Appends "!!!" at the end of the string | |
'excite': (s) => typeof s === 'string' ? s + '!!!' : s, | |
// Reverses the words in a sentence | |
'reverse-words': (s) => typeof s === 'string' ? s.split(' ').reverse().join(' ') : s, | |
// Converts a string into Morse code (simplified version without punctuation) | |
'morse-code': (s) => typeof s === 'string' ? s.toLowerCase().split('').map(char => mapMorse[char] || char).join(' ') : s, | |
// Masks all but the last 4 characters of a string | |
'mask-last4': (s) => typeof s === 'string' ? s.slice(0, -4).replace(/./g, '*') + s.slice(-4) : s, | |
// Masks all characters with asterisks | |
'mask': (s) => typeof s === 'string' ? '*'.repeat(s.length) : s, | |
// Masks all characters except the last 4 of an SSN | |
'mask-ssn': (s) => typeof s === 'string' ? s.replace(/^(.*?)(\d{4})$/, '***-**-$2') : s, | |
// Masks all digits of a credit card except the last 4, showing only the last block | |
'mask-cc': (s) => typeof s === 'string' ? s.replace(/\d(?=\d{4})/g, '*') : s, | |
// Anonymizes email addresses by masking the local part | |
'mask-email': (s) => typeof s === 'string' ? s.replace(/^(.)(.*)(@.*)$/, (_, a, b, c) => `${a}${'*'.repeat(b.length)}${c}`) : s, | |
// Masks a date, leaving only the year visible | |
'mask-date': (s) => typeof s === 'string' ? s.replace(/(\d{4})-(\d{2})-(\d{2})/, '****-**-$3') : s, | |
// Masks a phone number, leaving the last 4 digits visible | |
'mask-phone': (s) => typeof s === 'string' ? s.replace(/^(.*?)(\d{4})$/, '(***) ***-$2') : s, | |
// Obfuscates a string by shuffling its characters | |
'shuffle': (s) => typeof s === 'string' ? s.split('').sort(() => 0.5 - Math.random()).join('') : s, | |
// Transforms text into an approximation of leet speak, where certain letters are replaced with numerals or other characters. | |
'leet': (s) => typeof s === 'string' ? s.replace(/[aeiost]/gi, char => ({'a':'4','e':'3','i':'1','o':'0','s':'5','t':'7'}[char.toLowerCase()] || char)) : s, | |
// Flip characters upside down | |
'upside-down': (s) => typeof s === 'string' ? s.split('').reverse().map(char => ({'a':'ɐ','e':'ǝ','i':'ᴉ','o':'o','s':'s','t':'ʇ'}[char] || char)).join('') : s, | |
// Transforms text into Pig Latin for a playful effect. | |
'pig-latin': (s) => typeof s === 'string' ? s.split(/\s+/).map(word => /^[aeiou]/i.test(word) ? `${word}way` : `${word.slice(1)}${word[0]}ay`).join(' ') : s, | |
// Swaps the first consonants of two words for humorous effects. | |
'spoonerism': (s) => typeof s === 'string' && s.split(/\s+/).length > 1 ? s.split(' ').map((word, i, arr) => i === 0 ? arr[1].slice(0,1) + word.slice(1) : arr[0].slice(0,1) + word.slice(1)).join(' ') : s, | |
// Randomly changes the case of letters in a string. | |
'random-case': (s) => typeof s === 'string' ? s.split('').map(char => Math.random() > 0.5 ? char.toUpperCase() : char.toLowerCase()).join('') : s, | |
// Reverses the letters in each word while keeping the word order intact. | |
'backwards-words': (s) => typeof s === 'string' ? s.split(/\s+/).map(word => word.split('').reverse().join('')).join(' ') : s, | |
// Transforms text into zalgo | |
'zalgo': (s) => typeof s === 'string' ? s.split('').map(c => c + mapZalgo.up[Math.floor(Math.random() * mapZalgo.up.length)] + mapZalgo.middle[Math.floor(Math.random() * mapZalgo.middle.length)] + mapZalgo.down[Math.floor(Math.random() * mapZalgo.down.length)]).join('') : s, | |
// Transforms text into spongebob mocking text | |
'mocking': (s) => s.split('').map((c, i) => i % 2 === 0 ? c.toLowerCase() : c.toUpperCase()).join(''), | |
// Transforms text into bubble text | |
'bubble': (s) => s.toLowerCase().replace(/[a-z]/g, c => String.fromCharCode(9424 + c.charCodeAt(0) - 'a'.charCodeAt(0))), | |
// Transforms text into wave text | |
'wave': (s) => s.split('').map((c, i) => i % 4 < 2 ? c.toLowerCase() : c.toUpperCase()).join(''), | |
// Inserts a heartbeat or pulse symbol between words to simulate a heartbeat rhythm. | |
'heartbeat': (s) => s.replace(/\s/g, ' ♥ '), | |
// Appends Unicode combining characters to give text a "creepy" moving effect. | |
'creepy-crawly': (s) => s.replace(/./g, '$&\u035E\u0361'), | |
// Replaces each letter with a corresponding emoji that starts with that letter. | |
'emoji-letter': (s) => s.toLowerCase().replace(/./g, c => mapEmoji[c] || c), | |
// Lowercase Uppercase | |
'lower-upper': (s) => s.toLowerCase().replace(/./g, c => mapLowerUpper[c] || c), | |
// Applies a strikethrough effect to text using combining characters. | |
'crossed-out': (s) => s.replace(/./g, '$&\u0336'), | |
// Trims whitespace from the beginning and end of a string. | |
'trim': (s) => s.trim(), | |
// Trims only the beginning whitespace of a string. | |
'trim-start': (s) => s.trimStart(), | |
// Trims only the ending whitespace of a string. | |
'trim-end': (s) => s.trimEnd(), | |
// Ensures a string ends with a period if it doesn't already. | |
'ensure-period': (s) => s.endsWith('.') ? s : `${s}.`, | |
// Converts newline characters to HTML <br> tags. | |
'newlines-to-br': (s) => s.replace(/\n/g, '<br>'), | |
// Escapes HTML tags by replacing them with HTML entities. | |
'escape-html': (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''), | |
// Replaces multiple spaces with a single space. | |
'collapse-spaces': (s) => s.replace(/\s+/g, ' '), | |
// Flips the text upside down. | |
'flip': (s) => [...s].map(c => mapFlip[c.toLowerCase()] || c).reverse().join(''), | |
// Transforms text into mathematical bold characters. | |
'bold': (s) => [...s].map(c => mapMathBold[c.toLowerCase()] || c).join(''), | |
// Applies a faux Cyrillic effect. | |
'faux-cyrillic': (s) => s.replace(/./g, c => mapFauxCyrillic[c.toLowerCase()] || c), | |
// Alternates text case starting with uppercase. | |
'alternating-case': (s) => [...s].map((c, i) => i % 2 === 0 ? c.toUpperCase() : c.toLowerCase()).join(''), | |
// Inserts zero-width spaces between each character. | |
'zero-width-space': (s) => [...s].join(''), | |
// Creates a shadowed text effect by duplicating characters. | |
'shadow-text': (s) => [...s].map(c => c + '̴').join(''), | |
// Converts text to ASCII binary representation. | |
'binary': (s) => [...s].map(c => c.charCodeAt(0).toString(2).padStart(8, '0')).join(' '), | |
// Reverses each word in the string, keeping the sentence structure. | |
'reverse-words': (s) => s.split(/\s+/).map(word => [...word].reverse().join('')).join(' '), | |
// Replaces letters with superscript equivalents (for simple alphabetic characters). | |
'superscript': (s) => s.replace(/./g, c => mapSuperscript[c.toLowerCase()] || c), | |
// Adds asterisks before and after the username. | |
'star-surround': (s) => `*${s}*`, | |
// Wraps the username in brackets. | |
'bracket-wrap': (s) => `[${s}]`, | |
// Adds an underscore before and after the username. | |
'underscore-surround': (s) => `_${s}_`, | |
// Inserts a dot between each character. | |
'dot-spaced': (s) => [...s].join('.'), | |
// Adds a wave effect with tildes at both ends. | |
'waves': (s) => `~${s}~`, | |
// Adds a classic "Xx_" prefix and "_xX" suffix. | |
'xX-surround': (s) => `Xx_${s}_xX`, | |
// Adds a mystical aura around the username. | |
'mystical-aura': (s) => `༺${s}༻`, | |
// Adds emojis before and after the username to make it look like a chat bubble. | |
'chat-bubble': (s) => `💬 ${s} 💬`, | |
// Adds a sparkle effect with stars at both ends. | |
'sparkle': (s) => `✨ ${s} ✨`, | |
// Converts the username into a pirate speak. | |
'pirate-speak': (s) => s.replace(/[aieou]/gi, char => (mapPirate[char.toLowerCase()] || char)), | |
// Adds hearts before and after the username. | |
'heart-surround': (s) => `❤️ ${s} ❤️`, | |
// Applies a space invader effect. | |
'space-invader': (s) => s.replace(/./g, c => mapInvader[c.toLowerCase()] || c), | |
// Applies a cursive effect. | |
'cursive': (s) => s.replace(/./g, c => mapCursive[c.toLowerCase()] || c), | |
}; | |
const argumentFunctions = { | |
'default': (defaultValue) => (s) => s === undefined ? defaultValue : s, | |
'truncate': (value = 5) => (s) => typeof s === 'string' && s.length > parseInt(value) ? s.substr(0, parseInt(value)) + '...' : s, | |
'pad-start': (value = 10) => (s) => s.padStart(parseInt(value), ' '), | |
'pad-end': (value = 10) => (s) => s.padEnd(parseInt(value), ' '), | |
'repeat': (value = 3) => s => s.repeat(parseInt(value)), | |
'surround': (value) => s => [value, s, value].join(''), | |
}; | |
function template(str, data = {}) { | |
// Utility to parse function calls with arguments | |
const parseFunctionWithArgs = (part) => { | |
const funcMatch = part.match(/^([a-z-]+)\((.*?)?\)$/); | |
if (funcMatch) { | |
const [, funcName, arg] = funcMatch; | |
console.log(`[${funcName}]`, arg) | |
return { funcName, arg }; | |
} | |
return null; | |
}; | |
return str.replace(/\{([^\}]+)\}/g, (match, key) => { | |
const parts = key.split('|').map(part => part.trim()); | |
const pathStr = parts.shift(); | |
let value = data[pathStr]; // Initial value | |
for (const part of parts) { | |
const parsedFunc = parseFunctionWithArgs(part); | |
if (parsedFunc) { | |
// Handle argument-taking functions | |
const { funcName, arg } = parsedFunc; | |
if (argumentFunctions[funcName]) { | |
value = argumentFunctions[funcName](arg)(value); | |
} | |
} else if (transformFunctions[part]) { | |
console.log(`[${part}]`, value) | |
// Apply transformation functions | |
value = transformFunctions[part](value); | |
} | |
} | |
return value !== undefined ? value : ''; | |
}); | |
} | |
template('{name | default(hello world) | glitch }') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment