diff --git a/README.md b/README.md index 7f79515..7fa135e 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ some: - In addition to the default JavaScript Collator options, the following properties can be supplied - `locales`: A BCP 47 language tag, or an comma separated array of such strings. - `customSortOrder`: Custom Sort order in the form of a list of characters + - `customIgnoreCharacters`: A list of characters that are ignored when sorting, e.g. `"'\"()[]{}<>"` - `sortConsecutiveBlockHeaders`: sorts consecutive block headers, such as a list of `case` statements. - Default: `true` - *Language Overridable* diff --git a/src/providers/ConfigurationProvider.ts b/src/providers/ConfigurationProvider.ts index 427b9a8..1a89f44 100644 --- a/src/providers/ConfigurationProvider.ts +++ b/src/providers/ConfigurationProvider.ts @@ -38,6 +38,7 @@ export interface NaturalSortOptions { export interface BlockSortCollatorOptions extends Omit { locales?: string; customSortOrder?: string; + customIgnoreCharacters?: string; } export interface BlockSortConfiguration { diff --git a/src/providers/StringSortProvider.ts b/src/providers/StringSortProvider.ts index f728ca2..36d9838 100644 --- a/src/providers/StringSortProvider.ts +++ b/src/providers/StringSortProvider.ts @@ -2,6 +2,7 @@ import { BlockSortCollatorOptions } from "./ConfigurationProvider"; export class StringSortProvider extends Intl.Collator { private customSortOrder?: string; + private customIgnoreCharacters?: RegExp; private ignoreCase?: boolean; private direction?: "asc" | "desc"; @@ -29,22 +30,38 @@ export class StringSortProvider extends Intl.Collator { this.customSortOrder = customSortOrder; } + this.customIgnoreCharacters = options?.customIgnoreCharacters + ? new RegExp( + `[${options.customIgnoreCharacters.replace(/\\/, "\\\\").replace(/]/g, "\\]").replace(/-/g, "\\-")}]`, + "g" + ) + : undefined; this.ignoreCase = caseFirst === "false" ? true : false; this.direction = direction ?? "asc"; } public compare(a: string, b: string): number { - const { customSortOrder, direction, ignoreCase } = this; + const { customSortOrder, customIgnoreCharacters, direction, ignoreCase } = this; const sign = direction === "asc" ? 1 : -1; + if (customIgnoreCharacters) { + a = a.replace(customIgnoreCharacters, ""); + b = b.replace(customIgnoreCharacters, ""); + } + if (customSortOrder) { const minLength = Math.min(a.length, b.length); for (let i = 0; i < minLength; i++) { const aIndex = customSortOrder.indexOf(ignoreCase ? a[i].toLowerCase() : a[i]); const bIndex = customSortOrder.indexOf(ignoreCase ? b[i].toLowerCase() : b[i]); - if (aIndex === -1 || bIndex === -1) continue; - else if (aIndex !== bIndex) return (aIndex - bIndex) * sign; + if (aIndex === -1 || bIndex === -1) { + const diff = super.compare(a[i], b[i]); + if (diff !== 0) return diff * sign; + else continue; + } + + if (aIndex !== bIndex) return (aIndex - bIndex) * sign; else if (i === minLength - 1) return (a.length - b.length) * sign; } } diff --git a/src/test/fixtures/custom.ts b/src/test/fixtures/custom.ts index e5f0f74..fe49811 100644 --- a/src/test/fixtures/custom.ts +++ b/src/test/fixtures/custom.ts @@ -14,4 +14,16 @@ export const customSortTests: CustomSortTest[] = [ ranges: [new Range(7, 0, 21, 1)], collatorOptions: { customSortOrder: '"-_' }, }, + { + file: "custom.plaintext.fixture", + compareFile: "custom.plaintext.expect", + ranges: [new Range(23, 0, 37, 1)], + collatorOptions: { customSortOrder: "-_", customIgnoreCharacters: "'\"()[]{}<>" }, + }, + { + file: "custom.plaintext.fixture", + compareFile: "custom.plaintext.expect", + ranges: [new Range(23, 0, 37, 1)], + collatorOptions: { customSortOrder: '"-_' }, + }, ]; diff --git a/test/fixtures/custom.plaintext.expect b/test/fixtures/custom.plaintext.expect index f80829b..d4d164b 100644 --- a/test/fixtures/custom.plaintext.expect +++ b/test/fixtures/custom.plaintext.expect @@ -20,3 +20,19 @@ variable "grafana_address" { variable "grafana_password" { type = string } + +variable "grafana" { + type = bool +} +variable "grafana_password" { + type = string +} +variable "helm_chart_version" { + type = string +} +variable "name" { + type = string +} +variable "name_chart_version" { + type = string +} diff --git a/test/fixtures/custom.plaintext.fixture b/test/fixtures/custom.plaintext.fixture index cb935d0..98b33d9 100644 --- a/test/fixtures/custom.plaintext.fixture +++ b/test/fixtures/custom.plaintext.fixture @@ -20,3 +20,19 @@ variable "grafana_password" { variable "grafana-count" { type = number } + +variable "grafana_password" { + type = string +} +variable "name_chart_version" { + type = string +} +variable "grafana" { + type = bool +} +variable "helm_chart_version" { + type = string +} +variable "name" { + type = string +}