Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
(#33) Introduce sorting by ISO dates.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandru-dinu committed Jan 10, 2023
1 parent c5291bc commit 24b3d07
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
All notable changes to this project will be documented in this file.
See also the [releases](https://github.com/alexandru-dinu/obsidian-sortable/releases) page.

## [0.3.0] - 2023-01-10
### Added
- Introduce sorting by ISO dates ([regex](https://regex101.com/r/RfMAcx/1)).
- Mandatory format is `YYYY-MM-DD`, time is optional.

## [0.2.6] - 2022-08-06
### Fixed
- Don't show up-down arrows for the default table state; only show up / down arrows for ascending / descending sorting.
Expand Down Expand Up @@ -39,6 +44,7 @@ See also the [releases](https://github.com/alexandru-dinu/obsidian-sortable/rele
### Added
- Sort tables in ascending & descending order.

[0.3.0]: https://github.com/alexandru-dinu/obsidian-sortable/compare/0.2.6...0.3.0
[0.2.6]: https://github.com/alexandru-dinu/obsidian-sortable/compare/0.2.5...0.2.6
[0.2.5]: https://github.com/alexandru-dinu/obsidian-sortable/compare/0.2.4...0.2.5
[0.2.4]: https://github.com/alexandru-dinu/obsidian-sortable/compare/0.2.3...0.2.4
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.3.0
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "obsidian-sample-plugin",
"version": "0.12.0",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"name": "obsidian-sortable",
"version": "0.3.0",
"description": "Table sorting plugin",
"main": "main.js",
"scripts": {
"dev": "rollup --config rollup.config.js -w",
Expand Down
46 changes: 32 additions & 14 deletions src/sortable.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// allows time to be optional
const ISO_DATE_REGEX = /^(\d{4}-\d{2}-\d{2})(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?)?$/;

enum CellTypes {
TEXT,
NUMBER,
ISO_DATE,
}

enum SortOrder {
DEFAULT,
ASCENDING,
Expand All @@ -21,8 +30,7 @@ export type TTableStates = WeakMap<HTMLTableElement, TableState>;
function shouldSort(htmlEl: HTMLElement): boolean {
// dataview table: parent must be a "dataview" HTMLTableElement
const p = htmlEl.matchParent(".dataview");
if (p instanceof HTMLTableElement)
return true;
if (p instanceof HTMLTableElement) return true;

// reading mode, i.e. non-editing
return null !== htmlEl.matchParent(".markdown-reading-view");
Expand Down Expand Up @@ -119,28 +127,38 @@ function compareRows(
order: SortOrder,
collator: Intl.Collator
) {
let valueA = valueFromCell(a.cells[index]);
let valueB = valueFromCell(b.cells[index]);
let [valueA, typeA] = valueFromCell(a.cells[index]);
let [valueB, typeB] = valueFromCell(b.cells[index]);

if (order === SortOrder.DESCENDING) {
[valueA, valueB] = [valueB, valueA];
}

if (typeof valueA === "number" && typeof valueA === "number") {
return valueA < valueB ? -1 : 1;
if (typeA !== typeB) {
return collator.compare(valueA.toString(), valueB.toString());
}

return collator.compare(valueA.toString(), valueB.toString());
}

function tryParseFloat(x: string): string | number {
const y = parseFloat(x);
return isNaN(y) ? x : y;
switch (typeA) {
case CellTypes.NUMBER:
case CellTypes.ISO_DATE:
return valueA === valueB ? 0 : valueA < valueB ? -1 : 1;
case CellTypes.TEXT:
return collator.compare(valueA.toString(), valueB.toString());
}
}

function valueFromCell(element: HTMLTableCellElement) {
function valueFromCell(element: HTMLTableCellElement): [any, CellTypes] {
// TODO: extend to other data-types.
return tryParseFloat(element.textContent);
const text = element.textContent;

if (ISO_DATE_REGEX.test(text)) {
return [new Date(text), CellTypes.ISO_DATE];
}
const value = parseFloat(text);
if (!isNaN(value)) {
return [value, CellTypes.NUMBER];
}
return [text, CellTypes.TEXT];
}

function emptyTable(tableBody: HTMLTableSectionElement, rows: Array<HTMLTableRowElement>) {
Expand Down

0 comments on commit 24b3d07

Please sign in to comment.