From 3d313751fc78685e0db7cae35feead1e4364683c Mon Sep 17 00:00:00 2001 From: Abdurrahman Aborazmeh Date: Sun, 7 Jul 2024 17:48:18 +0300 Subject: [PATCH 1/5] add double and single guillemet --- README.md | 2 ++ src/parser/PairMaker.js | 10 +++++++++ test/textlint-rule-no-unmatched-pair-test.js | 22 +++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 242ba45..b0b137e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ textlint rule that check unmatched pairs like `(` and `]` - 角括弧[]: `[` and `]` - 重角括弧〚〛: `〚` and `〛` - 隅付き括弧【】: `【` and `】` +- double guillemet: `«` and `»` +- single guillemet: `‹` and `›` ## Examples diff --git a/src/parser/PairMaker.js b/src/parser/PairMaker.js index e3c26e3..720d264 100644 --- a/src/parser/PairMaker.js +++ b/src/parser/PairMaker.js @@ -66,6 +66,16 @@ const PAIR_MARKS = [ key: "隅付き括弧【】", start: `【`, end: `】` + }, + { + key: "double guillemet «»", + start: "«", + end: "»" + }, + { + key: "single guillemet ‹›", + start: "‹", + end: "›" } ]; diff --git a/test/textlint-rule-no-unmatched-pair-test.js b/test/textlint-rule-no-unmatched-pair-test.js index 135a622..7f6f045 100644 --- a/test/textlint-rule-no-unmatched-pair-test.js +++ b/test/textlint-rule-no-unmatched-pair-test.js @@ -37,7 +37,9 @@ tester.run("textlint-rule-no-unmatched-pair", rule, { // GitHub Flavored Markdown // https://github.com/orgs/community/discussions/16925 `> [!NOTE] -> some content` +> some content`, + `Paul a dit : « Je viendrai demain » .`, + `Elle a écrit: « L’article est intitulé ‹ La technologie aujourd’hui › » .` ], invalid: [ { @@ -95,6 +97,24 @@ This pair mark is called double quote.` column: 105 } ] + }, + { + text: `Paul a dit : « Je viendrai demain.`, + errors: [ + { + line: 1, + column: 15 + } + ] + }, + { + text: `Elle a écrit: « L’article est intitulé ‹ La technologie aujourd’hui » .`, + errors: [ + { + line: 1, + column: 41 + } + ] } ] }); From 5dbedbcc09ceec80ab9b53c1c689a2edf8cce424 Mon Sep 17 00:00:00 2001 From: Abdurrahman Aborazmeh Date: Sun, 7 Jul 2024 17:53:45 +0300 Subject: [PATCH 2/5] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2b4c9d..51210da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@textlint-rule/textlint-rule-no-unmatched-pair", - "version": "2.0.2", + "version": "2.0.3", "description": "textlint rule that check unmatched pairs like \"(\" and \")\"", "keywords": [ "textlintrule" From 6be936c5dee4a0a7ebadadd39a51e507a6730c97 Mon Sep 17 00:00:00 2001 From: azu Date: Mon, 8 Jul 2024 16:55:56 +0900 Subject: [PATCH 3/5] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51210da..f2b4c9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@textlint-rule/textlint-rule-no-unmatched-pair", - "version": "2.0.3", + "version": "2.0.2", "description": "textlint rule that check unmatched pairs like \"(\" and \")\"", "keywords": [ "textlintrule" From 7f582b9a21d1bf6260401726181d60dbedcd0487 Mon Sep 17 00:00:00 2001 From: Abdurrahman Aborazmeh Date: Mon, 8 Jul 2024 23:29:21 +0300 Subject: [PATCH 4/5] add ornate parenthesis --- README.md | 1 + src/parser/PairMaker.js | 5 +++++ test/textlint-rule-no-unmatched-pair-test.js | 12 +++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b0b137e..58db761 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ textlint rule that check unmatched pairs like `(` and `]` - 隅付き括弧【】: `【` and `】` - double guillemet: `«` and `»` - single guillemet: `‹` and `›` +- ornate parenthesis `﴾` and `﴿` ## Examples diff --git a/src/parser/PairMaker.js b/src/parser/PairMaker.js index 720d264..7330cc6 100644 --- a/src/parser/PairMaker.js +++ b/src/parser/PairMaker.js @@ -76,6 +76,11 @@ const PAIR_MARKS = [ key: "single guillemet ‹›", start: "‹", end: "›" + }, + { + key: "ornate parenthesis ﴾﴿", + start: "﴾", + end: "﴿" } ]; diff --git a/test/textlint-rule-no-unmatched-pair-test.js b/test/textlint-rule-no-unmatched-pair-test.js index 7f6f045..486b9fe 100644 --- a/test/textlint-rule-no-unmatched-pair-test.js +++ b/test/textlint-rule-no-unmatched-pair-test.js @@ -39,7 +39,8 @@ tester.run("textlint-rule-no-unmatched-pair", rule, { `> [!NOTE] > some content`, `Paul a dit : « Je viendrai demain » .`, - `Elle a écrit: « L’article est intitulé ‹ La technologie aujourd’hui › » .` + `Elle a écrit: « L’article est intitulé ‹ La technologie aujourd’hui › » .`, + `a test for ﴾ornate﴿ parenthesis` ], invalid: [ { @@ -115,6 +116,15 @@ This pair mark is called double quote.` column: 41 } ] + }, + { + text: `a test for ﴾ornate parenthesis`, + errors: [ + { + line: 1, + column: 13 + } + ] } ] }); From 4129c90d400f57f97e2aca90288f80324bbd8347 Mon Sep 17 00:00:00 2001 From: Abdurrahman Aborazmeh Date: Tue, 9 Jul 2024 02:49:20 +0300 Subject: [PATCH 5/5] support reversed characters in RTL --- README.md | 14 +++++++ src/parser/PairMaker.js | 39 ++++++++++++-------- src/textlint-rule-no-unmatched-pair.js | 4 +- test/textlint-rule-no-unmatched-pair-test.js | 20 +++++++++- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 58db761..3db9e12 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,20 @@ Via `.textlintrc`(Recommended) } ``` +Some pair characters like the ornate parenthesis `﴾﴿` are strictly left or right oriented in every context. +To use such characters in rtl context, you need to reverse their usage. +You can use this rule by turning on the rtl option: + +```json +{ + "rules": { + "@textlint-rule/no-unmatched-pair": { + "rtl": true + } + } +} +``` + Via CLI ``` diff --git a/src/parser/PairMaker.js b/src/parser/PairMaker.js index 7330cc6..bc6ca4f 100644 --- a/src/parser/PairMaker.js +++ b/src/parser/PairMaker.js @@ -9,7 +9,7 @@ * https://ja.wikipedia.org/wiki/%E6%8B%AC%E5%BC%A7 */ /** - * @typedef {{key:string,start:string,end:string}[]} PairMark + * @typedef {{key:string,start:string,end:string,reverseInRtl:boolean}[]} PairMark */ const PAIR_MARKS = [ { @@ -80,26 +80,34 @@ const PAIR_MARKS = [ { key: "ornate parenthesis ﴾﴿", start: "﴾", - end: "﴿" + end: "﴿", + reverseInRtl: true } ]; // create entries // [start.key, mark] // [end.key, mark] -const PAIR_MARKS_ENTRIES = PAIR_MARKS.map((mark) => { - return [ - [mark.start, mark], - [mark.end, mark] - ]; -}).flat(1); +const PAIR_MARKS_ENTRIES = (rtl) => + PAIR_MARKS.map((mark) => { + const newMark = Object.assign({}, mark); + if (rtl && newMark.reverseInRtl) { + [newMark.start, newMark.end] = [newMark.end, newMark.start]; + } + + return [ + [newMark.start, newMark], + [newMark.end, newMark] + ]; + }).flat(1); /** * Optimized Map - * @type Map + * @type Map */ -const PAIR_MARKS_KEY_Map = new Map(PAIR_MARKS_ENTRIES); -const matchPair = (string) => { +const createPairMarksKeyMap = (rtl) => new Map(PAIR_MARKS_ENTRIES(rtl)); +const matchPair = (string, rtl) => { + const PAIR_MARKS_KEY_Map = createPairMarksKeyMap(rtl); return PAIR_MARKS_KEY_Map.get(string); }; // For readme @@ -107,15 +115,16 @@ const matchPair = (string) => { export class PairMaker { /** * @param {import("./SourceCode").SourceCode} sourceCode + * @param {boolean} rtl * @returns */ - mark(sourceCode) { + mark(sourceCode, rtl) { const string = sourceCode.read(); if (!string) { return; } - const matchedPair = matchPair(string); + const matchedPair = matchPair(string, rtl); if (!matchedPair) { return; } @@ -123,12 +132,12 @@ export class PairMaker { // {"{test}"} if (sourceCode.isInContext(matchedPair)) { // check that string is end mark? - const pair = PAIR_MARKS.find((pair) => pair.end === string); + const pair = PAIR_MARKS.find((pair) => (rtl && pair.reverseInRtl ? pair.start : pair.end === string)); if (pair) { sourceCode.leaveContext(pair); } } else { - const pair = PAIR_MARKS.find((pair) => pair.start === string); + const pair = PAIR_MARKS.find((pair) => (rtl && pair.reverseInRtl ? pair.end : pair.start === string)); if (pair) { sourceCode.enterContext(pair); } diff --git a/src/textlint-rule-no-unmatched-pair.js b/src/textlint-rule-no-unmatched-pair.js index 8930f56..0b66fa4 100644 --- a/src/textlint-rule-no-unmatched-pair.js +++ b/src/textlint-rule-no-unmatched-pair.js @@ -4,7 +4,7 @@ import { PairMaker } from "./parser/PairMaker.js"; import { SourceCode } from "./parser/SourceCode.js"; import { IgnoreNodeManager } from "textlint-rule-helper"; -const report = (context) => { +const report = (context, options) => { const { Syntax, report, RuleError } = context; const ignoreNodeManager = new IgnoreNodeManager(); return { @@ -30,7 +30,7 @@ const report = (context) => { const characterIndex = sentenceIndex + source.index; // console.log(characterIndex, source.text[source.index], ignoreNodeManager.isIgnoredIndex(characterIndex)); if (!ignoreNodeManager.isIgnoredIndex(characterIndex)) { - pairMaker.mark(source); + pairMaker.mark(source, options.rtl); } source.peek(); } diff --git a/test/textlint-rule-no-unmatched-pair-test.js b/test/textlint-rule-no-unmatched-pair-test.js index 486b9fe..dca2b40 100644 --- a/test/textlint-rule-no-unmatched-pair-test.js +++ b/test/textlint-rule-no-unmatched-pair-test.js @@ -40,7 +40,13 @@ tester.run("textlint-rule-no-unmatched-pair", rule, { > some content`, `Paul a dit : « Je viendrai demain » .`, `Elle a écrit: « L’article est intitulé ‹ La technologie aujourd’hui › » .`, - `a test for ﴾ornate﴿ parenthesis` + `a test for ﴾ornate﴿ parenthesis`, + { + text: `كانت آية ﴿اقرأ﴾ أول آية نزلت من القرآن`, + options: { + rtl: true + } + } ], invalid: [ { @@ -125,6 +131,18 @@ This pair mark is called double quote.` column: 13 } ] + }, + { + text: `كانت آية ﴿اقرأ أول آية نزلت من القرآن`, + options: { + rtl: true + }, + errors: [ + { + line: 1, + column: 11 + } + ] } ] });