Improve emoji width measurement (#17813)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
5067313d68
commit
99cd3d7426
6 files changed
+185
-1
No files matched your search
@@ -0,0 +1,28 @@
|
||||
#### Improve emoji size measurement (#17813 by @seiyab)
|
||||
|
||||
This change improves table alignment in all languages.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input -->
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
|
||||
<!-- Input -->
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
|
||||
|
||||
<!-- Prettier main -->
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
```
|
||||
@@ -5,8 +5,10 @@ import {
|
||||
// @ts-expect-error -- Private
|
||||
_isWide as isWide,
|
||||
} from "get-east-asian-width";
|
||||
import narrowEmojis from "./narrow-emojis.evaluate.js";
|
||||
|
||||
const notAsciiRegex = /[^\x20-\x7F]/u;
|
||||
const narrowEmojisSet = new Set(narrowEmojis);
|
||||
|
||||
// Similar to https://github.com/sindresorhus/string-width
|
||||
// We don't strip ansi, always treat ambiguous width characters as having narrow width.
|
||||
@@ -24,7 +26,9 @@ function getStringWidth(text) {
|
||||
return text.length;
|
||||
}
|
||||
|
||||
text = text.replace(emojiRegex(), " ");
|
||||
text = text.replace(emojiRegex(), (match) =>
|
||||
narrowEmojisSet.has(match) ? " " : " ",
|
||||
);
|
||||
let width = 0;
|
||||
|
||||
// Use `Intl.Segmenter` when we drop support for Node.js v14
|
||||
@@ -43,6 +47,11 @@ function getStringWidth(text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore Variation Selectors
|
||||
if (codePoint >= 0xfe00 && codePoint <= 0xfe0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
width += isFullWidth(codePoint) || isWide(codePoint) ? 2 : 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import assert from "node:assert";
|
||||
|
||||
/**
|
||||
* How the narrow emoji list was generated:
|
||||
* 1. Start with Unicode's official emoji list https://unicode.org/Public/emoji/latest/emoji-test.txt
|
||||
* 2. Select emojis that:
|
||||
* - consist of a single code point, and
|
||||
* - also have a variant with U+FE0F.
|
||||
* 3. Manually remove any false positives.
|
||||
*/
|
||||
const narrowEmojis = [
|
||||
"\u{263A}", // ☺
|
||||
"\u{2639}", // ☹
|
||||
"\u{2620}", // ☠
|
||||
"\u{2763}", // ❣
|
||||
"\u{2764}", // ❤
|
||||
"\u{270C}", // ✌
|
||||
"\u{261D}", // ☝
|
||||
"\u{270D}", // ✍
|
||||
"\u{26F7}", // ⛷
|
||||
"\u{26F9}", // ⛹
|
||||
"\u{2618}", // ☘
|
||||
"\u{26E9}", // ⛩
|
||||
"\u{2668}", // ♨
|
||||
"\u{2708}", // ✈
|
||||
"\u{23F1}", // ⏱
|
||||
"\u{23F2}", // ⏲
|
||||
"\u{2600}", // ☀
|
||||
"\u{2601}", // ☁
|
||||
"\u{26C8}", // ⛈
|
||||
"\u{2602}", // ☂
|
||||
"\u{26F1}", // ⛱
|
||||
"\u{2744}", // ❄
|
||||
"\u{2603}", // ☃
|
||||
"\u{2604}", // ☄
|
||||
"\u{26F8}", // ⛸
|
||||
"\u{2660}", // ♠
|
||||
"\u{2665}", // ♥
|
||||
"\u{2666}", // ♦
|
||||
"\u{2663}", // ♣
|
||||
"\u{265F}", // ♟
|
||||
"\u{26D1}", // ⛑
|
||||
"\u{260E}", // ☎
|
||||
"\u{2328}", // ⌨
|
||||
"\u{2709}", // ✉
|
||||
"\u{270F}", // ✏
|
||||
"\u{2712}", // ✒
|
||||
"\u{2702}", // ✂
|
||||
"\u{26CF}", // ⛏
|
||||
"\u{2692}", // ⚒
|
||||
"\u{2694}", // ⚔
|
||||
"\u{2699}", // ⚙
|
||||
"\u{2696}", // ⚖
|
||||
"\u{26D3}", // ⛓
|
||||
"\u{2697}", // ⚗
|
||||
"\u{26B0}", // ⚰
|
||||
"\u{26B1}", // ⚱
|
||||
"\u{26A0}", // ⚠
|
||||
"\u{2622}", // ☢
|
||||
"\u{2623}", // ☣
|
||||
"\u{2B06}", // ⬆
|
||||
"\u{2197}", // ↗
|
||||
"\u{27A1}", // ➡
|
||||
"\u{2198}", // ↘
|
||||
"\u{2B07}", // ⬇
|
||||
"\u{2199}", // ↙
|
||||
"\u{2B05}", // ⬅
|
||||
"\u{2196}", // ↖
|
||||
"\u{2195}", // ↕
|
||||
"\u{2194}", // ↔
|
||||
"\u{21A9}", // ↩
|
||||
"\u{21AA}", // ↪
|
||||
"\u{2934}", // ⤴
|
||||
"\u{2935}", // ⤵
|
||||
"\u{269B}", // ⚛
|
||||
"\u{2721}", // ✡
|
||||
"\u{2638}", // ☸
|
||||
"\u{262F}", // ☯
|
||||
"\u{271D}", // ✝
|
||||
"\u{2626}", // ☦
|
||||
"\u{262A}", // ☪
|
||||
"\u{262E}", // ☮
|
||||
"\u{25B6}", // ▶
|
||||
"\u{25C0}", // ◀
|
||||
"\u{23F8}", // ⏸
|
||||
"\u{23F9}", // ⏹
|
||||
"\u{23FA}", // ⏺
|
||||
"\u{23CF}", // ⏏
|
||||
"\u{2640}", // ♀
|
||||
"\u{2642}", // ♂
|
||||
"\u{26A7}", // ⚧
|
||||
"\u{2716}", // ✖
|
||||
"\u{267E}", // ♾
|
||||
"\u{203C}", // ‼
|
||||
"\u{2049}", // ⁉
|
||||
"\u{2695}", // ⚕
|
||||
"\u{267B}", // ♻
|
||||
"\u{269C}", // ⚜
|
||||
"\u{2611}", // ☑
|
||||
"\u{2714}", // ✔
|
||||
"\u{2733}", // ✳
|
||||
"\u{2734}", // ✴
|
||||
"\u{2747}", // ❇
|
||||
"\u{00A9}", // ©
|
||||
"\u{00AE}", // ®
|
||||
"\u{2122}", // ™
|
||||
"\u{2139}", // ℹ
|
||||
"\u{25FC}", // ◼
|
||||
"\u{25FB}", // ◻
|
||||
"\u{25AA}", // ▪
|
||||
"\u{25AB}", // ▫
|
||||
];
|
||||
|
||||
assert.equal(new Set(narrowEmojis).size, narrowEmojis.length);
|
||||
assert.equal(narrowEmojis.join("").length, narrowEmojis.length);
|
||||
|
||||
export default narrowEmojis.sort().join("");
|
||||
@@ -116,6 +116,28 @@ Default | CLI Override | API Override
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`issue-15572.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
printWidth: 80
|
||||
proseWrap: "always"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
=====================================output=====================================
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`simple.md - {"proseWrap":"always"} format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["markdown"]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
| | |
|
||||
| :-: | :-: |
|
||||
| ✔ | ✘ |
|
||||
| ✘ | ✔ |
|
||||
| ✔ | ✘ |
|
||||
@@ -87,6 +87,9 @@ test("sharedUtil.getStringWidth", () => {
|
||||
expect(getStringWidth("👶🏽")).toBe(2);
|
||||
expect(getStringWidth("👩👩👦👦")).toBe(2);
|
||||
expect(getStringWidth("👨❤️💋👨")).toBe(2);
|
||||
|
||||
expect(getStringWidth("©︎")).toBe(1);
|
||||
expect(getStringWidth("©️")).toBe(2);
|
||||
});
|
||||
|
||||
test("sharedUtil.getAlignmentSize", () => {
|
||||
|
||||
Reference in new issue
Block a user