[add] client
Christian Fraß authored 3 years ago
|
5) <info@greenscale.de>
6)
7) »bacterio-plankton:string« is free software: you can redistribute it and/or modify
8) it under the terms of the GNU Lesser General Public License as published by
9) the Free Software Foundation, either version 3 of the License, or
10) (at your option) any later version.
11)
12) »bacterio-plankton:string« is distributed in the hope that it will be useful,
13) but WITHOUT ANY WARRANTY; without even the implied warranty of
14) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15) GNU Lesser General Public License for more details.
16)
17) You should have received a copy of the GNU Lesser General Public License
18) along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
19) */
20) var plain_text_to_html = function (text) {
21) var ret = text;
22) ret = ret.replace(/ /g, " "); // convert multiple whitespace to forced ones
23) ret = ret.split("\n").join("<br/>");
24) return ret;
25) };
26) /**
27) * @desc makes a valid
28) */
29) var format_sentence = function (str, rtl, caseSense) {
30) if (rtl === void 0) { rtl = false; }
31) if (caseSense === void 0) { caseSense = true; }
32) if (str === "") {
33) return str;
34) }
35) else {
36) var marks = {
37) ".": true,
38) "?": true,
39) "!": true
40) };
41) var default_mark = ".";
42) var ret = str.split("");
43) if (!rtl) {
44) ret[0] = ret[0].toLocaleUpperCase();
45) if (!(ret[ret.length - 1] in marks)) {
46) ret.push(default_mark);
47) }
48) }
49) else {
50) ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase();
51) if (!(ret[0] in marks)) {
52) ret.unshift(default_mark);
53) }
54) }
55) return ret.join("");
56) }
57) };
58) var fill_string_template = function (template_string, object, fabric, delimiter, default_string, sloppy) {
59) if (fabric === void 0) { fabric = function (object, key) { return object[key]; }; }
60) if (delimiter === void 0) { delimiter = "%"; }
61) if (default_string === void 0) { default_string = null; }
62) function get_tags(str) {
63) var r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi");
64) return ((str.match(r) || []).map(function (e) {
65) return e.slice(delimiter.length, e.length - delimiter.length);
66) }));
67) }
68) function replace_tag(str, tag, value) {
69) var r = new RegExp(delimiter + tag + delimiter, "gi");
70) return str.replace(r, value);
71) }
72) function replace_tags(str, obj) {
73) return (get_tags(str).reduce(function (ret, key) {
74) var value = "";
75) try {
76) value = fabric(obj, key);
77) if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) {
78) value = default_string;
79) }
80) }
81) catch (e) {
82) console.warn("invalid placeholder " + key);
83) value = default_string;
84) }
85) return replace_tag(ret, key, value);
86) }, str));
87) }
88) return replace_tags(template_string, object);
89) };
90) var make_string_template = function (_template, _fabrics) {
91) if (_fabrics === void 0) { _fabrics = {}; }
92) function replace_tag(str, tag, value) {
93) var r = new RegExp("%" + tag + "%", "gi");
94) return str.replace(r, value);
95) }
96) function replace_tags(str, obj) {
97) return (Object.keys(obj).reduce(function (ret, key) {
98) return replace_tag(ret, key, _fabrics[key] || obj[key]);
99) }, str));
100) }
101) return (function (tags) {
102) return replace_tags(_template, tags);
103) });
104) };
105) var make_eml_header = (function () {
106) var _template = "";
107) _template += "From: %from%\n";
108) _template += "To: %recipient%\n";
109) _template += "Subject: %subject%\n";
110) _template += "X-Mailer: greenscale-plankton.emlgen\n";
111) return make_string_template(_template);
112) })();
113) var make_eml_body = (function () {
114) var exports = {};
115) exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n");
116) // very basic implementation
117) // parts = [{contenttype:"text/html; charset=UTF-8", body: "<h1>foo</h1>" }, {...}]
118) exports["body_boundrary"] = function (parts, boundrary) {
119) var _template = "";
120) _template += "--%boundrary%\n";
121) _template += "Content-Type: %contenttype%\n\n%body%\n\n";
122) //_template += "--%boundrary%--\n\n";
123) var maker = make_string_template(_template);
124) return (parts.reduce(function (prev, curr) {
125) curr.boundrary = boundrary;
126) return [prev, maker(curr)].join("");
127) }, ""));
128) };
129) // body must be base64 encoded!
130) exports["attachment_boundrary"] = function (parts, boundrary) {
131) var _template = "";
132) _template += "--%boundrary%\n";
133) _template += "Content-Type: %contenttype%\n";
134) _template += "Content-Transfer-Encoding: base64\n";
135) _template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n";
136) _template += "%body%\n\n";
137) //_template += "--%boundrary%--\n\n";
138) var maker = make_string_template(_template);
139) return (parts.reduce(function (prev, curr) {
140) curr.boundrary = boundrary;
141) if (curr.disposition === void 0)
142) curr.disposition = "inline";
143) return [prev, maker(curr)].join("");
144) }, ""));
145) };
146) exports["gen_boundrary"] = function () {
147) return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
148) var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
149) return v.toString(16);
150) }));
151) };
152) // simple implementation without alternatives (old rfc)
153) exports["complete_boundrary"] = function (bodyparts, attachments) {
154) var ret = "";
155) var boundrary = exports["gen_boundrary"]();
156) ret += exports["body_boundrary"](bodyparts, boundrary);
157) ret += exports["attachment_boundrary"](attachments, boundrary);
158) ret += "--" + boundrary + "--\n\nINVISIBLE!!!!";
159) return (exports["simple_body"]({
160) "contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]),
161) "body": ret
162) }));
163) };
164) return exports;
165) })();
166) /*
167) This file is part of »bacterio-plankton:string«.
168)
|
[add] client
Christian Fraß authored 3 years ago
|
170) <info@greenscale.de>
171)
172) »bacterio-plankton:string« is free software: you can redistribute it and/or modify
173) it under the terms of the GNU Lesser General Public License as published by
174) the Free Software Foundation, either version 3 of the License, or
175) (at your option) any later version.
176)
177) »bacterio-plankton:string« is distributed in the hope that it will be useful,
178) but WITHOUT ANY WARRANTY; without even the implied warranty of
179) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
180) GNU Lesser General Public License for more details.
181)
182) You should have received a copy of the GNU Lesser General Public License
183) along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
184) */
185) var lib_string;
186) (function (lib_string) {
187) /**
188) * @author fenris
189) */
190) var hexdigits = 4;
191) /**
192) * @author fenris
193) */
194) var index_max = (1 << (4 * hexdigits));
195) /**
196) * @author fenris
197) */
198) var index_is = 0;
199) /**
200) * @author neuc,frac
201) */
202) function empty(str) {
203) return (str.trim() === "");
204) }
205) lib_string.empty = empty;
206) /**
207) * @desc returns a unique string
208) * @param {string} prefix an optional prefix for the generated string
209) * @return {string}
210) * @author fenris
211) */
212) function generate(prefix) {
213) if (prefix === void 0) { prefix = "string_"; }
214) if (index_is > index_max) {
215) throw (new Error("[string_generate] out of valid indices"));
216) }
217) else {
218) return lib_string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]);
219) }
220) }
221) lib_string.generate = generate;
222) /**
223) * @desc splits a string, but returns an empty list, if the string is empty
224) * @param {string} chain
225) * @param {string} separator
226) * @return {Array<string>}
227) * @author fenris
228) */
229) function split(chain, separator) {
230) if (separator === void 0) { separator = " "; }
231) if (chain.length == 0) {
232) return [];
233) }
234) else {
235) return chain.split(separator);
236) }
237) }
238) lib_string.split = split;
239) /**
240) * @author neu3no
241) */
242) function explode(str, needle, max) {
243) var temp = str.split(needle);
244) var right = temp.splice(max - 1);
245) temp.push(right.join(needle));
246) return temp;
247) }
248) lib_string.explode = explode;
249) /**
250) * @desc concats a given word with itself n times
251) * @param {string} word
252) * @param {int}
253) * @return {string}
254) * @author fenris
255) */
256) function repeat(word, count) {
257) // return ((count == 0) ? "" : (word + repeat(word, count-1)));
258) var result = "";
259) for (var n = 0; n < count; n += 1) {
260) result += word;
261) }
262) return result;
263) }
264) lib_string.repeat = repeat;
265) /**
266) * @desc lengthens a string by repeatedly appending or prepending another string
267) * @param {string} word the string to pad
268) * @param {int} length the length, which the result shall have
269) * @param {string} symbol the string, which will be added (multiple times)
270) * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false
271) * @return {string} the padded string
272) * @author fenris
273) */
274) function pad(word, length, symbol, mode) {
275) if (symbol === void 0) { symbol = " "; }
276) if (mode === void 0) { mode = "append"; }
277) switch (mode) {
278) case "prepend": {
279) // insert symbols only at the beginning
280) while (word.length < length)
281) word = symbol + word;
282) return word.substring(word.length - length);
283) break;
284) }
285) case "append": {
286) // insert symbols only at the end
287) while (word.length < length)
288) word = word + symbol;
289) return word.substring(0, length);
290) break;
291) }
292) case "widen": {
293) // insert symbols at both sides
294) var left = (((length - word.length) & 1) === 0);
295) while (word.length < length) {
296) word = (left
297) ? (symbol + word)
298) : (word + symbol));
299) left = (!left);
300) }
301) return word.substring(0, length);
302) break;
303) }
304) default: {
305) var message = ("unhandled mode '" + mode + "'");
306) console.warn(message);
307) return word;
308) break;
309) }
310) }
311) }
312) lib_string.pad = pad;
313) /**
314) * @desc checks if a given string conttains a certain substring
315) * @param {string} string
316) * @param {string} part
317) * @return {boolean}
318) * @author fenris
319) */
320) function contains(chain, part) {
321) if (typeof (chain) !== "string") {
322) return false;
323) }
324) return (chain.indexOf(part) >= 0);
325) }
326) lib_string.contains = contains;
327) /**
328) * @desc checks if a given string starts with a certain substring
329) * @param {string} string
330) * @param {string} part
331) * @return {boolean}
332) * @author fenris
333) */
334) function startsWith(chain, part) {
335) if (typeof (chain) !== "string") {
336) return false;
337) }
338) // return (string.indexOf(part) === 0);
339) return ((function (m, n) {
340) if (n === 0) {
341) return true;
342) }
343) else {
344) if (m === 0) {
345) return false;
346) }
347) else {
348) return ((chain[0] == part[0])
349) &&
350) startsWith(chain.substring(1), part.substring(1)));
351) }
352) }
353) })(chain.length, part.length));
354) }
355) lib_string.startsWith = startsWith;
356) /**
357) * @desc checks if a given string ends with a certain substring
358) * @param {string} string
359) * @param {string} part
360) * @return {boolean}
361) * @author fenris
362) */
363) function endsWith(chain, part) {
364) if (typeof (chain) !== "string") {
365) return false;
366) }
367) // return (string.lastIndexOf(part) === string.length-part.length);
368) return ((function (m, n) {
369) if (n === 0) {
370) return true;
371) }
372) else {
373) if (m === 0) {
374) return false;
375) }
376) else {
377) // console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1]));
378) return ((chain[m - 1] === part[n - 1])
379) &&
380) endsWith(chain.substring(0, m - 1), part.substring(0, n - 1)));
381) }
382) }
383) })(chain.length, part.length));
384) }
385) lib_string.endsWith = endsWith;
386) /**
387) * @desc count the occourrences of a string in a string
388) * @param string haystack_string the string wich should be examined
389) * @param string needle_string the string which should be counted
390) * @author neuc
391) */
392) function count_occourrences(haystack_string, needle_string, check_escape) {
393) var cnt = 0;
394) var pos = -1;
395) do {
396) pos = haystack_string.indexOf(needle_string, pos + 1);
397) if ((!check_escape) || (haystack_string[pos - 1] != "\\")) {
398) cnt++;
399) }
400) } while (pos >= 0);
401) return (cnt - 1);
402) }
403) lib_string.count_occourrences = count_occourrences;
404) /**
405) * @desc replaces occurences of "${name}" in a string by the corresponding values of an argument object
406) * @author fenris
407) */
408) function coin(str, args) {
409) Object.keys(args).forEach(function (key) {
410) // old syntax
411) {
412) var value = args[key];
413) var regexp_argument = new RegExp("\\${" + key + "}");
414) str = str.replace(regexp_argument, value);
415) }
416) // new syntax
417) {
418) var value = args[key];
419) var regexp_argument = new RegExp("{{" + key + "}}");
420) str = str.replace(regexp_argument, value);
421) }
422) });
423) return str;
424) }
425) lib_string.coin = coin;
426) /**
427) * @author fenris
428) */
429) lib_string.stance = coin;
430) /**
431) * @author fenris
432) */
433) function cut(str, length, delimiter) {
434) if (delimiter === void 0) { delimiter = "…"; }
435) if (str.length <= length) {
436) return str;
437) }
438) else {
439) return (str.slice(0, length - delimiter.length) + delimiter);
440) }
441) }
442) lib_string.cut = cut;
443) })(lib_string || (lib_string = {}));
444) /*
445) This file is part of »bacterio-plankton:string«.
446)
|
[add] client
Christian Fraß authored 3 years ago
|
448) <info@greenscale.de>
449)
450) »bacterio-plankton:string« is free software: you can redistribute it and/or modify
451) it under the terms of the GNU Lesser General Public License as published by
452) the Free Software Foundation, either version 3 of the License, or
453) (at your option) any later version.
454)
455) »bacterio-plankton:string« is distributed in the hope that it will be useful,
456) but WITHOUT ANY WARRANTY; without even the implied warranty of
457) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
458) GNU Lesser General Public License for more details.
459)
460) You should have received a copy of the GNU Lesser General Public License
461) along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
462) */
463) var lib_string;
464) (function (lib_string) {
465) var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/;
466) var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g;
467) function split_format(format) {
468) var tmp = format.match(pattern);
469) if (tmp === null)
470) return null;
471) return {
472) 'flags': tmp[1].split(""),
473) 'width': Number(tmp[2]),
474) 'precision': tmp[3] === '' ? null : Number(tmp[3]),
475) 'specifier': tmp[4],
476) 'string': format
477) };
478) }
479) function make_err(format, arg, should) {
480) return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!");
481) }
482) function test_arg(format, arg, should) {
483) if (typeof arg !== should) {
484) console.warn(make_err(format, arg, should));
485) return false;
486) }
487) return true;
488) }
489) function string_fill(str, char, len, left) {
490) while (str.length < len) {
491) if (left) {
492) str += char;
493) }
494) else {
495) str = char + str;
496) }
497) }
498) return str;
499) }
500) /**
501) * the known_parameters are used to parse the different identifiers for the welln known syntax:
502) * flag width precision identifier
503) * %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn]
504) * flags:
505) * 0 - fill with '0' instead of ' ' if the string length < width
506) * # - not implemented
507) * - - left-justified -> fill on the right side to reach width
508) * + - force using '+' on positive numbers
509) * ' ' - add a single space before positive numbers
510) *
511) * identifiers
512) * %f, %F - interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the
513) * resulting string is too short, precision: cut more then given decimal places
514) * %d, %i, %u - interpret number as integer, decimal places will be cut. width: like float, precision:
515) * fill with '0' on right side until length given in precision is reached
516) * %e - interpret as float and write as scientifical number, width & precision like in float
517) * %E - same es %e but uppercase 'E'
518) * %g - use the shortest string of %f or %e
519) * %G - use the shortest string of %E or %E
520) * %s - simply print a string
521) * %o - print the given number in octal notation
522) * %x - print the given number in hex notation
523) * %X - same as %x but with uppercase characters
524) * %a - alias to %x
525) * %A - alias to %X
526) * %n - just print nothing
527) * @type {{}}
528) */
529) var known_params = {};
530) known_params["f"] = function (format, arg) {
531) if (!test_arg(format, arg, "number"))
532) return "Ø";
533) var tmp = Math.abs(arg);
534) var sign = (arg < 0) ? -1 : 1;
535) var tmp_result = null;
536) if (format.precision !== null) {
537) tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision);
538) var tmp_ = (tmp * sign).toString().split(".");
539) if (tmp_.length === 1)
540) tmp_.push("");
541) tmp_[1] = string_fill(tmp_[1], "0", format.precision, true);
542) tmp_result = tmp_.join(".");
543) }
544) else {
545) tmp_result = (sign * tmp).toString();
546) }
547) if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) {
548) tmp_result = " " + tmp;
549) }
550) else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) {
551) tmp_result = "+" + tmp;
552) }
553) tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0));
554) return tmp_result;
555) };
556) known_params["F"] = known_params["f"];
557) known_params["d"] = function (format, arg) {
558) if (!test_arg(format, arg, 'number'))
559) return 'Ø';
560) var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString();
561) if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) {
562) tmp = ' ' + tmp;
563) }
564) else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) {
565) tmp = '+' + tmp;
566) }
567) tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
568) tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false);
569) return tmp;
570) };
571) known_params["i"] = known_params["d"];
572) known_params["u"] = known_params["d"];
573) known_params["e"] = function (format, arg) {
574) if (!test_arg(format, arg, 'number'))
575) return 'Ø';
576) var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString();
577) if (format.flags.indexOf(' ') >= 0 && arg >= 0) {
578) tmp = ' ' + tmp;
579) }
580) else if (format.flags.indexOf('+') >= 0 && arg >= 0) {
581) tmp = '+' + tmp;
582) }
583) tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
584) return tmp;
585) };
586) known_params["E"] = function (format, arg) {
587) return known_params["e"](format, arg).toUpperCase();
588) };
589) known_params["g"] = function (format, arg) {
590) if (!test_arg(format, arg, 'number'))
591) return 'Ø';
592) var tmpf = known_params["f"](format, arg);
593) var tmpe = known_params["e"](format, arg);
594) if (tmpf.length < tmpe.length) {
595) return tmpf;
596) }
597) else {
598) return tmpe;
599) }
600) };
601) known_params["G"] = function (format, arg) {
602) return known_params["g"](format, arg).toUpperCase();
603) };
604) known_params["s"] = function (format, arg) {
605) if (!test_arg(format, arg, 'string'))
606) return 'o.O';
607) var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg;
608) tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
609) return tmp;
610) };
611) known_params["o"] = function (format, arg) {
612) if (!test_arg(format, arg, 'number'))
613) return 'Ø';
614) var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
615) return known_params["s"](format, tmp.toString(8));
616) };
617) known_params["x"] = function (format, arg) {
618) if (!test_arg(format, arg, 'number'))
619) return 'Ø';
620) var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
621) return known_params["s"](format, tmp.toString(16));
622) };
623) known_params["a"] = known_params["x"];
624) known_params["X"] = function (format, arg) {
625) if (!test_arg(format, arg, 'number'))
626) return 'Ø';
627) return known_params["x"](format, arg).toUpperCase();
628) };
629) known_params["A"] = known_params["X"];
630) known_params["c"] = function (format, arg) {
631) var tmp = "";
632) if (typeof arg === "number") {
633) tmp = String.fromCharCode(arg);
634) }
635) else if ((typeof arg === "string") && (arg.length === 1)) {
636) tmp = arg[0];
637) }
638) else {
639) console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!");
640) }
641) return known_params["s"](format, tmp);
642) };
643) known_params["n"] = function () {
644) return "";
645) };
646) var decompose = function (chain, regexp) {
647) var result = regexp.exec(chain);
648) if (result == null) {
649) return null;
650) }
651) else {
652) var front = chain.substring(0, result.index);
653) var back = chain.substring(result.index + result[0].length);
654) return { "front": front, "match": result[0], "back": back };
655) }
656) };
657) /**
658) * an implementation of c sprintf
659) * @param {string} string format string
660) * @param {array} args arguments which should be filled into
661) * @returns {string}
662) */
663) lib_string.sprintf = function (input, args, original) {
664) if (args === void 0) { args = []; }
665) if (original === void 0) { original = null; }
666) if (original == null)
667) original = input;
668) var components = decompose(input, pattern);
669) if (components == null) {
670) if (args.length > 0) {
671) console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args);
672) }
673) return input;
674) }
675) else {
676) var arg;
677) var rest;
678) if (args.length > 0) {
679) arg = args[0];
680) rest = args.slice(1);
681) }
682) else {
683) console.warn("[sprintf] out of arguments while formatting '" + original + "'");
684) arg = null;
685) rest = [];
686) return input;
687) }
688) var fmt = split_format(components["match"]);
689) return (components["front"]
690) + known_params[fmt.specifier](fmt, arg)
691) + lib_string.sprintf(components["back"], rest, original));
692) }
693) };
694) /**
695) * an implementation of c printf
696) * @param {string} string format string
697) * @param {array} args arguments which should be filled into
698) * @returns {string}
699) */
700) function printf(format, args) {
701) console.log(lib_string.sprintf(format, args));
702) }
703) lib_string.printf = printf;
704) })(lib_string || (lib_string = {}));
705) var sprintf = lib_string.sprintf;
706) var printf = lib_string.printf;
707) /*
708) This file is part of »bacterio-plankton:string«.
709)
|