Merge branch 'worktree-macros-essays' into macros
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6m51s

This commit is contained in:
2026-03-04 15:27:46 +00:00
5 changed files with 373 additions and 143 deletions

View File

@@ -331,6 +331,7 @@
PRIMITIVES["last"] = function (c) { return c && c.length > 0 ? c[c.length - 1] : NIL; };
PRIMITIVES["rest"] = function (c) { return c ? c.slice(1) : []; };
PRIMITIVES["nth"] = function (c, n) { return c && n < c.length ? c[n] : NIL; };
PRIMITIVES["slice"] = function (c, start, end) { return c ? (end !== undefined && end !== NIL ? c.slice(start, end) : c.slice(start)) : c; };
PRIMITIVES["cons"] = function (x, c) { return [x].concat(c || []); };
PRIMITIVES["append"] = function (c, x) { return (c || []).concat([x]); };
PRIMITIVES["keys"] = function (d) { return Object.keys(d || {}); };
@@ -351,6 +352,57 @@
for (var i = a; step > 0 ? i < b : i > b; i += step) r.push(i);
return r;
};
PRIMITIVES["dissoc"] = function (d) {
var out = {}; for (var k in d) out[k] = d[k];
for (var i = 1; i < arguments.length; i++) delete out[arguments[i]];
return out;
};
PRIMITIVES["into"] = function (target, src) {
if (Array.isArray(target)) return target.concat(src || []);
var out = {}; for (var k in target) out[k] = target[k]; for (var k2 in src) out[k2] = src[k2]; return out;
};
// String operations
PRIMITIVES["replace"] = function (s, from, to) { return s ? String(s).split(from).join(to) : ""; };
PRIMITIVES["upper"] = function (s) { return s ? String(s).toUpperCase() : ""; };
PRIMITIVES["lower"] = function (s) { return s ? String(s).toLowerCase() : ""; };
PRIMITIVES["trim"] = function (s) { return s ? String(s).trim() : ""; };
PRIMITIVES["starts-with?"] = function (s, pfx) { return s ? String(s).indexOf(pfx) === 0 : false; };
PRIMITIVES["ends-with?"] = function (s, sfx) { var str = String(s || ""); return str.indexOf(sfx, str.length - sfx.length) !== -1; };
PRIMITIVES["escape"] = function (s) {
if (!s) return "";
return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
};
PRIMITIVES["strip-tags"] = function (s) { return s ? String(s).replace(/<[^>]*>/g, "") : ""; };
PRIMITIVES["split"] = function (s, sep) { return s ? String(s).split(sep) : []; };
PRIMITIVES["join"] = function (lst, sep) { return (lst || []).join(sep !== undefined ? sep : ""); };
PRIMITIVES["pluralize"] = function (n, singular, plural) { return n === 1 ? singular : (plural || singular + "s"); };
// Numeric
PRIMITIVES["clamp"] = function (val, lo, hi) { return Math.max(lo, Math.min(hi, val)); };
PRIMITIVES["parse-int"] = function (s, def) { var n = parseInt(s, 10); return isNaN(n) ? (def !== undefined ? def : 0) : n; };
PRIMITIVES["format-decimal"] = function (n, places) { return Number(n || 0).toFixed(places !== undefined ? places : 2); };
// Date formatting (basic)
PRIMITIVES["format-date"] = function (s, fmt) {
if (!s) return "";
try {
var d = new Date(s);
if (isNaN(d.getTime())) return String(s);
// Basic strftime-like: %Y %m %d %H %M %B %b %-d
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var short_months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
return fmt.replace(/%-d/g, d.getDate()).replace(/%d/g, ("0"+d.getDate()).slice(-2))
.replace(/%B/g, months[d.getMonth()]).replace(/%b/g, short_months[d.getMonth()])
.replace(/%Y/g, d.getFullYear()).replace(/%m/g, ("0"+(d.getMonth()+1)).slice(-2))
.replace(/%H/g, ("0"+d.getHours()).slice(-2)).replace(/%M/g, ("0"+d.getMinutes()).slice(-2));
} catch (e) { return String(s); }
};
PRIMITIVES["parse-datetime"] = function (s) { return s ? String(s) : NIL; };
PRIMITIVES["split-ids"] = function (s) {
if (!s) return [];
return String(s).split(",").map(function(x) { return x.trim(); }).filter(function(x) { return x; });
};
// --- CSSX Style Dictionary + Resolver ---