squint-cljs
Version:
<img src="./logo/logo.svg" width="100%">
185 lines (160 loc) • 4.14 kB
JavaScript
/*eslint no-unused-vars: ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_", "destructuredArrayIgnorePattern": "^_"}]*/
import { get, iterable, string_QMARK_ } from './core.js';
export function blank_QMARK_(s) {
if (s == null) return true;
// a non-string is not blank, like CLJS
if (typeof s !== 'string') return false;
if (s.length === 0) return true;
if (s.trimStart().length === 0) return true;
return false;
}
export function escape(s, cmap) {
let buffer = '';
const length = s.length;
for (let i = 0; i < length; i++) {
const ch = s.charAt(i);
const replacement = get(cmap, ch);
buffer += replacement != null ? String(replacement) : ch;
}
return buffer;
}
export function join(sep, coll) {
if (coll === undefined) {
coll = sep;
sep = '';
}
if (coll instanceof Array) {
return coll.join(sep);
}
let ret = '';
let addSep = false;
for (const o of iterable(coll)) {
if (addSep) ret += sep;
ret += o;
addSep = true;
}
return ret;
}
export function trim(s) {
return s.trim();
}
export function triml(s) {
return s.trimStart();
}
export function trimr(s) {
return s.trimEnd();
}
function discardTrailingIfNeeded(limit, v) {
if ((limit == null || limit === 0) && v.length > 1) {
for (;;)
if (v[v.length - 1] === "") {
v.pop();
} else break;
}
return v;
}
export function split(s, re, limit) {
// Clojure's limit caps the number of splits and keeps the remainder, unlike
// JS String.prototype.split which truncates the result. Only a positive
// limit changes behaviour; <1 (or unset) does a full split, with trailing
// empties discarded when the limit is 0 / unset.
if (limit == null || limit < 1) {
return discardTrailingIfNeeded(limit, s.split(re));
}
const parts = [];
let rem = s;
while (limit > 1) {
const m = rem.match(re);
if (m == null) break;
const idx = m.index;
parts.push(rem.substring(0, idx));
rem = rem.substring(idx + m[0].length);
limit--;
}
parts.push(rem);
return parts;
}
export function starts_with_QMARK_(s, substr) {
return s.startsWith(substr);
}
export function ends_with_QMARK_(s, substr) {
return s.endsWith(substr);
}
const escapeRegex = function(s) {
return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').replace(/\x08/g, '\\x08');
};
const replaceAll = function(s, re, replacement) {
var flags = "g";
if (re.ignoreCase) {
flags += "i";
}
if (re.multiline) {
flags += "m";
}
if (re.unicode) {
flags += "u";
}
const r = new RegExp(re.source, flags);
return s.replace(r, replacement);
};
const replaceWith = function(f) {
return (...args) => {
const [matches, _, __] = args;
if (matches.length == 1) {
return f(matches[0]);
} else {
return f(matches);
}
};
};
export function replace(s, match, replacement) {
if (string_QMARK_(match)) {
return s.replace(new RegExp(escapeRegex(match), "g"), replacement);
}
if (match instanceof RegExp) {
if (string_QMARK_(replacement)) {
return replaceAll(s, match, replacement);
}
else {
return replaceAll(s, match, replaceWith(replacement));
}
}
throw `Invalid match arg: $match`;
}
export function replace_first(s, match, replacement) {
return s.replace(match, replacement);
}
export function split_lines(s) {
return split(s, /\n|\r\n/);
}
export function index_of(s, value, from) {
const res = s.indexOf(value, from);
if (res < 0) {
return null;
}
return res;
}
export function last_index_of(s, value, from) {
const res = s.lastIndexOf(value, from);
if (res < 0) {
return null;
}
return res;
}
export function lower_case(s) {
return s.toLowerCase();
}
export function upper_case(s) {
return s.toUpperCase();
}
export function capitalize(s) {
if (s.length === 0) return s;
if (s.length === 1) return s.toUpperCase();
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
}
export function reverse(s) {
return [...s].reverse().join('');
}
export function includes_QMARK_(s, substr) {
return s.indexOf(substr) != -1;
}