feat(markdown): support CJK and emoji (#3026)
* refactor: extract `splitText` * fix: respcet CJK width in table * test: add failing test * fix: support emoji * test: add failing test * feat: support CJK character * feat: enable adding whitespace between non-CJK/CJK-character by default * fix: do not print softline at node that is sensitive to its identifier * fix: treat full-width whitespace as CJK punctuation * disallow leading/trailing full-width whitespace * feat: remove `--split-cjk-text` option and enable it by default * refactor: simplify regex and remove unnecessary `g` flagmaster
parent
c3b965145b
commit
c27cc7ff45
|
@ -18,9 +18,11 @@
|
|||
"babylon": "7.0.0-beta.23",
|
||||
"camelcase": "4.1.0",
|
||||
"chalk": "2.1.0",
|
||||
"cjk-regex": "1.0.1",
|
||||
"cosmiconfig": "3.1.0",
|
||||
"dashify": "0.2.2",
|
||||
"diff": "3.2.0",
|
||||
"emoji-regex": "6.5.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"esutils": "2.0.2",
|
||||
"flow-parser": "0.51.0",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const stringWidth = require("string-width");
|
||||
|
||||
const util = require("./util");
|
||||
const docBuilders = require("./doc-builders");
|
||||
const concat = docBuilders.concat;
|
||||
const fill = docBuilders.fill;
|
||||
|
@ -68,7 +67,7 @@ function fits(next, restCommands, width, mustBeFlat) {
|
|||
const doc = x[2];
|
||||
|
||||
if (typeof doc === "string") {
|
||||
width -= stringWidth(doc);
|
||||
width -= util.getStringWidth(doc);
|
||||
} else {
|
||||
switch (doc.type) {
|
||||
case "concat":
|
||||
|
@ -155,7 +154,7 @@ function printDocToString(doc, options) {
|
|||
if (typeof doc === "string") {
|
||||
out.push(doc);
|
||||
|
||||
pos += stringWidth(doc);
|
||||
pos += util.getStringWidth(doc);
|
||||
} else {
|
||||
switch (doc.type) {
|
||||
case "cursor":
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
const remarkFrontmatter = require("remark-frontmatter");
|
||||
const remarkParse = require("remark-parse");
|
||||
const unified = require("unified");
|
||||
const util = require("./util");
|
||||
|
||||
/**
|
||||
* based on [MDAST](https://github.com/syntax-tree/mdast) with following modifications:
|
||||
|
@ -145,15 +146,7 @@ function splitText() {
|
|||
return {
|
||||
type: "sentence",
|
||||
position: node.position,
|
||||
children: value
|
||||
.split(/(\s+)/g)
|
||||
.map(
|
||||
(text, index) =>
|
||||
index % 2 === 0
|
||||
? { type: "word", value: text }
|
||||
: { type: "whitespace", value: " " }
|
||||
)
|
||||
.filter(node => node.value !== "")
|
||||
children: util.splitText(value)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ const concat = docBuilders.concat;
|
|||
const join = docBuilders.join;
|
||||
const line = docBuilders.line;
|
||||
const hardline = docBuilders.hardline;
|
||||
const softline = docBuilders.softline;
|
||||
const fill = docBuilders.fill;
|
||||
const align = docBuilders.align;
|
||||
const docPrinter = require("./doc-printer");
|
||||
|
@ -42,11 +43,17 @@ function genericPrint(path, options, print) {
|
|||
|
||||
if (shouldRemainTheSameContent(path)) {
|
||||
return concat(
|
||||
options.originalText
|
||||
.slice(node.position.start.offset, node.position.end.offset)
|
||||
.split(/(\s+)/g)
|
||||
.map((text, index) => (index % 2 === 0 ? text : line))
|
||||
.filter(doc => doc !== "")
|
||||
util
|
||||
.splitText(
|
||||
options.originalText.slice(
|
||||
node.position.start.offset,
|
||||
node.position.end.offset
|
||||
)
|
||||
)
|
||||
.map(
|
||||
node =>
|
||||
node.type === "word" ? node.value : node.value === "" ? "" : line
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -68,7 +75,9 @@ function genericPrint(path, options, print) {
|
|||
.replace(/(^|[^\\])\*/g, "$1\\*") // escape all unescaped `*` and `_`
|
||||
.replace(/\b(^|[^\\])_\b/g, "$1\\_"); // `1_2_3` is not considered emphasis
|
||||
case "whitespace":
|
||||
return getAncestorNode(path, SINGLE_LINE_NODE_TYPES) ? " " : line;
|
||||
return getAncestorNode(path, SINGLE_LINE_NODE_TYPES)
|
||||
? node.value === "" ? "" : " "
|
||||
: node.value === "" ? softline : line;
|
||||
case "emphasis": {
|
||||
const parentNode = path.getParentNode();
|
||||
const index = parentNode.children.indexOf(node);
|
||||
|
@ -334,7 +343,7 @@ function printTable(path, options, print) {
|
|||
const columnMaxWidths = contents.reduce(
|
||||
(currentWidths, rowContents) =>
|
||||
currentWidths.map((width, columnIndex) =>
|
||||
Math.max(width, rowContents[columnIndex].length)
|
||||
Math.max(width, util.getStringWidth(rowContents[columnIndex]))
|
||||
),
|
||||
contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:)
|
||||
);
|
||||
|
@ -388,15 +397,15 @@ function printTable(path, options, print) {
|
|||
}
|
||||
|
||||
function alignLeft(text, width) {
|
||||
return concat([text, " ".repeat(width - text.length)]);
|
||||
return concat([text, " ".repeat(width - util.getStringWidth(text))]);
|
||||
}
|
||||
|
||||
function alignRight(text, width) {
|
||||
return concat([" ".repeat(width - text.length), text]);
|
||||
return concat([" ".repeat(width - util.getStringWidth(text)), text]);
|
||||
}
|
||||
|
||||
function alignCenter(text, width) {
|
||||
const spaces = width - text.length;
|
||||
const spaces = width - util.getStringWidth(text);
|
||||
const left = Math.floor(spaces / 2);
|
||||
const right = spaces - left;
|
||||
return concat([" ".repeat(left), text, " ".repeat(right)]);
|
||||
|
|
103
src/util.js
103
src/util.js
|
@ -1,7 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
const stringWidth = require("string-width");
|
||||
const emojiRegex = require("emoji-regex")();
|
||||
const escapeStringRegexp = require("escape-string-regexp");
|
||||
|
||||
const getCjkRegex = require("cjk-regex");
|
||||
const cjkRegex = getCjkRegex();
|
||||
const cjkPunctuationRegex = getCjkRegex.punctuations();
|
||||
|
||||
function isExportDeclaration(node) {
|
||||
if (node) {
|
||||
switch (node.type) {
|
||||
|
@ -636,7 +642,104 @@ function mapDoc(doc, callback) {
|
|||
return callback(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* split text into whitespaces and words
|
||||
* @param {string} text
|
||||
* @return {Array<{ type: "whitespace", value: " " | "" } | { type: "word", value: string }>}
|
||||
*/
|
||||
function splitText(text) {
|
||||
const KIND_NON_CJK = "non-cjk";
|
||||
const KIND_CJK_CHARACTER = "cjk-character";
|
||||
const KIND_CJK_PUNCTUATION = "cjk-punctuation";
|
||||
|
||||
const nodes = [];
|
||||
|
||||
text
|
||||
.replace(
|
||||
new RegExp(`(${cjkRegex.source})\n(${cjkRegex.source})`, "g"),
|
||||
"$1$2"
|
||||
)
|
||||
// `\s` but exclude full-width whitspace (`\u3000`)
|
||||
.split(/([^\S\u3000]+)/)
|
||||
.forEach((token, index, tokens) => {
|
||||
// whitespace
|
||||
if (index % 2 === 1) {
|
||||
nodes.push({ type: "whitespace", value: " " });
|
||||
return;
|
||||
}
|
||||
|
||||
// word separated by whitespace
|
||||
|
||||
if ((index === 0 || index === tokens.length - 1) && token === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
token
|
||||
.split(new RegExp(`(${cjkRegex.source})`))
|
||||
.forEach((innerToken, innerIndex, innerTokens) => {
|
||||
if (
|
||||
(innerIndex === 0 || innerIndex === innerTokens.length - 1) &&
|
||||
innerToken === ""
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// non-CJK word
|
||||
if (innerIndex % 2 === 0) {
|
||||
if (innerToken !== "") {
|
||||
appendNode({
|
||||
type: "word",
|
||||
value: innerToken,
|
||||
kind: KIND_NON_CJK
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// CJK character
|
||||
const kind = cjkPunctuationRegex.test(innerToken)
|
||||
? KIND_CJK_PUNCTUATION
|
||||
: KIND_CJK_CHARACTER;
|
||||
appendNode({ type: "word", value: innerToken, kind });
|
||||
});
|
||||
});
|
||||
|
||||
return nodes;
|
||||
|
||||
function appendNode(node) {
|
||||
const lastNode = nodes[nodes.length - 1];
|
||||
if (lastNode && lastNode.type === "word") {
|
||||
if (isBetween(KIND_NON_CJK, KIND_CJK_CHARACTER)) {
|
||||
nodes.push({ type: "whitespace", value: " " });
|
||||
} else if (
|
||||
!isBetween(KIND_NON_CJK, KIND_CJK_PUNCTUATION) &&
|
||||
// disallow leading/trailing full-width whitespace
|
||||
![lastNode.value, node.value].some(value => /\u3000/.test(value))
|
||||
) {
|
||||
nodes.push({ type: "whitespace", value: "" });
|
||||
}
|
||||
}
|
||||
nodes.push(node);
|
||||
|
||||
function isBetween(kind1, kind2) {
|
||||
return (
|
||||
(lastNode.kind === kind1 && node.kind === kind2) ||
|
||||
(lastNode.kind === kind2 && node.kind === kind1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStringWidth(text) {
|
||||
// emojis are considered 2-char width for consistency
|
||||
// see https://github.com/sindresorhus/string-width/issues/11
|
||||
// for the reason why not implemented in `string-width`
|
||||
return stringWidth(text.replace(emojiRegex, " "));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getStringWidth,
|
||||
splitText,
|
||||
mapDoc,
|
||||
getMaxContinuousCount,
|
||||
getPrecedence,
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`cjk.md 1`] = `
|
||||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
||||
|
||||
`;
|
||||
|
||||
exports[`collapsed.md 1`] = `
|
||||
[hello][]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
|
@ -1,5 +1,31 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`cjk.md 1`] = `
|
||||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落
|
||||
|
||||
這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長
|
||||
很長的段落
|
||||
|
||||
這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
||||
全 形 空白全 形 空白全 形 空白
|
||||
|
||||
`;
|
||||
|
||||
exports[`inline-nodes.md 1`] = `
|
||||
It removes all original styling[*](#styling-footnote) and ensures that all outputted code conforms to a consistent style. (See this [blog post](http://jlongster.com/A-Prettier-Formatter))
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落
|
||||
|
||||
這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
|
@ -0,0 +1,58 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`cjk.md 1`] = `
|
||||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
||||
|
||||
空白全形空白全形空白全形空白 空白全形空白全形空白全形空白 空白全形空白全形空白全形空白 空白全形空白全形空白全形空白
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長
|
||||
很長的段落
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
||||
全 形 空白全 形 空白
|
||||
|
||||
空白全形空白全形空白全形空白 空白全形空白全形空白全形空白 空白全形空白全形空白
|
||||
全形空白 空白全形空白全形空白全形空白
|
||||
|
||||
`;
|
||||
|
||||
exports[`link.md 1`] = `
|
||||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
||||
|
||||
`;
|
||||
|
||||
exports[`mixed.md 1`] = `
|
||||
這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!
|
||||
|
||||
`;
|
||||
|
||||
exports[`space.md 1`] = `
|
||||
這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段
|
||||
Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著
|
||||
中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個
|
||||
English 混合著中文的一段 Paragraph!
|
||||
|
||||
`;
|
|
@ -0,0 +1,5 @@
|
|||
這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落
|
||||
|
||||
全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白全 形 空白
|
||||
|
||||
空白全形空白全形空白全形空白 空白全形空白全形空白全形空白 空白全形空白全形空白全形空白 空白全形空白全形空白全形空白
|
|
@ -0,0 +1 @@
|
|||
run_spec(__dirname, { parser: "markdown" });
|
|
@ -0,0 +1 @@
|
|||
[這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落][]
|
|
@ -0,0 +1 @@
|
|||
這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!這是一個English混合著中文的一段Paragraph!
|
|
@ -0,0 +1 @@
|
|||
這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!這是一個 English 混合著中文的一段 Paragraph!
|
|
@ -11,6 +11,28 @@ exports[`align.md 1`] = `
|
|||
|
||||
`;
|
||||
|
||||
exports[`cjk.md 1`] = `
|
||||
| abc | def | ghi |
|
||||
| --- | --- | --- |
|
||||
| 第一欄 | 第二欄 | 第三欄 |
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| abc | def | ghi |
|
||||
| ------ | ------ | ------ |
|
||||
| 第一欄 | 第二欄 | 第三欄 |
|
||||
|
||||
`;
|
||||
|
||||
exports[`emoji.md 1`] = `
|
||||
| abc | def | ghi |
|
||||
| --- | --- | --- |
|
||||
| 👍👍👍 | 👍👍👍 | 👍👍👍 |
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| abc | def | ghi |
|
||||
| ------ | ------ | ------ |
|
||||
| 👍👍👍 | 👍👍👍 | 👍👍👍 |
|
||||
|
||||
`;
|
||||
|
||||
exports[`escape.md 1`] = `
|
||||
| a | b | c |
|
||||
|:--|:-:|--:|
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
| abc | def | ghi |
|
||||
| --- | --- | --- |
|
||||
| 第一欄 | 第二欄 | 第三欄 |
|
|
@ -0,0 +1,3 @@
|
|||
| abc | def | ghi |
|
||||
| --- | --- | --- |
|
||||
| 👍👍👍 | 👍👍👍 | 👍👍👍 |
|
|
@ -1060,6 +1060,10 @@ circular-json@^0.3.1:
|
|||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
|
||||
|
||||
cjk-regex@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cjk-regex/-/cjk-regex-1.0.1.tgz#9bee3087e5e4e943549ace766b5d95a9b700dd41"
|
||||
|
||||
cli-cursor@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
|
||||
|
@ -1395,6 +1399,10 @@ elliptic@^6.0.0:
|
|||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.0"
|
||||
|
||||
emoji-regex@6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
|
||||
|
||||
emojis-list@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||
|
|
Loading…
Reference in New Issue