include convert html to sigpro
This commit is contained in:
@@ -16,4 +16,5 @@
|
||||
* **Concepts**
|
||||
* [Tags](api/tags.md)
|
||||
* [Global Store](api/global.md)
|
||||
* [JSX Style](api/jsx.md)
|
||||
* [JSX Style](api/jsx.md)
|
||||
* [HTML converter](convert.md)
|
||||
76
docs/convert.js
Normal file
76
docs/convert.js
Normal file
@@ -0,0 +1,76 @@
|
||||
(() => {
|
||||
// src/convert.js
|
||||
var { $, div, h1, label, textarea, button, span } = window;
|
||||
function html2sigpro(h) {
|
||||
const B = new Set(["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "ismap", "itemscope", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected", "truespeed"]), esc = (v) => v.replace(/"/g, "\\\""), bP = (el) => {
|
||||
let a = [...el.attributes].map(({ name: n, value: v }) => /^on/i.test(n) ? `${n}: (e) => { ${v.replace(/\s+/g, " ").trim()} }` : B.has(n.toLowerCase()) && (!v || v == n) ? `${n}: true` : `${n}: "${esc(v)}"`);
|
||||
return a.length ? `{ ${a.join(", ")} }` : "";
|
||||
}, cN = (n, d = 0) => {
|
||||
let s = " ".repeat(d);
|
||||
if (n.nodeType == 3) {
|
||||
let t = n.textContent;
|
||||
return t.trim() ? `${s}"${esc(t)}"` : "";
|
||||
}
|
||||
if (n.nodeType == 1) {
|
||||
let t = n.tagName.toLowerCase(), p = bP(n), c = [...n.childNodes].map((i) => cN(i, d + 1)).filter(Boolean);
|
||||
if (!c.length)
|
||||
return `${s}${t}(${p})`;
|
||||
if (c.length == 1 && !c[0].includes(`
|
||||
`))
|
||||
return `${s}${t}(${p ? p + ", " : ""}${c[0].trim()})`;
|
||||
return `${s}${t}(${p ? p + ", " : ""}[
|
||||
${c.join(`,
|
||||
`)}
|
||||
${s}])`;
|
||||
}
|
||||
return "";
|
||||
}, r = [...new DOMParser().parseFromString(h, "text/html").body.childNodes].map((n) => cN(n)).filter(Boolean);
|
||||
return r.length == 1 ? r[0].trim() : `[
|
||||
${r.join(`,
|
||||
`)}
|
||||
]`;
|
||||
}
|
||||
var converter = () => {
|
||||
const inH = $("");
|
||||
const setInH = (v) => inH(v);
|
||||
const outS = $("");
|
||||
const setOutS = (v) => outS(v);
|
||||
cnv = () => {
|
||||
try {
|
||||
setOutS(html2sigpro(inH()));
|
||||
} catch (e) {
|
||||
setOutS("Error: " + e.message);
|
||||
}
|
||||
}, txS = "width:100%;height:200px;padding:10px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px;box-sizing:border-box;resize:vertical", btS = "padding:8px 16px;border:none;border-radius:4px;cursor:pointer;margin-right:8px;font-size:14px";
|
||||
return div({ style: "max-width:900px;margin:20px auto;font-family:sans-serif" }, [
|
||||
h1("HTML → SigPro"),
|
||||
label({ style: "display:block;font-weight:700" }, "HTML:"),
|
||||
textarea({
|
||||
style: txS,
|
||||
placeholder: "HTML...",
|
||||
value: inH,
|
||||
oninput: (e) => {
|
||||
setInH(e.target.value);
|
||||
cnv();
|
||||
}
|
||||
}),
|
||||
div({ style: "margin:10px 0" }, [
|
||||
button({ style: btS + ";background:#3b82f6;color:#fff", onclick: cnv }, "Convert"),
|
||||
button({ style: btS + ";background:#d1d5db", onclick: () => {
|
||||
setInH("");
|
||||
setOutS("");
|
||||
} }, "Clear")
|
||||
]),
|
||||
div({ style: "display:flex;justify-content:space-between;align-items:center;margin-bottom:5px" }, [
|
||||
span({ style: "font-weight:700" }, "Out:"),
|
||||
button({ style: btS + ";background:#10b981;color:#fff", onclick: () => {
|
||||
navigator.clipboard.writeText(outS());
|
||||
alert("Copied!");
|
||||
} }, "Copy")
|
||||
]),
|
||||
textarea({ style: txS + ";background:#f9fafb", readonly: true, value: outS, placeholder: "Result..." })
|
||||
]);
|
||||
};
|
||||
window.html2sigpro = html2sigpro;
|
||||
window.converter = converter;
|
||||
})();
|
||||
11
docs/convert.md
Normal file
11
docs/convert.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# HTML to SigPro Converter
|
||||
|
||||
Convert your existing HTML markup directly into SigPro Tag Helper syntax. Paste your HTML in the left panel and get clean, ready-to-use SigPro code on the right.
|
||||
|
||||
## Usage
|
||||
|
||||
<div id="sigpro-converter"></div>
|
||||
|
||||
```js
|
||||
mount(window.converter, '#sigpro-converter');
|
||||
```
|
||||
@@ -51,7 +51,7 @@
|
||||
);
|
||||
codeBlocks.forEach((code) => {
|
||||
try {
|
||||
const scriptContent = `(function() { ${code.innerText} })();`;
|
||||
const scriptContent = `(function() { ${code.innerText} }).call(window);`;
|
||||
const runDemo = new Function(scriptContent);
|
||||
runDemo();
|
||||
} catch (err) {
|
||||
@@ -65,6 +65,7 @@
|
||||
</script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="./sigpro.js"></script>
|
||||
<script src="./convert.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"del": "bun pm cache rm && rm -f bun.lockb && rm -f bun.lock",
|
||||
"clean": "rm -rf dist",
|
||||
"prebuild": "npm run clean",
|
||||
"build:convert": "bun build ./src/convert.js --bundle --outfile=./docs/convert.js --format=iife",
|
||||
"build:iife": "bun build ./src/build_umd.js --bundle --outfile=./dist/sigpro.js --format=iife --global-name=sp",
|
||||
"build:iife:min": "bun build ./src/build_umd.js --bundle --outfile=./dist/sigpro.min.js --format=iife --global-name=sp --minify",
|
||||
"build:esm": "bun build ./src/sigpro.js --bundle --outfile=./dist/sigpro.esm.js --format=esm",
|
||||
@@ -52,7 +53,7 @@
|
||||
"build:utils": "bun build ./src/sigpro.utils.js --bundle --outfile=./dist/sigpro.utils.js --format=esm",
|
||||
"build:vite": "bun build ./src/sigpro.vite.js --bundle --outfile=./dist/sigpro.vite.js --format=esm --external:fs --external:path",
|
||||
"build:copy": "cp ./dist/sigpro.js ./docs/sigpro.js",
|
||||
"build": "bun run build:iife && bun run build:iife:min && bun run build:esm && bun run build:esm:min && bun run build:utils && bun run build:vite && bun run build:copy",
|
||||
"build": "bun run build:iife && bun run build:iife:min && bun run build:esm && bun run build:esm:min && bun run build:utils && bun run build:vite && bun run build:convert && bun run build:copy",
|
||||
"docs": "bun x serve docs"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
61
src/convert.js
Normal file
61
src/convert.js
Normal file
@@ -0,0 +1,61 @@
|
||||
const { $, div, h1, label, textarea, button, span } = window;
|
||||
|
||||
function html2sigpro(h) {
|
||||
const B = new Set(['allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'truespeed']),
|
||||
esc = v => v.replace(/"/g, '\\"'),
|
||||
bP = el => {
|
||||
let a = [...el.attributes].map(({ name: n, value: v }) =>
|
||||
/^on/i.test(n) ? `${n}: (e) => { ${v.replace(/\s+/g, ' ').trim()} }` :
|
||||
(B.has(n.toLowerCase()) && (!v || v == n)) ? `${n}: true` : `${n}: "${esc(v)}"`
|
||||
);
|
||||
return a.length ? `{ ${a.join(', ')} }` : '';
|
||||
},
|
||||
cN = (n, d = 0) => {
|
||||
let s = ' '.repeat(d);
|
||||
if (n.nodeType == 3) {
|
||||
let t = n.textContent;
|
||||
return t.trim() ? `${s}"${esc(t)}"` : '';
|
||||
}
|
||||
if (n.nodeType == 1) {
|
||||
let t = n.tagName.toLowerCase(), p = bP(n),
|
||||
c = [...n.childNodes].map(i => cN(i, d + 1)).filter(Boolean);
|
||||
if (!c.length) return `${s}${t}(${p})`;
|
||||
if (c.length == 1 && !c[0].includes('\n')) return `${s}${t}(${p ? p + ', ' : ''}${c[0].trim()})`;
|
||||
return `${s}${t}(${p ? p + ', ' : ''}[\n${c.join(',\n')}\n${s}])`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
r = [...new DOMParser().parseFromString(h, 'text/html').body.childNodes].map(n => cN(n)).filter(Boolean);
|
||||
return r.length == 1 ? r[0].trim() : `[\n${r.join(',\n')}\n]`;
|
||||
}
|
||||
|
||||
const converter = () => {
|
||||
const inH = $('');
|
||||
const setInH = (v) => inH(v);
|
||||
const outS = $('');
|
||||
const setOutS = (v) => outS(v);
|
||||
cnv = () => { try { setOutS(html2sigpro(inH())) } catch (e) { setOutS('Error: ' + e.message) } },
|
||||
txS = "width:100%;height:200px;padding:10px;border:1px solid #ccc;border-radius:4px;font-family:monospace;font-size:14px;box-sizing:border-box;resize:vertical",
|
||||
btS = "padding:8px 16px;border:none;border-radius:4px;cursor:pointer;margin-right:8px;font-size:14px";
|
||||
|
||||
return div({ style: "max-width:900px;margin:20px auto;font-family:sans-serif" }, [
|
||||
h1("HTML → SigPro"),
|
||||
label({ style: "display:block;font-weight:700" }, "HTML:"),
|
||||
textarea({
|
||||
style: txS, placeholder: "HTML...", value: inH,
|
||||
oninput: e => { setInH(e.target.value); cnv() }
|
||||
}),
|
||||
div({ style: "margin:10px 0" }, [
|
||||
button({ style: btS + ";background:#3b82f6;color:#fff", onclick: cnv }, "Convert"),
|
||||
button({ style: btS + ";background:#d1d5db", onclick: () => { setInH(''); setOutS('') } }, "Clear")
|
||||
]),
|
||||
div({ style: "display:flex;justify-content:space-between;align-items:center;margin-bottom:5px" }, [
|
||||
span({ style: "font-weight:700" }, "Out:"),
|
||||
button({ style: btS + ";background:#10b981;color:#fff", onclick: () => { navigator.clipboard.writeText(outS()); alert('Copied!') } }, "Copy")
|
||||
]),
|
||||
textarea({ style: txS + ";background:#f9fafb", readonly: true, value: outS, placeholder: "Result..." })
|
||||
]);
|
||||
}
|
||||
|
||||
window.html2sigpro = html2sigpro;
|
||||
window.converter = converter;
|
||||
Reference in New Issue
Block a user