Skip to content

Instantly share code, notes, and snippets.

@mscalora
mscalora / parse-emails-from-text.js
Created March 21, 2018 16:53
Parse emails from text
parseEmails: function (emailStr) {
// remove RFC-822 adornments & normalize delimiters
var rfc822Cleaner = /(?:"[^@"'<>]*?"|(?:^|\n| |,|;)(?:[^@"'<>])+?)\s*?<([-a-z0-9_.%+]+?@[-a-z0-9.]+?.[-a-z0-9]{2,63}?)>/gi,
exchangeCleaner = /"(?:[^@"()])*?\(([-a-z0-9_.%+]+?@[-a-z0-9.]+?.[-a-z0-9]{2,63})\)(?:[^@"()])*?"\s*?<\1>/gi,
cleanedStr = emailStr.replace(rfc822Cleaner, ' $1 ').replace(exchangeCleaner, ' $1 ').replace(/(\n|[;, ])+/g, ';'),
emailList = _.split(cleanedStr, ';');
var re = /(?:^|\s|\n|[;,<"'(])([-a-z0-9_.%+]+@[-a-z0-9.]+?.[-a-z0-9]{2,63})(?:^|\s|\n|[;,>"')])/gi,
emails = [],
dummy = emailStr.replace(re, function (match, email) { emails.push(email); return '[' + email + ']';});
@mscalora
mscalora / cmpdirs.py
Created February 18, 2018 22:07
Based on Andriy Makukha's script from https://askubuntu.com/questions/421712/comparing-the-contents-of-two-directories/996529#996529 with a third parameter of a skip/exclude regular expression
#!/usr/bin/env python3
import os, sys, re
skip = re.compile(sys.argv[3] if len(sys.argv) > 3 else '$.')
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
@mscalora
mscalora / geti
Created February 18, 2018 00:01
Case-insensitive get like lodash's _.get()
function geti (value, prop) {
if (_.isPlainObject(value)) {
if (_.isString(prop) && prop !== '') {
return geti(value, prop.split('.'));
} else if (_.isArray(prop) && prop.length) {
const key = _.toLower(prop.shift()),
val = Object.keys(value).reduce(function (a, k) {
if (a !== undefined) {
return a;
}
@mscalora
mscalora / humanizeDuration.php
Created January 9, 2018 12:25
Return a duration (in seconds) in a humanized string format like: "2 seconds" or "1 year"
function humanizeDuration ($secs) {
$secs = ($secs<1)? 1 : $secs;
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
@mscalora
mscalora / build-nano.md
Created October 28, 2017 13:33
Building nano editor from source recipe for mac and debian ubuntu mint

build nano

nano build dependencies

on a generic Debian distro

sudo apt-get install autoconf autopoint automake gettext git groff pkg-config texinfo gcc make libncursesw5-dev

on a mac

@mscalora
mscalora / stars.svg
Last active September 11, 2017 19:55
stars, lean & plump
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@mscalora
mscalora / mac-nano-build-setup
Created August 28, 2017 13:52
Steps to build nano on a modern macos system (in 2017)
##### Prerequisites
#
# * brew
# * xcode command line tools
#
### brew installs
brew install automake autoconf pkg-config gettext ncurses
### Add env vars - ~/.bashrc or ~/zshrc if you are a zsh user
<div id="twt-comments"></div>
<script>
document.querySelectorAll('#ArchiveList .posts a').forEach(function (a) {
var span = document.createElement('span');
span.setAttribute('twt-comment-count', a.getAttribute('href'));
a.insertAdjacentHTML('beforeend', ' [');
a.insertAdjacentElement('beforeend', span);
a.insertAdjacentHTML('beforeend', ']');
});
h2 = document.querySelector('.main .date-header');
@mscalora
mscalora / svg-ribbon.html
Created August 11, 2017 17:29
Using svg to implement a ribbon button with css and an svg element
<!doctype html>
<html>
<head>
<link rel="shortcut icon" href="//scalora.net/ticon.png">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
@mscalora
mscalora / htmlEncode.js
Created August 10, 2017 18:03
ES6ish htmlEncode
const escapeChars = { '¢' : 'cent', '£' : 'pound', '¥' : 'yen', '€': 'euro', '©' : 'copy', '®' : 'reg', '<' : 'lt', '>' : 'gt', '"' : 'quot', '&' : 'amp', '\'' : '#39'},
htmlEncode = function (s) {
return s.replace(/[\u00A0-\u9999<>\&'"]/gim, function (i) {
return `&${escapeChars[i] || '#' + i.charCodeAt(0)};`;
});
};