A index.html => index.html +114 -0
@@ 0,0 1,114 @@
+<!doctype html>
+<head>
+<meta charset='utf-8' />
+<title>The TPL License</title>
+<link rel=preload href='/templates/list.txt' />
+<!-- TODO: stylesheet -->
+</head>
+<body>
+<main>
+ <h1>The <u>T</u>erse <u>P</u>ublic <u>L</u>icense Family</h1>
+ <p>A family of minimal licenses for artists and developers, without
+ the sheer size of the more thorough licenses. If you forsee
+ yourself going to court, maybe pick something more robust. If you
+ just want something simple for a small project, this may well be
+ for you.</p>
+ <p>Feel free to <a href="https://amehut.dev/~aleteoryx/tpl">suggest
+ improvements</a>.</p>
+ <h2>Generation Wizard</h2>
+ <section id=wizard>
+ <label for=license_sel>License:</label> <select id=license_sel></select><br/>
+ <input type=checkbox id=include_header checked /> <label for=include_header>Include header?</label><br/>
+ <div id=license_opts></div>
+ <textarea readonly id=license_text cols=74 rows=10></textarea>
+ </section>
+</main>
+<script>(async function() {
+
+async function parse_and_fetch_parts(metadata) {
+ let format = [];
+ for (const part of metadata.format) {
+ if (!part.includes(":")) {
+ format.push({file: part});
+ continue;
+ }
+ let [name, file] = part.split(":", 2);
+ if (name[0] == "+") {
+ format.push({file, optional: name.slice(1), default: true});
+ continue;
+ } else {
+ format.push({file, optional: name, default: false})
+ }
+ }
+
+ format = await Promise.all(
+ format.map(x =>
+ fetch(`/templates/${x.file}`).then(r => r.text())
+ .then(c => ({...x, contents: c}))));
+
+ metadata.format = format;
+ return metadata;
+}
+
+const metafiles = await fetch("/templates/list.txt")
+ .then(r => r.text())
+ .then(x =>
+ x.split("\n").filter(x => x != "")
+ .map(x => `/templates/${x.trim()}/meta.json`));
+
+const metadata = await Promise.all(
+ metafiles.map(x => fetch(x).then(r => r.json())));
+
+const templates = Object.fromEntries(
+ (await Promise.all(
+ metadata.map(parse_and_fetch_parts)))
+ .map(x => [x.name, x]));
+
+async function template_changed() {
+ license_opts.innerText = "";
+ for (const part of templates[license_sel.value].format) {
+ if (part.optional) {
+ const box = document.createElement("input");
+ box.type = "checkbox";
+ box.id = part.optional.replace(" ", "-");
+ box.checked = part.default;
+ const label = document.createElement("label");
+ label.for = box.id;
+ label.innerText = part.optional;
+ const br = document.createElement("br");
+ license_opts.append(box, " ", label, br);
+ }
+ }
+ params_changed();
+}
+async function params_changed() {
+ template = templates[license_sel.value];
+ license_text.value = "";
+ if (include_header.checked) {
+ license_text.value +=
+ `-- TPL ${template.name} v${template.version}\n`;
+ license_text.value += "-- <https://amehut.dev/~aleteoryx/tpl>\n";
+ license_text.value += '-'.repeat(72);
+ }
+
+ for (const part of template.format) {
+ if (part.optional && !(document.getElementById(part.optional.replace(" ", "-")).checked)) {
+ continue;
+ }
+ license_text.value += "\n\n";
+ license_text.value += part.contents.trim();
+ }
+}
+
+for (const template in templates) {
+ const opt = document.createElement("option");
+ opt.innerText = template;
+ license_sel.append(opt);
+}
+license_sel.addEventListener("change", template_changed);
+include_header.addEventListener("change", params_changed);
+
+template_changed();
+
+})()</script>
+</body>
M templates/PD/meta.json => templates/PD/meta.json +2 -1
@@ 1,5 1,6 @@
{
- "name": "Public Domain",
+ "name": "Public Domain Dedication",
+ "description": "A no-frills public domain dedication. Use this if you don't care who does what with your work, and just want it freely available.",
"version": "1.0",
"format": [
"/PD/main.txt",