ng-whatsapp-format
Version:
Angular pipe to format WhatsApp-style text (bold, italic, strikethrough, code, etc.)
127 lines (115 loc) • 4.66 kB
JavaScript
import * as i0 from '@angular/core';
import { Pipe } from '@angular/core';
class NgWhatsappFormatPipe {
styleElement = null;
constructor() {
this.injectStyles();
}
injectStyles() {
if (typeof document !== 'undefined' && !this.styleElement) {
this.styleElement = document.createElement('style');
this.styleElement.innerHTML = `
.whatsapp-bold {
font-weight: bold;
}
.whatsapp-italic {
font-style: italic;
}
.whatsapp-strike {
text-decoration: line-through;
}
.whatsapp-monospace {
font-family: monospace;
background-color: #f5f5f5;
padding: 2px 4px;
border-radius: 3px;
}
.whatsapp-inline-code {
font-family: monospace;
background-color: #f5f5f5;
padding: 2px 4px;
border-radius: 3px;
}
.whatsapp-quote {
border-left: 4px solid #ccc;
padding-left: 10px;
margin-left: 5px;
color: #555;
}
.whatsapp-list {
padding-left: 20px;
margin: 0;
}
.whatsapp-bullet,
.whatsapp-numbered {
list-style-type: none;
}
`;
document.head.appendChild(this.styleElement);
}
}
transform(value) {
if (!value) {
return value;
}
// Bold text starting and ending with *
value = value.replace(/\*(\S(?:.*?\S)?)\*/g, '<span class="whatsapp-bold">$1</span>');
// Italic text: _text_ (but not inside emails or words)
value = value.replace(/(^|[\s>])_(?!_)([^_]+?)_(?=[\s<]|$)/g, '$1<span class="whatsapp-italic">$2</span>');
// Strike-through text starting and ending with ~
value = value.replace(/~(\S(?:.*?\S)?)~/g, '<span class="whatsapp-strike">$1</span>');
// // Monospace with ``` (triple backticks)
// value = value.replace(
// /```(.+?)```/gs,
// '<span class="whatsapp-monospace">$1</span>'
// );
// Inline code with ` (single backtick)
value = value.replace(/`(\S(?:.*?\S)?)`/g, '<span class="whatsapp-inline-code">$1</span>');
// Quote with >
value = value.replace(/^> (.+)$/gm, '<blockquote class="whatsapp-quote">$1</blockquote>');
// ✅ Parse URLs, including plain domains like google.com
value = value.replace(/\b((https?:\/\/)?(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}([^\s<]*)?)/gi, (match, p1) => {
let url = match;
if (!/^https?:\/\//i.test(match)) {
url = `https://${match}`;
}
return `<a href="${url}" target="_blank" rel="noopener noreferrer">${match}</a>`;
});
// // Bullet list (using * or -)
// value = value.replace(
// /(^|\n)([*-]) (.+)/g,
// '$1<li class="whatsapp-bullet">$3</li>'
// );
// value = value.replace(
// /(<li(.+)<\/li>)/g,
// '<ul class="whatsapp-list">$1</ul>'
// );
// // Numbered list
// value = value.replace(
// /(^|\n)(\d+)\. (.+)/g,
// '$1<li class="whatsapp-numbered">$2. $3</li>'
// );
// value = value.replace(
// /(<li(.+)<\/li>)/g,
// '<ol class="whatsapp-list">$1</ol>'
// );
return value;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgWhatsappFormatPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: NgWhatsappFormatPipe, isStandalone: true, name: "ngWhatsappFormat" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgWhatsappFormatPipe, decorators: [{
type: Pipe,
args: [{
name: 'ngWhatsappFormat',
standalone: true,
}]
}], ctorParameters: () => [] });
/*
* Public API Surface of ng-whatsapp-format
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgWhatsappFormatPipe };
//# sourceMappingURL=ng-whatsapp-format.mjs.map