mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 10:51:22 +00:00
Update translations. Code dedup and cleanup
This commit is contained in:
@@ -19,18 +19,31 @@ function Norm(ch, caseSensitive) {
|
||||
return caseSensitive ? folded : folded.toLowerCase(); // case-sensitivity is the only toggle
|
||||
}
|
||||
|
||||
// Pre-normalize a whole haystack with the SAME per-char fold FuzzyRanges uses, so a caller can match
|
||||
// it repeatedly against one cached string. The fold is 1:1 in length, so indices stay aligned to the
|
||||
// ORIGINAL text - the highlight ranges that FuzzyRangesNorm returns slice the original correctly.
|
||||
// Iterate by UTF-16 code unit (not Array.from code point) to mirror FuzzyRanges' own indexing exactly.
|
||||
// Pre-normalize a whole haystack with a length-preserving fold, so a caller can match it repeatedly
|
||||
// against one cached string. One input UTF-16 code unit always maps to one output code unit, so
|
||||
// indices stay aligned to the ORIGINAL text - the highlight ranges that FuzzyRangesNorm returns slice
|
||||
// the original correctly. Iterate by UTF-16 code unit (not Array.from code point) to mirror
|
||||
// FuzzyRanges' own indexing exactly.
|
||||
function NormText(text, caseSensitive) {
|
||||
const src = text || "";
|
||||
let out = "";
|
||||
for (let i = 0; i < src.length; i++)
|
||||
out += Norm(src[i], caseSensitive);
|
||||
out += NormStable(src[i], caseSensitive);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Length-preserving variant of Norm: NFD can expand a code unit (Hangul syllables become Jamo) or
|
||||
// drop it (combining diacritics), and toLowerCase can expand one too (U+0130). Any of those would
|
||||
// desync highlight offsets, so fall back to the original unit whenever the fold is not 1:1.
|
||||
function NormStable(ch, caseSensitive) {
|
||||
const folded = FoldChar(ch);
|
||||
const stable = folded.length === 1 ? folded : ch;
|
||||
if (caseSensitive)
|
||||
return stable;
|
||||
const lower = stable.toLowerCase();
|
||||
return lower.length === 1 ? lower : stable;
|
||||
}
|
||||
|
||||
// Match a PRE-normalized haystack against a PRE-normalized needle (both produced by NormText with the
|
||||
// same caseSensitive flag). Skipping the per-character fold makes repeated matching (per keystroke over a
|
||||
// cached pool) cheap. Returns ranges in original coordinates, or null on no match.
|
||||
@@ -115,18 +128,3 @@ function WholeWordRanges(text, query, caseSensitive) {
|
||||
ranges.push([match.index, match.index + match[0].length]);
|
||||
return ranges.length > 0 ? ranges : null;
|
||||
}
|
||||
|
||||
// Same whole-word (\b-bounded) match as WholeWordRanges, but against PRE-normalized haystack/needle
|
||||
// (NormText output, so offsets stay length-aligned to the original text). Returns the first match as
|
||||
// [[i, i+len]] in original coordinates, or null. Non-global so the caller can reuse one compiled regex
|
||||
// across many fields without re-setting lastIndex. Skipping the per-char fold keeps the Speed Dial's
|
||||
// per-keystroke scan over thousands of cached settings cheap.
|
||||
function WholeWordRangesNorm(haystackNorm, needleNorm) {
|
||||
const t = haystackNorm || "";
|
||||
const needle = needleNorm || "";
|
||||
if (!needle)
|
||||
return null;
|
||||
const re = new RegExp(`\\b${EscapeRegExp(needle)}\\b`);
|
||||
const match = re.exec(t);
|
||||
return match ? [[match.index, match.index + match[0].length]] : null;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ const vm = require("vm"), assert = require("assert"), fs = require("fs");
|
||||
const ctx = {};
|
||||
vm.createContext(ctx);
|
||||
vm.runInContext(fs.readFileSync(__dirname + "/fuzzy-search.js", "utf8"), ctx);
|
||||
const { FoldChar, Norm, NormText, EscapeRegExp, FuzzyRanges, WholeWordRanges, FuzzyRangesNorm, WholeWordRangesNorm } = ctx;
|
||||
const { FoldChar, Norm, NormText, EscapeRegExp, FuzzyRanges, WholeWordRanges, FuzzyRangesNorm } = ctx;
|
||||
|
||||
// FoldChar / Norm: accents fold, case only folds when case-insensitive.
|
||||
assert.equal(FoldChar("é"), "e");
|
||||
@@ -41,8 +41,11 @@ assert.deepEqual(FuzzyRangesNorm(NormText("Auto-Orient", false), NormText("orien
|
||||
assert.deepEqual(FuzzyRangesNorm(NormText("AutoOriented", false), NormText("orient", false)), [[4, 10]]);
|
||||
assert.equal(FuzzyRangesNorm(NormText("Measure", false), NormText("xyz", false)), null); // no subsequence
|
||||
|
||||
// WholeWordRangesNorm: \b-bounded literal against a pre-normalized haystack, offsets in original coords.
|
||||
assert.deepEqual(WholeWordRangesNorm(NormText("Auto-Orient", false), NormText("orient", false)), [[5, 11]]);
|
||||
assert.equal(WholeWordRangesNorm(NormText("AutoOriented", false), NormText("orient", false)), null); // inside a word
|
||||
// NormText stays 1:1 with the original even when NFD expands (Hangul syllables) or drops (combining
|
||||
// diacritics, U+0130) a code unit, so highlight ranges remain aligned to the original string.
|
||||
assert.equal(NormText("각x", false).length, "각x".length);
|
||||
assert.equal(NormText("e\u0301x", false).length, "e\u0301x".length);
|
||||
assert.equal(NormText("\u0130x", false).length, "\u0130x".length);
|
||||
assert.equal(FuzzyRangesNorm(NormText("각abcdeXfgh", false), NormText("X", false))[0][0], 6);
|
||||
|
||||
console.log("ok");
|
||||
|
||||
Reference in New Issue
Block a user