Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(remark-grid-tables): support fullwidth tables #312

Merged
merged 3 commits into from
Feb 4, 2019
Merged

fix(remark-grid-tables): support fullwidth tables #312

merged 3 commits into from
Feb 4, 2019

Conversation

chitoku-k
Copy link
Contributor

This PR adds fullwidth support for remark-grid-tables.

Fullwidth forms are the string representation that consumes double width in render. So far remark-grid-tables assumpted that every letter being rendered in the same width on the screen, thus it failed to handle fullwidth letters. In other words, the implementation currently treats the length of a string and the width of a string are equal, which is not always the case in some writing systems (like East Asian countries).

For instance, let's see the current behavior that requires:

+-------+-----+
| Hello | Dog |
+-------+-----+
| こんにちは | 🐶🦄👍 |
+-------+-----+

which makes almost impossible to correctly format a table by hand because:

  • Hello and こんにちは are both 5 letters but consumes different width
  • Dog and 🐶🦄👍 are both 3 letters but consumes double as well

In order to solve this issue, this PR fixes calculation and string operarion to carefully distinguish display width with the support of @nxmix/is-full-width and makes the following expression possible:

+------------+--------+
| Hello      | Dog    |
+------------+--------+
| こんにちは | 🐶🦄👍 |
+------------+--------+

(Screenshots are attached because GitHub seems to render those letters incorrectly. Using Unicode terminals are fine though.)

Another issue that is solved is surrogate pairs. JavaScript internally processes strings in UTF-16 to make us deal with some messy operation. For example, DOG FACE (🐶) is U+1F436; these codepoints like the ones emoji use have some restriction over string operators:

  • Not properly counted by length:
'🐶'.length // => 2
  • Not accessible through index:
'🐶'[0] // => '�' (broken)
  • However properly treated in Array.from():
Array.from('🐶') // => [ '🐶' ]

Therefore, the utility functions are added for all the cases above:

/**
 * Returns whether the given position is a valid character.
 * The position is equal to the display width.
 * @param {string} line
 * @param {number} pos
 * @returns {boolean}
 */
function isCodePointPosition (line, pos) {}
/**
 * Returns a part of string between the given position.
 * The position is equal to the display width.
 * @param {string} line
 * @param {number} start
 * @param {number?} end
 * @return {string}
 */
function substringLine (line, start, end) {}
/**
 * Returns the display width of the given string.
 * @param {string} line
 * @return {number}
 */
function computeLineLength (line) {}

Thanks for any efforts made to this package!

@chitoku-k
Copy link
Contributor Author

Added another support that is necessary for combined emoji (👨‍👨‍👧‍👦) that even Array.from() cannot split them by grapheme.

@vhf
Copy link
Contributor

vhf commented Jan 30, 2019

Thanks @chitoku-k ! I'll review over the weekend if time permits 👍

@vhf vhf merged commit b366bc7 into zestedesavoir:master Feb 4, 2019
vhf added a commit that referenced this pull request Feb 4, 2019
fix(remark-grid-tables): support fullwidth tables
@vhf
Copy link
Contributor

vhf commented Feb 4, 2019

@chitoku-k chitoku-k deleted the fix/doublewidth branch February 5, 2019 05:54
@chitoku-k
Copy link
Contributor Author

@vhf Thanks for accepting this. Love this product ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants