From 2d1065dc528463da386082d22ef88e7b8e1c5fbc Mon Sep 17 00:00:00 2001 From: Anthony DePasquale Date: Mon, 7 Sep 2026 11:14:39 -0400 Subject: [PATCH] Do not fold dotless i to ASCII i in reference labels --- lib/inlines.js | 18 ++++++++++++++---- test/regression.txt | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/inlines.js b/lib/inlines.js index d2907b7a..8a6d70ce 100644 --- a/lib/inlines.js +++ b/lib/inlines.js @@ -99,12 +99,22 @@ var text = function(s) { // collapse internal space, unicode case fold. // See commonmark/commonmark.js#168. var normalizeReference = function(string) { - return string + var trimmed = string .slice(1, string.length - 1) .trim() - .replace(/[ \t\r\n]+/g, " ") - .toLowerCase() - .toUpperCase(); + .replace(/[ \t\r\n]+/g, " "); + // Dotless i (U+0131) has no default CaseFolding.txt entry, so it folds to + // itself (the I to dotless i mapping is Turkic-only), but it uppercases to + // ASCII I, so toLowerCase/toUpperCase would merge it with i. Fold the runs + // between occurrences instead. A run boundary can only affect final sigma, + // whose two lowercase forms uppercase alike; every other mapping these + // locale-independent methods apply is context-free. + if (trimmed.indexOf("\u0131") === -1) { + return trimmed.toLowerCase().toUpperCase(); + } + return trimmed.replace(/[^\u0131]+/g, function(part) { + return part.toLowerCase().toUpperCase(); + }); }; // INLINE PARSER diff --git a/test/regression.txt b/test/regression.txt index b4861783..c359e258 100644 --- a/test/regression.txt +++ b/test/regression.txt @@ -591,3 +591,37 @@ Issue #212 - Non-empty blank lines in fenced code ignored when in lists
  
 
```````````````````````````````` + +Dotless i (U+0131) is not folded to ASCII i + +```````````````````````````````` example +[I]: /a + +[ı]: /b + +[a][i] [b][ı] +. +

a b

+```````````````````````````````` + +Labels containing dotless i still fold their other characters + +```````````````````````````````` example +[FIQ]: /a + +[Fıq]: /b + +[a][fiq] [b][fıQ] +. +

a b

+```````````````````````````````` + +A dotless i reference does not resolve against an ASCII I definition + +```````````````````````````````` example +[I]: /a + +[ı] +. +

[ı]

+````````````````````````````````