Skip to content

Instantly share code, notes, and snippets.

@nijikokun
Created March 21, 2024 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nijikokun/554df4f35f959f8741d7ff14f168c409 to your computer and use it in GitHub Desktop.
Save nijikokun/554df4f35f959f8741d7ff14f168c409 to your computer and use it in GitHub Desktop.
String Template
// 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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;'),
// 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