emoji-line-break
Version:
Split emoji text into multiple lines.
212 lines (172 loc) • 7.04 kB
HTML
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Download your custom file</title>
<meta name="description" content="">
<meta name="keywords" content="">
<style type="text/css">
textarea {
width: 200px;
height: 200px;
}
button {
height: 36px;
min-width: 64px;
padding: 0 16px;
}
a {
margin-top: 20px;
width: fit-content;
flex: 1 0 auto;
display: flex;
align-items: center;
justify-content: center;
padding: 0 23px;
height: 52px;
font-size: 18px;
border-radius: 4px;
box-shadow:0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
background-color: #607d8b ;
border-color: #607d8b ;
color: #fff;
font-weight: 700;
}
</style>
</head>
<body>
</body>
<script type="text/javascript">
let is_mobile = (() => {
if (typeof window !== 'undefined') {
/** 浏览器判断 */
return /Mobile/img.test(window.navigator.appVersion) && !/win|mac/img.test(window.navigator.platform);
} else if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
/** 微信小程序判断 */
return /android|ios/img.test(wx.getSystemInfoSync().platform);
}
return false;
})();
function generateDownloadLink(filename, text, lang) {
let element = document.createElement('a');
let fileFix = FILETYPE === 'esm' ? '"use strict";export default ' : '"use strict";module.exports = ';
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileFix + text));
filename = filename.replace(/.js/, (p1) => {
let prefix = '';
prefix += (is_mobile ? '.mobile' : '');
prefix += '.' + lang;
prefix += (FILETYPE === 'esm' ? '.esm' : '.common');
return prefix + p1;
})
element.setAttribute('download', filename);
element.innerText = 'Download ' + filename;
document.body.appendChild(element);
}
function generateExactRegex(set) {
let exactRegex = [];
let escape = /[\-\\\[\]$^]/;
for (let item in set) {
let regExStr = set[item].reduce((p1, p2) => {
escape.test(p2) && (p2 = '\\' + p2);
return p1 + p2
}, '')
let result = {}
result[KMAP.ratio] = +item;
result[KMAP.regex] = `[${regExStr}]`;
exactRegex.push(result);
}
return exactRegex
}
const BASE = {
letter: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
numbers: [0,1,2,3,4,5,6,7,8,9],
punctuation: ['`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '+', '/', '<', '>', ':', '?', '\\', '[', ']', '{', '}', '|','\'', '"', ';', ',', '.', '~', '_', ' ', 'ː']
}
const BASECHAR = {
en: {
serif: 'ː',
'sans-serif': '0',
Arial: 'a',
cursive: 'a'
},
zh: {
serif: '爱',
'sans-serif': '爱',
Arial: '爱',
cursive: '爱'
},
emoji: '😘'
}
const FILETYPE = 'commonjs'; // esm, commonjs
const PRECISION = 3;
let baseFontSize= '16px';
let fontWeight= ['lighter', 'normal', 'bold'];
let fontFamily= ['serif', 'sans-serif', 'Arial', 'cursive'];
/** /src/keymap.js */
const KMAP = {
ratio: 'T',
regex: 'R',
fontSize: 'Z',
baseWidth: 'W',
offset: 'O',
emojiRatio: 'J',
lighter: 'L',
normal: 'N',
bold: 'B',
serif: 'S',
Arial: 'A',
cursive: 'C',
'sans-serif': 'I'
}
function generateUnitBase(lang) {
let ctx = document.createElement('canvas').getContext("2d");
let ctxOffset = document.createElement('canvas').getContext("2d");
let measureChar = '';
let result = {};
fontWeight.forEach(fw => {
fontFamily.forEach(fm => {
measureChar = BASECHAR[lang][fm];
ctx.font = `${fw} ${baseFontSize} ${fm}`
ctxOffset.font = `${fw} ${baseFontSize.replace(/\d+/, p1 => (+p1 + 1))} ${fm}`;
let baseW = ctx.measureText(measureChar).width;
!result[KMAP[fw]] && (result[KMAP[fw]] = {})
result[KMAP[fw]][KMAP[fm]] = {}
result[KMAP[fw]][KMAP[fm]][KMAP.fontSize] = baseFontSize;
result[KMAP[fw]][KMAP[fm]][KMAP.baseWidth] = +baseW.toFixed(PRECISION);
result[KMAP[fw]][KMAP[fm]][KMAP.offset] = +(ctxOffset.measureText(measureChar).width - baseW).toFixed(PRECISION);
result[KMAP[fw]][KMAP[fm]][KMAP.emojiRatio] = +(ctx.measureText(BASECHAR.emoji).width / baseW).toFixed(PRECISION);
})
})
console.log(`unit-base-${lang}:`, result)
generateDownloadLink('unit-base.js', JSON.stringify(result), lang)
}
function generateLangRegex(lang, extendChars) {
let ctx = document.createElement('canvas').getContext("2d");
let measureChar = '';
let result = {};
let amountChars = BASE.letter.concat(BASE.punctuation, BASE.numbers, BASE.letter.map(lt => lt.toUpperCase()), extendChars || []);
fontWeight.forEach(fw => {
fontFamily.forEach(fm => {
measureChar = BASECHAR[lang][fm];
ctx.font = `${fw} ${baseFontSize} ${fm}`;
let baseW = ctx.measureText(measureChar).width;
let ratset = {};
amountChars.forEach(item => {
let itemrat = (ctx.measureText(item).width / baseW).toFixed(PRECISION);
!ratset[itemrat] && (ratset[itemrat] = [])
ratset[itemrat].push(item)
});
!result[KMAP[fw]] && (result[KMAP[fw]] = {})
result[KMAP[fw]][KMAP[fm]] = generateExactRegex(ratset).filter(item => item[KMAP.ratio] !== 1)
})
})
console.log(`exact-regex-${lang}:`, result)
generateDownloadLink('exact-regex.js', JSON.stringify(result), lang)
}
generateUnitBase('zh');
generateUnitBase('en');
generateLangRegex('zh', ['·', '!', '¥', '……', '(', ')', '—', '。', '【', '】', ':', '“', '”', '‘', '’', '《', '》', '?', ',']);
generateLangRegex('en');
</script>
</html>