Skip to content

Commit 4845186

Browse files
authored
Merge pull request #20976 from calixteman/bidi_tests
Add the bidi tests coming from BidiTest.txt and BidiCharacterTest.txt
2 parents 466c626 + 42c229c commit 4845186

File tree

4 files changed

+594320
-10
lines changed

4 files changed

+594320
-10
lines changed

src/core/bidi.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
import { warn } from "../shared/util.js";
1717

18+
// Implements a subset of the Unicode Bidirectional Algorithm (UBA).
19+
// Specification: https://www.unicode.org/reports/tr9/tr9-48.html
20+
1821
// Character types for symbols from 0000 to 00FF.
1922
// Source: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
2023
// prettier-ignore
@@ -297,25 +300,42 @@ function bidi(str, startLevel = -1, vertical = false) {
297300
text if the text on both sides has the same direction. European and Arabic
298301
numbers are treated as though they were R. Start-of-level-run (sor) and
299302
end-of-level-run (eor) are used at level run boundaries.
303+
See https://www.unicode.org/reports/tr9/tr9-48.html#N1
300304
*/
301305
for (i = 0; i < strLength; ++i) {
302306
if (types[i] === "ON") {
303307
const end = findUnequal(types, i + 1, "ON");
308+
309+
// Scan left past non-strong types to find the nearest strong context
310+
// (L, R, EN, or AN), falling back to sor at the level-run boundary.
304311
let before = sor;
305-
if (i > 0) {
306-
before = types[i - 1];
312+
for (let j = i - 1; j >= 0; j--) {
313+
const tt = types[j];
314+
if (tt === "L") {
315+
before = "L";
316+
break;
317+
}
318+
if (tt === "R" || tt === "EN" || tt === "AN") {
319+
before = "R";
320+
break;
321+
}
307322
}
308323

324+
// Scan right past non-strong types to find the nearest strong context,
325+
// falling back to eor at the level-run boundary.
309326
let after = eor;
310-
if (end + 1 < strLength) {
311-
after = types[end + 1];
312-
}
313-
if (before !== "L") {
314-
before = "R";
315-
}
316-
if (after !== "L") {
317-
after = "R";
327+
for (let j = end; j < strLength; j++) {
328+
const tt = types[j];
329+
if (tt === "L") {
330+
after = "L";
331+
break;
332+
}
333+
if (tt === "R" || tt === "EN" || tt === "AN") {
334+
after = "R";
335+
break;
336+
}
318337
}
338+
319339
if (before === after) {
320340
types.fill(before, i, end);
321341
}

0 commit comments

Comments
 (0)