Skip to content

Commit

Permalink
support reversed characters in RTL
Browse files Browse the repository at this point in the history
  • Loading branch information
aborazmeh committed Jul 8, 2024
1 parent 7f582b9 commit 4129c90
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 18 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

```
Expand Down
39 changes: 24 additions & 15 deletions src/parser/PairMaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
{
Expand Down Expand Up @@ -80,55 +80,64 @@ 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<string, {key:string,start:string,end:string}>
* @type Map<string, {key:string,start:string,end:string,reverseInRtl:boolean}>
*/
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
// console.log(PAIR_MARKS.map(pair => `- ${pair.key}: \`${pair.start}\` and \`${pair.end}\``).join("\n"));
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;
}
// support nested pair
// {"{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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/textlint-rule-no-unmatched-pair.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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();
}
Expand Down
20 changes: 19 additions & 1 deletion test/textlint-rule-no-unmatched-pair-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
{
Expand Down Expand Up @@ -125,6 +131,18 @@ This pair mark is called double quote.`
column: 13
}
]
},
{
text: `كانت آية ﴿اقرأ أول آية نزلت من القرآن`,
options: {
rtl: true
},
errors: [
{
line: 1,
column: 11
}
]
}
]
});

0 comments on commit 4129c90

Please sign in to comment.