HTML
Hook for transforming code in HTML
schema-version: v3
kind: plugin
metadata:
name: code-transformation-plugin
display-name: code-transformation-plugin
description: Code transformation example.
version: 1.0.0
spec:
hooks:
- type: code-transformation
engine-version: 0.2.0-beta
trigger: after-render
language: html
trans-pattern-path: trans-patterns/pattern.ts
source-path: src/code.ts
Supported Constructs in HTML
tag
Tags allow insertion, removal, and ellipsis operators, which means you can use any supported operator wherever a tag is valid.
The following example inserts a div
tag as the first element inside the body
tag. The pattern has file scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: file-scope; >>>>
<...>
<body>
+<<div id="header">
<h1>Welcome to My Website</h1>
</div>>+
<...>
</body>
<...>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="header">
<h1>Welcome to My Website</h1>
</div>
<span><p>This is a paragraph.</p></span>
<p>This is another paragraph.</p>
<div id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
The following example removes all div
tags with no attributes, regardless of their internal content. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<h1>Welcome to My Website</h1>
</div>
<div>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div>
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
-<<div>
<...>
</div>>-
<!DOCTYPE html>
<html lang="en">
<body>
</body>
</html>
tagName
Tag names support ID match, insertion, and removal operators. This means you can use any supported operators instead of a tag name.
Remember that insertion and removal operators must always occur in pairs when used in the context of a tag name. Otherwise, a tag could end up without a name or with more than one name.
When using insertion and removal operators in the context of a tag name, make sure to use them in the closing tag. Otherwise, the opening and closing tags will have different names.
The following example removes all tags whose names start with app
, regardless of their internal content, as long as they do not have any attributes. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<body>
<app-header>
Welcome to My Website
</app-header>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<app-footer id="footer">
<p>Contact us at contact@example.com</p>
</app-footer>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
-<<*<app.+>*>
<...>
<*<app.+>*>>-
<!DOCTYPE html>
<html lang="en">
<body>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
</body>
</html>
If all my-tag
tags lack attributes, regardless of their content, their name is changed to my-new-tag
. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<body>
<my-tag> Content 1 </my-tag>
<my-tag> Content 2 </my-tag>
<my-tag> Content 3 </my-tag>
<my-tag attribute="attr"> Content 4 </my-tag>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
<-<my-tag>- +<my-new-tag>+>
<...>
</-<my-tag>- +<my-new-tag>+>
<!DOCTYPE html>
<html lang="en">
<body>
<my-new-tag> Content 1 </my-new-tag>
<my-new-tag> Content 2 </my-new-tag>
<my-new-tag> Content 3 </my-new-tag>
<my-tag attribute="attr"> Content 4 </my-tag>
</body>
</html>
tagContent
Tag content supports insertion, removal, and ellipsis operators. This means you can use any of the supported operators nested within the content of a tag.
The following example inserts a br
tag nested within all div
tags, regardless of their internal content, as long as they do not have any attributes. The pattern has a snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<body>
<div id="header">
<h1>Welcome to My Website</h1>
</div>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
<div>
<...>
+<<br/>>+
</div>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="header">
<h1>Welcome to My Website</h1>
<br/>
</div>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<br/>
</div>
<div id="footer">
<p>Contact us at contact@example.com</p>
<br/>
</div>
</body>
</html>
attribute
Tag attributes support insertion, removal, and ellipsis operators. You can use any supported operators wherever a tag attribute is valid.
The following example inserts the attribute class="text-align: center;"
into all div
tags, regardless of the tag's internal content or other attributes. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<!DOCTYPE html>
<html lang="en">
<body>
<div id="header">
<h1>Welcome to My Website</h1>
</div>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
<div +<class="text-align: center;">+ <...>>
<...>
</div>
<!DOCTYPE html>
<html lang="en">
<body>
<div class="text-align: center;" id="header">
<h1>Welcome to My Website</h1>
</div>
<div class="text-align: center;" id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div class="text-align: center;" id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
attributeValue
Attribute values support String match, insertion, and removal operators. You can use any supported operators wherever an attribute value is valid.
Remember that insertion and removal operators must always occur in pairs when used in the context of an attribute value. Otherwise, an attribute could end up without a value or with more than one value.
The following example removes the id
attribute from all div
tags, regardless of the original attribute value (string match operator with regex .*
), the tag's internal content, or other attributes. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Pattern
<!DOCTYPE html>
<html lang="en">
<body>
<div id="header">
<h1>Welcome to My Website</h1>
</div>
<div id="content">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div id="footer">
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
<div <...> -<id=*<".*">*>- <...>>
<...>
</div>
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<h1>Welcome to My Website</h1>
</div>
<div>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
<div>
<p>Contact us at contact@example.com</p>
</div>
</body>
</html>
The following example replaces the href
attribute value of the first li
with "#main"
, regardless of the attribute value (string match operator with regex .*
), the tag's internal content, or other attributes. The pattern has file scope..
- Original Code
- Transformation Pattern
- Transformed Code
<html>
<head>
<h1>Welcome to My Website</h1>
<nav>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</head>
<body>
<h1> My Sample Page</h1>
</body>
</html>
<<<< pattern-name: my_pattern; pattern-scope: file-scope; >>>>
<html>
<...>
<head>
<...>
<nav>
<...>
<ul>
<li><a href=-<*<".*">*>- +<"#main">+> <...> </a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
<...>
</nav>
<...>
</head>
<...>
</html>
<html>
<head>
<h1>Welcome to My Website</h1>
<nav>
<ul>
<li><a href="#main">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</head>
<body>
<h1> My Sample Page</h1>
</body>
</html>
attributeName
Attribute names support ID match, insertion, and removal operators. You can use any supported operators wherever an attribute name is valid.
Remember that insertion and removal operators must always occur in pairs when used in the context of an attribute name. Otherwise, an attribute could end up without a name or with more than one name.
The following example replaces the id
attribute name with class
in all section
tags, regardless of the attribute value (string match operator with regex .*
), the tag's internal content, or other attributes. The pattern has snippet scope.
- Original Code
- Transformation Pattern
- Transformed Code
<main>
<section id="home">
<h2>Home</h2>
<p>This is the home section. Here you can find the latest updates and news.</p>
</section>
<section id="about">
<h2>About</h2>
<p>This section provides information about our company and our mission.</p>
<img src="about.jpg" alt="About Us">
</section>
<section id="services">
<h2>Services</h2>
<p>We offer a wide range of services to meet your needs.</p>
<ul>
<li>Service 1</li>
<li>Service 2</li>
<li>Service 3</li>
</ul>
</section>
<section id="contact">
<h2>Contact</h2>
<p>If you have any questions, feel free to reach out to us.</p>
<form action="/submit-form" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<br>
<button type="submit">Submit</button>
</form>
</section>
</main>
<<<< pattern-name: my_pattern; pattern-scope: snippet-scope; >>>>
<section <...> -<id>- +<class>+ = *<".*">* <...>>
<...>
</section>
<main>
<section class="home">
<h2>Home</h2>
<p>This is the home section. Here you can find the latest updates and news.</p>
</section>
<section class="about">
<h2>About</h2>
<p>This section provides information about our company and our mission.</p>
<img src="about.jpg" alt="About Us">
</section>
<section class="services">
<h2>Services</h2>
<p>We offer a wide range of services to meet your needs.</p>
<ul>
<li>Service 1</li>
<li>Service 2</li>
<li>Service 3</li>
</ul>
</section>
<section class="contact">
<h2>Contact</h2>
<p>If you have any questions, feel free to reach out to us.</p>
<form action="/submit-form" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<br>
<button type="submit">Submit</button>
</form>
</section>
</main>