@keepmhwn/mark-over
v0.1.0
Published
Transform text within markup tags (HTML) via callbacks while preserving structure
Maintainers
Readme
mark-over
Transform text content within HTML markup while preserving structure
A lightweight library that allows you to transform text content within HTML elements while maintaining the original HTML structure. Perfect for internationalization, text manipulation, or any scenario where you need to modify text content without breaking your markup.
Features
- 🎯 Preserve Structure - Maintains HTML structure while transforming text
- 🔄 Async Support - Works with both synchronous and asynchronous transformations
- 🌐 Universal - Works in both Node.js and browser environments
- 📦 Zero Dependencies (browser mode) - Lightweight for browser usage
- 🎨 Tag Awareness - Access element information (tag name, id, classes) during transformation
- ⚙️ Configurable - Skip specific tags that shouldn't be transformed
Installation
npm install @keepmhwn/mark-overyarn add @keepmhwn/mark-overpnpm add @keepmhwn/mark-overUsage
Node.js Example
import { markOver } from "@keepmhwn/mark-over";
// or explicitly: import { markOver } from "@keepmhwn/mark-over/node";
const html = "<div><h1>Hello</h1><p>World</p></div>";
const result = await markOver(
{
html: html,
},
(taggedText) => {
// Transform each text node
return taggedText.text.toUpperCase();
}
);
console.log(result);
// Output: <div><h1>HELLO</h1><p>WORLD</p></div>Browser Example
import { markOver } from "@keepmhwn/mark-over";
// or explicitly: import { markOver } from "@keepmhwn/mark-over/browser";
const html = "<div><h1>Hello</h1><p>World</p></div>";
const result = await markOver(
{
html: html,
},
(taggedText) => {
return taggedText.text.toUpperCase();
}
);
console.log(result);
// Output: <div><h1>HELLO</h1><p>WORLD</p></div>Note: The default import (
@keepmhwn/mark-over) automatically selects the correct implementation based on your environment. Use/browseror/nodefor explicit control.
Translation Example
import { markOver } from "@keepmhwn/mark-over";
const translations = {
Hello: "안녕하세요",
World: "세계",
Welcome: "환영합니다",
};
const html = `
<div>
<h1>Hello</h1>
<p>Welcome to the World</p>
</div>
`;
const result = await markOver(
{
html: html,
},
(taggedText) => {
// Translate each word
return taggedText.text
.split(" ")
.map((word) => translations[word] || word)
.join(" ");
}
);Using Tag Information
import { markOver } from "@keepmhwn/mark-over";
const html = `
<div>
<h1 id="title" class="header">Product Name</h1>
<p class="description">Description text</p>
<span class="price">$99.99</span>
</div>
`;
const result = await markOver(
{
html: html,
},
(taggedText) => {
// Access element information
const { text, tag } = taggedText;
// Different transformation based on tag
if (tag.name === "H1") {
return text.toUpperCase();
}
// Different transformation based on class
if (tag.classList?.includes("price")) {
return `💰 ${text}`;
}
return text;
}
);Async Transformation (e.g., API calls)
import { markOver } from "@keepmhwn/mark-over";
async function translateText(text: string): Promise<string> {
// Call translation API
const response = await fetch("https://api.example.com/translate", {
method: "POST",
body: JSON.stringify({ text, target: "ko" }),
});
const data = await response.json();
return data.translatedText;
}
const html = "<div><p>Hello World</p></div>";
const result = await markOver(
{
html: html,
},
async (taggedText) => {
// Async transformation
return await translateText(taggedText.text);
}
);Skip Specific Tags
import { markOver } from "@keepmhwn/mark-over";
const html = `
<div>
<p>Translate this</p>
<code>const x = 42;</code>
<pre>function example() {}</pre>
</div>
`;
const result = await markOver(
{
html: html,
skipTags: ["CODE", "PRE"], // Don't transform code blocks
},
(taggedText) => {
return taggedText.text.toUpperCase();
}
);
// CODE and PRE tags remain unchangedAPI
Import Paths
@keepmhwn/mark-over- Auto-detects environment (recommended)@keepmhwn/mark-over/node- Explicitly for Node.js@keepmhwn/mark-over/browser- Explicitly for browsers
markOver(options, transform)
Transforms text content within HTML markup.
Parameters
options:BrowserMarkOverOptions | NodeMarkOverOptionshtml:string- HTML string to transformskipTags:string[](optional) - Array of tag names to skip (default:["STYLE", "SCRIPT", "CODE", "PRE", "SVG"])
transform:(taggedText: TaggedText) => string | Promise<string>- Transformation functiontaggedText: Object containing:text:string- The text contenttag: Object with element information:name:string- Tag name (e.g., "DIV", "P", "SPAN")id:string | null- Element IDclassList:string[] | null- Array of class names
key:number- Unique identifier
Returns
Promise<string> - Transformed HTML string
TypeScript
This library is written in TypeScript and includes type definitions.
import { markOver, type TaggedText } from "@keepmhwn/mark-over";
// or: import { markOver, type NodeMarkOverOptions, type TaggedText } from "@keepmhwn/mark-over/node";
// or: import { markOver, type BrowserMarkOverOptions, type TaggedText } from "@keepmhwn/mark-over/browser";
const result = await markOver(
{
html: "<p>Hello</p>",
},
(taggedText: TaggedText): string => {
return taggedText.text.toUpperCase();
}
);Use Cases
- 🌍 Internationalization (i18n) - Translate HTML content while preserving structure
- 📝 Text Processing - Apply text transformations (uppercase, lowercase, etc.)
- 🔍 Content Analysis - Extract and analyze text with context
- 🎨 Dynamic Styling - Add markup based on text content
- 🤖 AI Text Enhancement - Process text through AI APIs while maintaining HTML structure
- 🔐 Content Sanitization - Transform or filter text content
Default Skip Tags
By default, the following tags are skipped to preserve technical content:
STYLE- CSS stylesSCRIPT- JavaScript codeCODE- Inline codePRE- Preformatted textSVG- SVG elements
You can override this by providing your own skipTags array.
License
MIT © minhwan(keepmhwn)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Issues
If you find a bug or have a feature request, please open an issue.
Author
minhwan(keepmhwn)
- Email: [email protected]
- GitHub: @keepmhwn
