URI Slug function composition
Partial Application + Composition by reduceRight
by AntowaKartowa
HTML
<div class="container">
<div class="input">
<input type="text" name="text-for-slug" id="field">
<button id="generate">Получить slug</button>
</div>
<div id="result"></div>
</div>
CSS
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0;
width: 100vw;
height: 100vh;
}
.container {
position: relative;
}
.input {
text-align: center;
}
#result {
margin: 10px 0;
font-style: 14px;
line-height: 21px;
height: 21px;
}
JavaScript
const partial = (fn, ...args) => fn.length > args.length ? partial.bind(null, fn, ...args) : fn(...args);
const compose = (...fns) => x => fns.reduceRight((val, fn) => fn(val), x);
const partialJoin = partial((str, arr) => arr.join(str));
const partialSplit = partial((splitBy, str) => str.split(splitBy));
const toLowerCase = str => str.toLowerCase();
const trim = str => str.trim();
const translitLower = function(text) {
text = text
.replace(/\u042A/g, '')
.replace(/\u0451/g, 'yo')
.replace(/\u0439/g, 'i')
.replace(/\u0446/g, 'ts')
.replace(/\u0443/g, 'u')
.replace(/\u043A/g, 'k')
.replace(/\u0435/g, 'e')
.replace(/\u043D/g, 'n')
.replace(/\u0433/g, 'g')
.replace(/\u0448/g, 'sh')
.replace(/\u0449/g, 'sch')
.replace(/\u0437/g, 'z')
.replace(/\u0445/g, 'h')
.replace(/\u044A/g, "'")
.replace(/\u0410/g, 'a')
.replace(/\u0444/g, 'f')
.replace(/\u044B/g, 'i')
.replace(/\u0432/g, 'v')
.replace(/\u0430/g, 'a')
.replace(/\u043F/g, 'p')
.replace(/\u0440/g, 'r')
.replace(/\u043E/g, 'o')
.replace(/\u043B/g, 'l')
.replace(/\u0434/g, 'd')
.replace(/\u0436/g, 'zh')
.replace(/\u044D/g, 'e')
.replace(/\u042C/g, "'")
.replace(/\u044F/g, 'ya')
.replace(/\u0447/g, 'ch')
.replace(/\u0441/g, 's')
.replace(/\u043C/g, 'm')
.replace(/\u0438/g, 'i')
.replace(/\u0442/g, 't')
.replace(/\u044C/g, "'")
.replace(/\u0431/g, 'b')
.replace(/\u044E/g, 'yu');
return text;
};
const toSlug = compose(
encodeURIComponent,
partialJoin('-'),
partialSplit(' '),
translitLower,
toLowerCase,
trim
);
// ---
generate.onclick = () => result.innerText = toSlug(field.value);