Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 74 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The plugin is written in TypeScript and exports all necessary types. Import them

```typescript
import type NaturalLanguageDates from 'nldates-revived';
import type { NLDResult, NLDRangeResult } from 'nldates-revived/src/parser';
import type { NLDResult, NLDRangeResult, NLDPeriodResult, DateGranularity } from 'nldates-revived/src/parser';
import type { NLDSettings, DayOfWeek } from 'nldates-revived/src/settings';
```

Expand Down Expand Up @@ -138,6 +138,19 @@ console.log(result2.formattedString); // "2025-01-06 15:00"

**Note:** This method uses the format from `plugin.settings.format` and automatically appends time format if a time component is detected.

**Periodic-note formats:** If the input resolves to a whole week/month/quarter/year (e.g. "next week", "Q3", "next quarter") and the corresponding `weekFormat`/`monthFormat`/`quarterFormat`/`yearFormat` setting is non-empty, that format is used instead:

```typescript
// If settings.quarterFormat is "YYYY-[Q]Q"
const result = plugin.parseDate("next quarter");
console.log(result.formattedString); // "2025-Q2"

const result2 = plugin.parseDate("Q3 2026");
console.log(result2.formattedString); // "2026-Q3"
```

See `parser.getParsedPeriod()` below for the underlying granularity detection.

---

### `parseDateRange(dateString: string): NLDRangeResult | null`
Expand Down Expand Up @@ -174,6 +187,8 @@ if (weekRange) {
- Weekday ranges: "from Monday to Friday" / "de lundi à vendredi"
- Week ranges: "next week" / "semaine prochaine" (returns all days of the week)

**Note:** A week-range result (`granularity: "week"`) is only produced by `plugin.parseDateRange()` directly. The higher-level `getParseCommand()` used by the plugin's commands skips this multi-day list in favor of `plugin.parseDate()`'s single `weekFormat` value whenever `settings.weekFormat` is configured -- see `parseDate()` above.

---

### `parseTime(dateString: string): NLDResult`
Expand Down Expand Up @@ -272,6 +287,34 @@ Low-level time component detection.

---

### `parser.getParsedPeriod(selectedText: string, weekStartPreference: DayOfWeek): NLDPeriodResult`

Like `getParsedDate()`, but also reports the calendar granularity ("day"/"week"/"month"/"quarter"/"year") the input expression referred to. Falls back to `getParsedDate()` (granularity `"day"`) for anything that isn't a whole-period reference.

**Parameters:**
- `selectedText` (string): Natural language date string (e.g., "next quarter", "Q3 2026", "2026-W02", "tomorrow")
- `weekStartPreference` (DayOfWeek): Day of week to consider as week start

**Returns:** `NLDPeriodResult` object (`{ date: Date; granularity: DateGranularity }`)

**Example:**
```typescript
const parser = plugin.parser;
const { date, granularity } = parser.getParsedPeriod("next quarter", "monday");
console.log(granularity); // "quarter"

parser.getParsedPeriod("Q3", "monday").granularity; // "quarter"
parser.getParsedPeriod("2026-W02", "monday").granularity; // "week"
parser.getParsedPeriod("tomorrow", "monday").granularity; // "day"
```

**Recognized period expressions (all 12 supported languages):**
- "this/next/last week|month|quarter|year" (e.g. "next quarter", "semaine prochaine", "来月", "다음 분기")
- Explicit quarter: "Q3", "Q3 2026", "2026 Q3", "2026-Q3" (language-neutral)
- Explicit ISO week: "2026-W02" (language-neutral)

---

## Types and Interfaces

### `NLDResult`
Expand Down Expand Up @@ -309,6 +352,29 @@ interface NLDRangeResult {
isRange: true;
/** Optional list of all dates in the range as Moment objects */
dateList?: Moment[];
/** Set to "week" for a whole-week period reference (e.g. "next week"), as opposed to an explicit weekday-to-weekday range. */
granularity?: "week";
}
```

### `DateGranularity`

The calendar granularity a parsed expression resolves to, as reported by `parser.getParsedPeriod()`.

```typescript
type DateGranularity = "day" | "week" | "month" | "quarter" | "year";
```

### `NLDPeriodResult`

Result object returned by `parser.getParsedPeriod()`.

```typescript
interface NLDPeriodResult {
/** A date that falls within the resolved period (e.g. any day of the target week). */
date: Date;
/** The calendar granularity detected from the input text. */
granularity: DateGranularity;
}
```

Expand Down Expand Up @@ -337,6 +403,13 @@ interface NLDSettings {
italian: boolean;
modalToggleLink: boolean;
modalMomentFormat: string; // Moment.js format for the Date Picker, date-only (default: "YYYY-MM-DD")
// Periodic-note formats (all default to ""/disabled): used instead of `format`
// when an expression resolves to a whole week/month/quarter/year (e.g. "next
// week", "Q3") -- for linking to Periodic Notes-style notes.
weekFormat: string; // e.g. "GGGG-[W]WW"
monthFormat: string; // e.g. "YYYY-MM"
quarterFormat: string; // e.g. "YYYY-[Q]Q"
yearFormat: string; // e.g. "YYYY"
// Smart suggestions
enableSmartSuggestions: boolean;
enableHistorySuggestions: boolean;
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Added
- The autosuggest dropdown now shows a preview of the resolved date/time next to each suggestion (e.g. `Next Monday` — `2025-01-06`), so you can see what will actually be inserted before picking one.
- **Korean support** (partial): `오늘`/`내일`/`어제`, weekdays, `이번`/`다음`/`지난` prefixes, and suffix-style relative expressions (`3일 후`, `2주 전`). Vocabulary based on [CreamNuts' nldates-obsidian-korean](https://github.com/CreamNuts/nldates-obsidian-korean) (MIT), with thanks. Like the other partially-supported languages, chrono-node has no Korean parser to fall back on, so some combined phrasings (weekday + specific time, date ranges) aren't recognized yet — tracked in [#40](https://github.com/Amato21/nldates-revived/issues/40).
- **Periodic-note formats**: optional `weekFormat`/`monthFormat`/`quarterFormat`/`yearFormat` settings (Settings → Periodic notes), each empty/disabled by default. When set, an expression that resolves to a whole period instead of a single day — `@next week`, `@this quarter`, `@Q3`, `@Q3 2026`, `@2026-W02` — uses that format (e.g. `GGGG-[W]WW`, `YYYY-[Q]Q`) instead of the daily Date format, for linking to weekly/monthly/quarterly/yearly notes (e.g. with the Periodic Notes plugin). Recognized in all 12 supported languages (`@next week`/`@semaine prochaine`/`@来週`/`@다음 주`/etc.). Leaving a field empty keeps the existing behavior unchanged, including `@next week`'s current behavior of inserting a link for every day of the week. Closes [#49](https://github.com/Amato21/nldates-revived/issues/49).

### Fixed
- Date Picker: picking a date via the calendar grid or a quick-select button (Today/Tomorrow/Next week/...) always inserted `12:00` as the time, regardless of what was actually selected. The modal was reformatting the selection down to a bare date string and re-parsing it through the NLP engine to build the preview/output, which discarded the actual time and let chrono-node's "no time specified" default (noon) leak through. Quick-select buttons had a related issue: they carried the real current wall-clock time instead of a clean date.
- Dutch: `next`/`last` were missing the neuter grammatical forms ("volgend"/"vorig", no final "-e") needed before neuter nouns like "jaar" and the newly-added "kwartaal" — only the common-gender forms ("volgende"/"vorige", used correctly before "week"/"maand") were recognized, so phrases like "volgend jaar" didn't parse as a relative expression.

### Changed
- Date Picker no longer deals with time at all — it's a date picker. Previously, picking a date always carried *some* time value (the real current wall-clock time), with no way to control or clear it. Rather than adding a settings menu to make that time optional, the modal now always produces a plain date, even if the manual input field is used to type a phrase that includes a time (e.g. "today at 3pm"). The default format changed from `YYYY-MM-DD HH:mm` to `YYYY-MM-DD` accordingly. For dates that do need a specific time, use the "Insert the current date and time" command or type a full expression into the autosuggest instead.
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ Go to **Settings > Natural Language Dates**:
* **Manage history:** Opens a list of everything in your suggestion history (most relevant first), with a button to remove any single entry, plus a "Clear all" option (armed on the first click, applied on the second, so it can't be triggered by accident)
* **Date Formatting:**
* **Omit date for short relative expressions:** When enabled, short relative expressions for today (e.g., `@in 15 min`, `@in 2 hours`) will display only the time (e.g., `14:30`) instead of `[[2024-01-15]] 14:30` (enabled by default)
* **Periodic Notes:** Optional formats for linking to weekly/monthly/quarterly/yearly notes (e.g. used by the [Periodic Notes](https://github.com/liamcain/obsidian-periodic-notes) plugin), each empty/disabled by default:
* **Week format** (e.g. `GGGG-[W]WW`), **Month format** (e.g. `YYYY-MM`), **Quarter format** (e.g. `YYYY-[Q]Q`), **Year format** (e.g. `YYYY`)
* When set, an expression that resolves to a whole period instead of a single day — `@next week`, `@this quarter`, `@Q3`, `@Q3 2026`, `@2026-W02` — uses that format instead of the daily Date format. Leave a field empty to keep using the daily format for that granularity (and, for weeks specifically, the existing behavior of inserting a link for every day of the week).
* Recognized in all 12 supported languages: `@next week`/`@semaine prochaine`/`@来週`/`@다음 주`, etc.

**Note:** History data is stored in `.obsidian/plugins/nldates-revived/history.json` and is limited to the 100 most relevant entries for optimal performance.

Expand Down
Loading
Loading