Skip to content

Commit 26bdbef

Browse files
authored
Merge pull request #108 from posthtml/2.1.0
2 parents 9ed18f2 + d267e81 commit 26bdbef

File tree

8 files changed

+7445
-12321
lines changed

8 files changed

+7445
-12321
lines changed

.eslintrc

Lines changed: 0 additions & 23 deletions
This file was deleted.

.github/workflows/nodejs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414

1515
strategy:
1616
matrix:
17-
node-version: [18, 20]
17+
node-version: [18, 20, 22]
1818

1919
steps:
2020
- uses: actions/checkout@v4

biome.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
3+
"organizeImports": {
4+
"enabled": true
5+
},
6+
"linter": {
7+
"enabled": true,
8+
"rules": {
9+
"recommended": true
10+
}
11+
}
12+
}

build.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
export default defineBuildConfig({
4+
rollup: {
5+
emitCJS: true,
6+
},
7+
rootDir: './lib',
8+
outDir: '../dist',
9+
entries: ['index.js'],
10+
})

dist/index.cjs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict';
2+
3+
const intersectKeys = (_a, _b) => {
4+
let ai = 0;
5+
let bi = 0;
6+
const result = [];
7+
const a = Object.keys(_a).sort();
8+
const b = Object.keys(_b).sort();
9+
while (ai < a.length && bi < b.length) {
10+
if (a[ai] < b[bi]) {
11+
ai++;
12+
} else if (a[ai] > b[bi]) {
13+
bi++;
14+
} else {
15+
result.push(a[ai]);
16+
ai++;
17+
bi++;
18+
}
19+
}
20+
return result;
21+
};
22+
23+
function lowercaseEntities(string) {
24+
return String(string).replace(/&[A-Z]+;/g, (match) => match.toLowerCase());
25+
}
26+
function processContent(options, content, attribute, attributeValue) {
27+
if (Array.isArray(content)) {
28+
return Promise.all(content.map((childContent) => processContent(options, childContent, attribute, attributeValue)));
29+
}
30+
if (typeof content === "object" && content !== null) {
31+
if (content.content) {
32+
return Promise.resolve(processContent(options, content.content, attribute, attributeValue)).then((updatedContent) => {
33+
content.content = updatedContent;
34+
return content;
35+
});
36+
}
37+
return Promise.resolve(content);
38+
}
39+
if (typeof options[attribute] === "function") {
40+
return Promise.resolve(options[attribute](String(content), attributeValue)).then((content2) => lowercaseEntities(content2));
41+
}
42+
return Promise.resolve(content);
43+
}
44+
function walk(options, node) {
45+
if (node.attrs) {
46+
const opt = intersectKeys(options, node.attrs)[0];
47+
if (opt !== void 0) {
48+
const attribute = opt;
49+
const attributeValue = node.attrs[attribute];
50+
delete node.attrs[attribute];
51+
return processContent(options, node.content, attribute, attributeValue).then((result) => {
52+
node.content = result;
53+
return node;
54+
});
55+
}
56+
}
57+
if (Array.isArray(node.content)) {
58+
return Promise.all(node.content.map((childNode) => walk(options, childNode))).then((updatedContent) => {
59+
node.content = updatedContent;
60+
return node;
61+
});
62+
}
63+
return Promise.resolve(node);
64+
}
65+
const plugin = (options) => {
66+
return (nodes) => {
67+
return Promise.all(nodes.map((node) => walk(options, node))).then((updatedNodes) => updatedNodes);
68+
};
69+
};
70+
71+
module.exports = plugin;

dist/index.mjs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const intersectKeys = (_a, _b) => {
2+
let ai = 0;
3+
let bi = 0;
4+
const result = [];
5+
const a = Object.keys(_a).sort();
6+
const b = Object.keys(_b).sort();
7+
while (ai < a.length && bi < b.length) {
8+
if (a[ai] < b[bi]) {
9+
ai++;
10+
} else if (a[ai] > b[bi]) {
11+
bi++;
12+
} else {
13+
result.push(a[ai]);
14+
ai++;
15+
bi++;
16+
}
17+
}
18+
return result;
19+
};
20+
21+
function lowercaseEntities(string) {
22+
return String(string).replace(/&[A-Z]+;/g, (match) => match.toLowerCase());
23+
}
24+
function processContent(options, content, attribute, attributeValue) {
25+
if (Array.isArray(content)) {
26+
return Promise.all(content.map((childContent) => processContent(options, childContent, attribute, attributeValue)));
27+
}
28+
if (typeof content === "object" && content !== null) {
29+
if (content.content) {
30+
return Promise.resolve(processContent(options, content.content, attribute, attributeValue)).then((updatedContent) => {
31+
content.content = updatedContent;
32+
return content;
33+
});
34+
}
35+
return Promise.resolve(content);
36+
}
37+
if (typeof options[attribute] === "function") {
38+
return Promise.resolve(options[attribute](String(content), attributeValue)).then((content2) => lowercaseEntities(content2));
39+
}
40+
return Promise.resolve(content);
41+
}
42+
function walk(options, node) {
43+
if (node.attrs) {
44+
const opt = intersectKeys(options, node.attrs)[0];
45+
if (opt !== void 0) {
46+
const attribute = opt;
47+
const attributeValue = node.attrs[attribute];
48+
delete node.attrs[attribute];
49+
return processContent(options, node.content, attribute, attributeValue).then((result) => {
50+
node.content = result;
51+
return node;
52+
});
53+
}
54+
}
55+
if (Array.isArray(node.content)) {
56+
return Promise.all(node.content.map((childNode) => walk(options, childNode))).then((updatedContent) => {
57+
node.content = updatedContent;
58+
return node;
59+
});
60+
}
61+
return Promise.resolve(node);
62+
}
63+
const plugin = (options) => {
64+
return (nodes) => {
65+
return Promise.all(nodes.map((node) => walk(options, node))).then((updatedNodes) => updatedNodes);
66+
};
67+
};
68+
69+
export { plugin as default };

0 commit comments

Comments
 (0)