Merge pull request #152 from SebastianMC/151-sort-notes-in-dd-mmm-yyyy-format
151 sort notes in dd mmm yyyy format
This commit is contained in:
commit
fa6aafa3bd
|
@ -1,3 +1,5 @@
|
||||||
|
import {toString} from "builtin-modules";
|
||||||
|
|
||||||
export const RomanNumberRegexStr: string = ' *([MDCLXVI]+)'; // Roman number
|
export const RomanNumberRegexStr: string = ' *([MDCLXVI]+)'; // Roman number
|
||||||
export const CompoundRomanNumberDotRegexStr: string = ' *([MDCLXVI]+(?:\\.[MDCLXVI]+)*)';// Compound Roman number with dot as separator
|
export const CompoundRomanNumberDotRegexStr: string = ' *([MDCLXVI]+(?:\\.[MDCLXVI]+)*)';// Compound Roman number with dot as separator
|
||||||
export const CompoundRomanNumberDashRegexStr: string = ' *([MDCLXVI]+(?:-[MDCLXVI]+)*)'; // Compound Roman number with dash as separator
|
export const CompoundRomanNumberDashRegexStr: string = ' *([MDCLXVI]+(?:-[MDCLXVI]+)*)'; // Compound Roman number with dash as separator
|
||||||
|
@ -6,6 +8,8 @@ export const NumberRegexStr: string = ' *(\\d+)'; // Plain number
|
||||||
export const CompoundNumberDotRegexStr: string = ' *(\\d+(?:\\.\\d+)*)'; // Compound number with dot as separator
|
export const CompoundNumberDotRegexStr: string = ' *(\\d+(?:\\.\\d+)*)'; // Compound number with dot as separator
|
||||||
export const CompoundNumberDashRegexStr: string = ' *(\\d+(?:-\\d+)*)'; // Compound number with dash as separator
|
export const CompoundNumberDashRegexStr: string = ' *(\\d+(?:-\\d+)*)'; // Compound number with dash as separator
|
||||||
|
|
||||||
|
export const Date_dd_Mmm_yyyy_RegexStr: string = ' *([0-3]*[0-9]-(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\\d{4})'; // Date like 01-Jan-2020
|
||||||
|
|
||||||
export const DOT_SEPARATOR = '.'
|
export const DOT_SEPARATOR = '.'
|
||||||
export const DASH_SEPARATOR = '-'
|
export const DASH_SEPARATOR = '-'
|
||||||
|
|
||||||
|
@ -23,12 +27,16 @@ export const WordInAnyLanguageRegexStr = '(\\p{Letter}+)' // remember about th
|
||||||
|
|
||||||
export const WordInASCIIRegexStr = '([a-zA-Z]+)'
|
export const WordInASCIIRegexStr = '([a-zA-Z]+)'
|
||||||
|
|
||||||
export function prependWithZeros(s: string, minLength: number) {
|
export function prependWithZeros(s: string|undefined, minLength: number): string {
|
||||||
if (s.length < minLength) {
|
if ('string' === typeof s) {
|
||||||
const delta: number = minLength - s.length;
|
if (s.length < minLength) {
|
||||||
return '000000000000000000000000000'.substring(0, delta) + s;
|
const delta: number = minLength - s.length;
|
||||||
|
return '000000000000000000000000000'.substring(0, delta) + s;
|
||||||
|
} else {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return s;
|
return prependWithZeros((s ?? '').toString(), minLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,3 +103,18 @@ export function getNormalizedRomanNumber(s: string, separator?: string, places?:
|
||||||
return `${prependWithZeros(romanToIntStr(s), places ?? DEFAULT_NORMALIZATION_PLACES)}//`
|
return `${prependWithZeros(romanToIntStr(s), places ?? DEFAULT_NORMALIZATION_PLACES)}//`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DAY_POSITIONS = '00'.length
|
||||||
|
const MONTH_POSITIONS = '00'.length
|
||||||
|
const YEAR_POSITIONS = '0000'.length
|
||||||
|
|
||||||
|
const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
|
||||||
|
|
||||||
|
export function getNormalizedDate_dd_Mmm_yyyy_NormalizerFn(s: string): string | null {
|
||||||
|
// Assumption - the regex date matched against input s, no extensive defensive coding needed
|
||||||
|
const components = s.split('-')
|
||||||
|
const day = prependWithZeros(components[0], DAY_POSITIONS)
|
||||||
|
const month = prependWithZeros( `${1 + MONTHS.indexOf(components[1])}`, MONTH_POSITIONS)
|
||||||
|
const year = prependWithZeros(components[2], YEAR_POSITIONS)
|
||||||
|
return `${year}-${month}-${day}//`
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ import {
|
||||||
CompoundRomanNumberDashRegexStr,
|
CompoundRomanNumberDashRegexStr,
|
||||||
CompoundRomanNumberDotRegexStr,
|
CompoundRomanNumberDotRegexStr,
|
||||||
DASH_SEPARATOR,
|
DASH_SEPARATOR,
|
||||||
|
Date_dd_Mmm_yyyy_RegexStr,
|
||||||
DOT_SEPARATOR,
|
DOT_SEPARATOR,
|
||||||
|
getNormalizedDate_dd_Mmm_yyyy_NormalizerFn,
|
||||||
getNormalizedNumber,
|
getNormalizedNumber,
|
||||||
getNormalizedRomanNumber,
|
getNormalizedRomanNumber,
|
||||||
NumberRegexStr,
|
NumberRegexStr,
|
||||||
|
@ -348,6 +350,8 @@ const InlineRegexSymbol_Digit1: string = '\\d'
|
||||||
const InlineRegexSymbol_Digit2: string = '\\[0-9]'
|
const InlineRegexSymbol_Digit2: string = '\\[0-9]'
|
||||||
const InlineRegexSymbol_0_to_3: string = '\\[0-3]'
|
const InlineRegexSymbol_0_to_3: string = '\\[0-3]'
|
||||||
|
|
||||||
|
const Date_dd_Mmm_yyyy_RegexSymbol: string = '\\[dd-Mmm-yyyy]'
|
||||||
|
|
||||||
const InlineRegexSymbol_CapitalLetter: string = '\\C'
|
const InlineRegexSymbol_CapitalLetter: string = '\\C'
|
||||||
const InlineRegexSymbol_LowercaseLetter: string = '\\l'
|
const InlineRegexSymbol_LowercaseLetter: string = '\\l'
|
||||||
|
|
||||||
|
@ -365,7 +369,8 @@ const sortingSymbolsArr: Array<string> = [
|
||||||
escapeRegexUnsafeCharacters(CompoundRomanNumberDotRegexSymbol),
|
escapeRegexUnsafeCharacters(CompoundRomanNumberDotRegexSymbol),
|
||||||
escapeRegexUnsafeCharacters(CompoundRomanNumberDashRegexSymbol),
|
escapeRegexUnsafeCharacters(CompoundRomanNumberDashRegexSymbol),
|
||||||
escapeRegexUnsafeCharacters(WordInASCIIRegexSymbol),
|
escapeRegexUnsafeCharacters(WordInASCIIRegexSymbol),
|
||||||
escapeRegexUnsafeCharacters(WordInAnyLanguageRegexSymbol)
|
escapeRegexUnsafeCharacters(WordInAnyLanguageRegexSymbol),
|
||||||
|
escapeRegexUnsafeCharacters(Date_dd_Mmm_yyyy_RegexSymbol)
|
||||||
]
|
]
|
||||||
|
|
||||||
const sortingSymbolsRegex = new RegExp(sortingSymbolsArr.join('|'), 'gi')
|
const sortingSymbolsRegex = new RegExp(sortingSymbolsArr.join('|'), 'gi')
|
||||||
|
@ -433,6 +438,7 @@ export const CompoundDashRomanNumberNormalizerFn: NormalizerFn = (s: string) =>
|
||||||
export const NumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s)
|
export const NumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s)
|
||||||
export const CompoundDotNumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s, DOT_SEPARATOR)
|
export const CompoundDotNumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s, DOT_SEPARATOR)
|
||||||
export const CompoundDashNumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s, DASH_SEPARATOR)
|
export const CompoundDashNumberNormalizerFn: NormalizerFn = (s: string) => getNormalizedNumber(s, DASH_SEPARATOR)
|
||||||
|
export const Date_dd_Mmm_yyyy_NormalizerFn: NormalizerFn = (s: string) => getNormalizedDate_dd_Mmm_yyyy_NormalizerFn(s)
|
||||||
|
|
||||||
export enum AdvancedRegexType {
|
export enum AdvancedRegexType {
|
||||||
None, // to allow if (advancedRegex)
|
None, // to allow if (advancedRegex)
|
||||||
|
@ -443,7 +449,8 @@ export enum AdvancedRegexType {
|
||||||
CompoundDotRomanNumber,
|
CompoundDotRomanNumber,
|
||||||
CompoundDashRomanNumber,
|
CompoundDashRomanNumber,
|
||||||
WordInASCII,
|
WordInASCII,
|
||||||
WordInAnyLanguage
|
WordInAnyLanguage,
|
||||||
|
Date_dd_Mmm_yyyy
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortingSymbolToRegexpStr: { [key: string]: RegExpSpecStr } = {
|
const sortingSymbolToRegexpStr: { [key: string]: RegExpSpecStr } = {
|
||||||
|
@ -487,6 +494,11 @@ const sortingSymbolToRegexpStr: { [key: string]: RegExpSpecStr } = {
|
||||||
normalizerFn: IdentityNormalizerFn,
|
normalizerFn: IdentityNormalizerFn,
|
||||||
advancedRegexType: AdvancedRegexType.WordInAnyLanguage,
|
advancedRegexType: AdvancedRegexType.WordInAnyLanguage,
|
||||||
unicodeRegex: true
|
unicodeRegex: true
|
||||||
|
},
|
||||||
|
[Date_dd_Mmm_yyyy_RegexSymbol]: { // Intentionally retain character case
|
||||||
|
regexpStr: Date_dd_Mmm_yyyy_RegexStr,
|
||||||
|
normalizerFn: Date_dd_Mmm_yyyy_NormalizerFn,
|
||||||
|
advancedRegexType: AdvancedRegexType.Date_dd_Mmm_yyyy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
CompoundRomanNumberDotRegexStr,
|
CompoundRomanNumberDotRegexStr,
|
||||||
CompoundRomanNumberDashRegexStr,
|
CompoundRomanNumberDashRegexStr,
|
||||||
WordInASCIIRegexStr,
|
WordInASCIIRegexStr,
|
||||||
WordInAnyLanguageRegexStr
|
WordInAnyLanguageRegexStr, getNormalizedDate_dd_Mmm_yyyy_NormalizerFn
|
||||||
} from "../../custom-sort/matchers";
|
} from "../../custom-sort/matchers";
|
||||||
|
|
||||||
describe('Plain numbers regexp', () => {
|
describe('Plain numbers regexp', () => {
|
||||||
|
@ -405,3 +405,29 @@ describe('getNormalizedRomanNumber', () => {
|
||||||
expect(getNormalizedRomanNumber(s, separator, LEN)).toBe(out)
|
expect(getNormalizedRomanNumber(s, separator, LEN)).toBe(out)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('getNormalizedDate_dd_Mmm_yyyy_NormalizerFn', () => {
|
||||||
|
const params = [
|
||||||
|
['13-Jan-2012', '2012-01-13//'],
|
||||||
|
['3-Feb-2', '0002-02-03//'],
|
||||||
|
['1-Mar-1900', '1900-03-01//'],
|
||||||
|
['42-Apr-9999', '9999-04-42//'],
|
||||||
|
['0-May-0', '0000-05-00//'],
|
||||||
|
['21-Jun-2024', '2024-06-21//'],
|
||||||
|
['7-Jul-1872', '1872-07-07//'],
|
||||||
|
['15-Aug-1234', '1234-08-15//'],
|
||||||
|
['1234-Sep-7777', '7777-09-1234//'],
|
||||||
|
['3-Oct-2023', '2023-10-03//'],
|
||||||
|
['8-Nov-2022', '2022-11-08//'],
|
||||||
|
['18-Dec-2021', '2021-12-18//'],
|
||||||
|
['88-Dec-2012', '2012-12-88//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
['13-JANUARY-2012', '2012-00-13//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
['1 .1', '0000-00-1 .1//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
['', '0000-00-00//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
['abc', '0000-00-abc//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
['def-abc', '0000-00-def//'], // Invalid case, Regexp on matcher in the caller should guard against this
|
||||||
|
];
|
||||||
|
it.each(params)('>%s< should become %s', (s: string, out: string) => {
|
||||||
|
expect(getNormalizedDate_dd_Mmm_yyyy_NormalizerFn(s)).toBe(out)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
CompoundDotNumberNormalizerFn,
|
CompoundDotNumberNormalizerFn,
|
||||||
ConsumedFolderMatchingRegexp,
|
ConsumedFolderMatchingRegexp,
|
||||||
consumeFolderByRegexpExpression,
|
consumeFolderByRegexpExpression,
|
||||||
convertPlainStringToRegex,
|
convertPlainStringToRegex, Date_dd_Mmm_yyyy_NormalizerFn,
|
||||||
detectSortingSymbols,
|
detectSortingSymbols,
|
||||||
escapeRegexUnsafeCharacters,
|
escapeRegexUnsafeCharacters,
|
||||||
extractSortingSymbol,
|
extractSortingSymbol,
|
||||||
|
@ -404,11 +404,17 @@ const expectedSortSpecsExampleSortingSymbols: { [key: string]: CustomSortSpec }
|
||||||
regex: /^(\p{Letter}+)\. is for any modern language word$/iu,
|
regex: /^(\p{Letter}+)\. is for any modern language word$/iu,
|
||||||
normalizerFn: IdentityNormalizerFn
|
normalizerFn: IdentityNormalizerFn
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
type: CustomSortGroupType.ExactName,
|
||||||
|
regexPrefix: {
|
||||||
|
regex: /^ *([0-3]*[0-9]-(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{4}) for the specific date format of 12\-Apr\-2024$/i,
|
||||||
|
normalizerFn: Date_dd_Mmm_yyyy_NormalizerFn
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
type: CustomSortGroupType.Outsiders
|
type: CustomSortGroupType.Outsiders
|
||||||
}],
|
}],
|
||||||
targetFoldersPaths: ['mock-folder'],
|
targetFoldersPaths: ['mock-folder'],
|
||||||
outsidersGroupIdx: 7
|
outsidersGroupIdx: 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +426,7 @@ Plain syntax\\R+ ... works?
|
||||||
And this kind of... \\D+plain syntax???
|
And this kind of... \\D+plain syntax???
|
||||||
Here goes ASCII word \\a+
|
Here goes ASCII word \\a+
|
||||||
\\A+. is for any modern language word
|
\\A+. is for any modern language word
|
||||||
|
\\[dd-Mmm-yyyy] for the specific date format of 12-Apr-2024
|
||||||
`
|
`
|
||||||
|
|
||||||
describe('SortingSpecProcessor', () => {
|
describe('SortingSpecProcessor', () => {
|
||||||
|
@ -3141,6 +3148,7 @@ describe('hasMoreThanOneSortingSymbol', () => {
|
||||||
['\\-r+', false], ['--\\-r+--\\-D+++', true],
|
['\\-r+', false], ['--\\-r+--\\-D+++', true],
|
||||||
['\\d+abcd\\d+efgh', true],
|
['\\d+abcd\\d+efgh', true],
|
||||||
['\\R+abcd\\.R+efgh', true],
|
['\\R+abcd\\.R+efgh', true],
|
||||||
|
['\\R+abcd\\[dd-Mmm-yyyy]', true],
|
||||||
['\\d+\\.D+\\-d+\\R+\\.r+\\-R+ \\d+', true]
|
['\\d+\\.D+\\-d+\\R+\\.r+\\-R+ \\d+', true]
|
||||||
])('should correctly detect in >%s< (%s) sorting regex symbols', (s: string, b: boolean) => {
|
])('should correctly detect in >%s< (%s) sorting regex symbols', (s: string, b: boolean) => {
|
||||||
const result = hasMoreThanOneSortingSymbol(s)
|
const result = hasMoreThanOneSortingSymbol(s)
|
||||||
|
|
Loading…
Reference in New Issue