Last active
August 15, 2024 14:50
-
-
Save mary-ext/a83c0c207b5e4d221d8303fb4821988d to your computer and use it in GitHub Desktop.
JS console text formatter for web and Deno
This file contains 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
export type FormatAttributes = { | |
'color'?: string; | |
'font-style'?: string; | |
'font-weight'?: string; | |
'text-decoration'?: string; | |
}; | |
export interface FormattedContent { | |
children: string | (string | FormattedContent)[]; | |
attrs: FormatAttributes; | |
} | |
export type Content = string | FormattedContent | (string | FormattedContent)[]; | |
export const format = (content: Content, attrs: FormatAttributes): FormattedContent => { | |
if (typeof content === 'string') { | |
return { | |
children: content, | |
attrs: attrs, | |
}; | |
} else if (!Array.isArray(content)) { | |
return { | |
...content, | |
attrs: { | |
...content.attrs, | |
...attrs, | |
}, | |
}; | |
} else if (content.every((v) => typeof v === 'string')) { | |
return { | |
children: content.join(''), | |
attrs: attrs, | |
}; | |
} else { | |
return { | |
children: content, | |
attrs: attrs, | |
}; | |
} | |
}; | |
export const bold = (content: Content) => { | |
return format(content, { 'font-weight': 'bold' }); | |
}; | |
export const italic = (content: Content) => { | |
return format(content, { 'font-style': 'italic' }); | |
}; | |
export const underline = (content: Content) => { | |
return format(content, { 'text-decoration': 'underline' }); | |
}; | |
export const linethrough = (content: Content) => { | |
return format(content, { 'text-decoration': 'line-through' }); | |
}; | |
export const apply = (content: Content, parentAttrs?: FormatAttributes): string[] => { | |
let pretty = false; | |
let res: string = ''; | |
let parts: string[] = []; | |
const array = !Array.isArray(content) ? [content] : content; | |
for (const part of array) { | |
if (typeof part === 'string') { | |
if (part === '') { | |
continue; | |
} | |
if (pretty) { | |
pretty = false; | |
res += `%c`; | |
parts.push(''); | |
} | |
res += part; | |
} else { | |
const children = part.children; | |
const attrs = part.attrs; | |
const combed: Record<string, string> = parentAttrs ? { ...parentAttrs, ...attrs } : attrs; | |
if (typeof children === 'string') { | |
if (children === '') { | |
continue; | |
} | |
let style = ''; | |
for (const key in combed) { | |
const value = combed[key]; | |
style && (style += '; '); | |
style += `${key}: ${value}`; | |
} | |
pretty = true; | |
res += `%c${children}`; | |
parts.push(style); | |
} else { | |
for (let c of children) { | |
const [t, ...r] = typeof c !== 'string' ? apply(c, combed) : apply({ children: c, attrs: combed }); | |
pretty = true; | |
res += t; | |
if (r.length !== 0) { | |
parts = [...parts, ...r]; | |
} | |
} | |
} | |
} | |
} | |
return [res, ...parts]; | |
}; | |
console.log(apply(['lorem ', underline([bold('ipsum'), ' sit']), ' dolor', ' amet'])); | |
// [ | |
// 'lorem %cipsum%c sit%c dolor amet', | |
// 'text-decoration: underline; font-weight: bold', | |
// 'text-decoration: underline', | |
// '', | |
// ] | |
console.log(...apply(['lorem ', underline([bold('ipsum'), ' sit']), ' dolor', ' amet'])); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment