-
Notifications
You must be signed in to change notification settings - Fork 0
/
typography.js
80 lines (63 loc) · 2.23 KB
/
typography.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { dom, article } from '/app/index.js';
// inspired by Typeset.js
// https://blot.im/typeset/
let replace = function(old, nu) {
if (nu instanceof Node)
old.parentNode.replaceChild(nu, old);
else if (typeof nu === 'string') {
var frag = document.createDocumentFragment();
let temp = document.createElement('div');
temp.innerHTML = nu;
let child;
while (child = temp.firstChild) {
frag.appendChild(child);
}
old.parentNode.replaceChild(frag, old);
}
};
let s = (klas, chr) => `<span class=${klas}>${chr}</span>`;
article.ready.then(() => {
let time = performance.now();
dom('p').map(el => {
let first = true;
dom.textNodes(el).map(n => {
let needsPush = (
n.textContent.indexOf('‘') >= 0 ||
n.textContent.indexOf('“') >= 0
);
if (needsPush) {
let html = n.textContent;
html = html.replace(/(^|\s)(“‘|‘“)/g, (m, p1, p2, offset, string) => {
if (first && /^\s*$/.test(string.slice(0, offset)))
return s('pull-triple', p2);
else if (/\s/.test(string.slice(offset - 1, offset)))
return s('push-triple','') + ' ' + s('pull-double', p2);
});
html = html.replace(/(^|\s)“/g, (m, p1, offset, string) => {
if (first && /^\s*$/.test(string.slice(0, offset)))
return s('pull-double','“');
else
return s('push-double','') + ' ' + s('pull-double','“')
});
html = html.replace(/(^|\s)‘/g, (m, p1, offset, string) => {
if (first && /^\s*$/.test(string.slice(0, offset)))
return s('pull-single','‘');
else
return s('push-single','') + ' ' + s('pull-single','‘')
});
replace(n, html);
}
if (/[^\s]/.test(n.textContent))
first = false;
});
// adding non-breaking space between two last words to prevent
// single-word lines (widowed words)
dom.textNodes(el).reverse().find(n => {
if (/[^\s]\s[^\s]/.test(n.textContent)) {
n.textContent = n.textContent.replace(/(.*)\s([^\s])/, '$1\u00A0$2');
return true;
}
});
});
// console.log(`time to run: ${ Math.round(performance.now() - time) }ms`);
});