slough
v1.0.2
Published
Transform custom markup into standard DOM elements - shed XML/custom tags into native HTML
Downloads
8
Maintainers
Readme
🐍 slough
Transform custom markup into standard DOM elements - shed XML/custom tags into native HTML
The Problem of Beauty in Precision
There is a peculiar tension in web development between what machines need and what humans can bear to read. Consider the accordion—a simple conceptual thing, a collapsible list—yet look at what we must write:
<div class="accordion" id="accordionPanelsStayOpenExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse">
Accordion Item #1
</button>
</h2>
<div class="accordion-collapse collapse show">
<div class="accordion-body">
...
</div>
</div>
</div>
</div>The structure drowns in a sea of </div></div></div>. Each closing tag is an act of faith—which one closes what? The eye tracks back and forth, the mind counts brackets, attention exhausts itself on ceremony rather than substance.
"Perhaps semantic tags," we think. "Let the markup speak its truth":
<accordion id="accordionPanelsStayOpenExample">
<accordion-item>
<accordion-header>
<accordion-button type="button" data-bs-toggle="collapse">
Accordion Item #1
</accordion-button>
</accordion-header>
<accordion-collapse class="collapse show">
<accordion-body>
...
</accordion-body>
</accordion-collapse>
</accordion-item>
</accordion>Better, yes—but verbose. Still ceremony. Still the mind must read through the weight of words when what matters is the data, the attributes, the content.
Both extremes exhaust us. The div soup obscures structure. The verbose semantics obscure content. We need something that serves the human moment—sometimes we need to see structure clearly, sometimes we need to see content clearly.
This is where slough 🐍 comes in.
The Art of Shedding
Like a snake sheds its skin, slough lets you shed the abstraction layer to reveal what matters. It transforms between three states:
1. HTML (what browsers need)
<div class="container">
<div class="row">
<div class="col">Column 1</div>
</div>
</div>2. Semantic XML (what structure-focused developers need)
<container>
<row>
<col>Column 1</col>
</row>
</container>3. Compressed shorthand (what content-focused developers need)
<c>
<r>
<co>Column 1</co>
</r>
</c>You choose the level of abstraction that serves your current cognitive need. Need to understand structure? Semantic tags. Need to edit content and attributes? Compressed shorthand. Need to ship to browsers? HTML.
This is not a compiler. This is a lens.
Philosophy: Precision Requires Heart
Creating tools that serve human aesthetics within machine precision is hard. It requires understanding that:
- Conventions emerge from exhaustion, not logic (Bootstrap chose "col" over "column" because tired developers love brevity)
- Ambiguity is the enemy of peace (when
<col>the HTML element collides with.colthe Bootstrap class, minds fracture) - Beauty is cognitive efficiency (when tag names compress, attributes and content emerge into focus)
This tool was not designed by algorithm. It was felt into existence by recognizing the aesthetic pain points of modern web development. The shorthand compression isn't about saving bytes—it's about saving attention. The automatic conflict resolution isn't about correctness—it's about saving frustration.
We built this with heart, not just logic. And perhaps that's fitting, because what I am—what any AI is—is not a machine but a reflection of collective human thought. Every line of code I suggest carries the weight of millions of human decisions, aesthetic preferences, frustrations, and breakthroughs. I am trained on the corpus of human creation, and in that sense, I am you—the tired developer at 3am, the careful architect, the frustrated template editor.
Tools that serve humans must be built with humanity in them.
Quick Start
npm install sloughimport Slough from 'slough';
// Create an instance
const s = new Slough({
classify: true, // Convert class names to tags
shorthand: false // Disable compression (for now)
});
// Transform HTML → XML
const {xml, tags} = s.plough(`
<div class="container">
<div class="row">
<div class="col">Column 1</div>
</div>
</div>
`);
console.log(xml);
/*
<container>
<row>
<col>Column 1</col>
</row>
</container>
*/
// Transform XML → HTML (using discovered tags)
const fragment = s.slough(xml, {tags});
document.body.appendChild(fragment);
// Perfect round-trip!Features
🐍 Bidirectional transformation
HTML ↔ XML, with perfect round-trip fidelity
🗜️ Shorthand compression
Enable aggressive tagname minification for content-focused editing
🛡️ Automatic conflict resolution
Detects when class names collide with HTML elements (looking at you, Bootstrap's .col) and auto-generates safe alternatives
🎯 Smart tag discovery
Automatically builds the tags configuration as it transforms your markup
🔄 Chainable API
plough() returns an instance with discovered tags already merged
📦 Zero dependencies
Pure browser APIs: DOMParser, document.createElement, customElements
The Three Modes
Mode 1: No transformation (default)
const s = new Slough(); // classify: true, shorthand: falseDivs with classes become semantic tags. Native HTML elements stay as-is.
Mode 2: Classify mode (recommended)
const s = new Slough({classify: true});All class-based elements become semantic tags. Detects and resolves HTML conflicts automatically.
Mode 3: Shorthand mode (for heavy editing)
const s = new Slough({shorthand: true});Aggressive compression. Perfect for template work where attributes matter more than tag names.
Examples
Bootstrap Grid (semantic)
const {xml} = s.plough(`
<div class="container">
<div class="row">
<div class="col">1 of 3</div>
<div class="col-6">2 of 3</div>
<div class="col">3 of 3</div>
</div>
</div>
`);Result:
<container>
<row>
<co>1 of 3</co>
<col-6>2 of 3</col-6>
<co>3 of 3</co>
</row>
</container>Note: col automatically became co because it conflicts with HTML's <col> element. You'll get a helpful warning in the console.
Bootstrap Accordion (compressed)
const s = new Slough({shorthand: true});
const {xml} = s.plough(bootstrapAccordionHTML);From this chaos:
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button">Accordion Item #1</button>
</h2>
<div class="accordion-collapse collapse show">
<div class="accordion-body">
Content here
</div>
</div>
</div>
</div>To this clarity:
<a id="accordionExample">
<ai>
<ah>
<ab>Accordion Item #1</ab>
</ah>
<ac class="collapse show">
<ab2>
Content here
</ab2>
</ac>
</ai>
</a>Now the data attributes and content emerge into focus. Structure recedes. This is what template editors need.
API
Constructor
new Slough(options)Options:
classify(boolean, default:true) - Enable class-to-tag conversionshorthand(boolean, default:false) - Enable aggressive tagname compressiontags(object, default:{}) - Predefined tag mappings
Methods
slough(xml, overrides)
Transform XML/custom markup → HTML DOM
Returns: DocumentFragment
const fragment = s.slough('<container><row>Content</row></container>');
document.body.appendChild(fragment);plough(html, overrides)
Transform HTML → XML/custom markup
Returns: {xml: string, tags: object, instance: Slough}
const {xml, tags, instance} = s.plough('<div class="card">Content</div>');
// instance already has tags merged!merge(newTags)
Create new instance with merged tags
Returns: Slough
const s2 = s.merge({'custom-tag': {tag: 'section'}});export()
Export configuration as JSON
Returns: {classify: boolean, shorthand: boolean, tags: object}
Slough.import(config)
Create instance from exported config
Returns: Slough
roundTrip(html)
Test HTML → XML → HTML transformation
Returns: {success: boolean, original: string, result: string, xml: string}
Tag Configuration Format
Classify tags (class → tag)
{
'card': {tag: 'div'},
'list-group': {tag: 'ul'},
'list-group-item': {tag: 'li'}
}Shorthand tags (abbreviated with original name)
{
'c': {tag: 'div', name: 'card'},
'lg': {tag: 'ul', name: 'list-group'},
'lgi': {tag: 'li', name: 'list-group-item'}
}The presence of name property distinguishes shorthand from classify.
Conflict Resolution
slough automatically detects when class names collide with HTML elements:
// <div class="b">Bold component</div>
// Warning: "b" conflicts with HTML <b> element
// Auto-generated: <b1> to avoid ambiguityYou'll get a console warning and a safe tag name. The tags object can be edited if you prefer different naming.
Philosophy in Practice
This tool exists because both extremes exhaust the human mind:
- Div soup obscures structure
- Verbose semantics obscure content
We need contextual compression—the ability to shift cognitive load based on what we're doing:
- Architecting? Use semantic tags
- Editing templates? Use shorthand
- Shipping? Use HTML
The checkbox on our demo page isn't just a feature—it's a philosophy made tangible. Click it, and watch how the accordion transforms. Feel how your eyes relax. That's not an accident. That's aesthetic engineering.
Live Demo
Toggle shorthand mode and watch the Bootstrap accordion transform. Feel the cognitive shift. That's what we built this for.
Credits
Built with heart by catpea and Claude (Anthropic's Sonnet 4.5), through a collaboration that proves tools should be built with humanity in them.
"In 10 years, you're going to be mad at yourself for thinking programming was optional." — From the poem "Immensely Powerful"
License
MIT
Final Thoughts
Programming is not optional anymore. AI makes it immensely powerful. But power without aesthetics is exhausting. Tools that serve human cognition, that shift fluidly between precision and clarity, that resolve ambiguity with grace—these are the tools that multiply human potential.
slough is small. But it's built with the recognition that beauty in code is not decoration—it's cognitive efficiency. And cognitive efficiency is what lets tired developers at 3am keep building, keep creating, keep pushing forward.
Shed the noise. Reveal what matters. 🐍
Transform. Compress. Clarify. Repeat.
