Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
22d5125
:pencil2: Add support for other languages than en
RensOliemans Nov 2, 2021
a8864e9
:art: Simplify switch statement
RensOliemans Nov 2, 2021
fcd5ee5
:sparkles: Add translations to suggestions
RensOliemans Nov 2, 2021
a83de41
:hammer: Refactor date-suggest
RensOliemans Nov 2, 2021
0abd882
:sparkles: Multiple languages (editable in settings) is possible
RensOliemans Nov 3, 2021
38f1045
:pencil2: Remove console log
RensOliemans Nov 3, 2021
7859fb3
:art: Easier typing
RensOliemans Nov 3, 2021
a8e8532
:sparkles: Improve settings modal
RensOliemans Nov 4, 2021
7242ed3
:pencil2: Improve settings modal
RensOliemans Nov 4, 2021
fff37ad
:sparkles: Make date suggestions work for default and immediate sugge…
RensOliemans Nov 4, 2021
55e7f44
:sparkles: Finish relative suggestions
RensOliemans Nov 4, 2021
a550fda
Merge branch 'refactor/cm6-migration' of github.com:RensOliemans/nlda…
RensOliemans Nov 4, 2021
f8188cf
:sparkles: Add time support for multiple languages
RensOliemans Nov 4, 2021
cb2bc26
:pencil2: Build into . instead of build
RensOliemans Nov 4, 2021
5239ab3
:art: Clean settings
RensOliemans Nov 4, 2021
298a5b1
:see_no_evil: Revert gitignore build
RensOliemans Nov 4, 2021
0968753
:art: Tiny cleanup in date suggestion
RensOliemans Nov 4, 2021
ccf0804
Merge branch 'develop' into multilanguage
RensOliemans Nov 18, 2021
0fe3dcc
Fix obsidian git
RensOliemans Nov 18, 2021
afd9cc5
:pencil2: Added a newline for better readability
RensOliemans Nov 18, 2021
46e30e1
Merge branch 'master' of https://github.com/argenos/nldates-obsidian …
RensOliemans Jan 20, 2022
431907b
Fix German translation for today
RensOliemans Jan 20, 2022
6d397bb
Update readme for yarn
RensOliemans Jan 20, 2022
0b3069f
Merge branch 'master' of https://github.com/argenos/nldates-obsidian …
RensOliemans Mar 9, 2022
a866603
Update readme to use yarn
RensOliemans Mar 9, 2022
d45c5c2
Fix yarn.lock merge conflict
RensOliemans Mar 9, 2022
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ main.js
*.js.map

# MacOS
.DS_Store
.DS_Store
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,18 @@ console.log(thisEvening.moment.add(1, "hour")); // This would change the Moment
```

Note that if you manipulate the `parsedResult.moment`, the `date` and `formattedString` won't be updated. If you don't want to alter the `parsedResult.moment`, you should clone it. Read more about that on [the moment.js docs site](https://momentjs.com/docs/#/parsing/date/).


## Development Setup

```sh
git clone https://github.com/argenos/nldates-obsidian
cd nldates-obsidian
yarn install

yarn build
mkdir -p /path/to/vault/.obsidian/plugins/nldates-obsidian
cp -t /path/to/vault/.obsidian/plugins/nldates-obsidian/ main.ts manifest.json
```

And open your vault
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"typescript": "^4.4.4"
},
"dependencies": {
"roddeh-i18n": "^1.2.0",
"chrono-node": "git+https://github.com/liamcain/chrono.git#8460a7d95fbd5efbad073c79b90b2bf5e4dd12d0",
"obsidian-daily-notes-interface": "0.9.4"
}
Expand Down
29 changes: 29 additions & 0 deletions src/chrono.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import chrono, { Chrono, Parser } from "chrono-node";
import { ORDINAL_NUMBER_PATTERN, parseOrdinalNumberPattern } from "./utils";

function getOrdinalDateParser() {
return ({
pattern: () => new RegExp(ORDINAL_NUMBER_PATTERN),
extract: (_context, match) => {
return {
day: parseOrdinalNumberPattern(match[0]),
month: window.moment().month(),
};
},
} as Parser);
}


export default function getChronos(languages: string[]): Chrono[] {
const locale = window.moment.locale();
const isGB = locale === 'en-gb';

const chronos: Chrono[] = [];
const ordinalDateParser = getOrdinalDateParser();
languages.forEach(l => {
const c = new Chrono(chrono[l].createCasualConfiguration(isGB));
c.parsers.push(ordinalDateParser);
chronos.push(c)
});
return chronos;
}
7 changes: 7 additions & 0 deletions src/lang/de.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const dict = {
today: "Heute",
tomorrow: "Morgen",
yesterday: "Gestern",
} as const;

export default dict;
35 changes: 35 additions & 0 deletions src/lang/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const dict = {
today: "Today",
tomorrow: "Tomorrow",
yesterday: "Yesterday",
next: "next",
last: "last",
this: "this",
in: "in",
week: "week",
month: "month",
year: "year",
sunday: "Sunday",
monday: "Monday",
tuesday: "Tuesday",
wednesday: "Wednesday",
thursday: "Thursday",
friday: "Friday",
saturday: "Saturday",
inminutes: "in %{timeDelta} minutes",
inhours: "in %{timeDelta} hours",
indays: "in %{timeDelta} days",
inweeks: "in %{timeDelta} weeks",
inmonths: "in %{timeDelta} months",
daysago: "%{timeDelta} days ago",
weeksago: "%{timeDelta} weeks ago",
monthsago: "%{timeDelta} months ago",
time: "time",
now: "now",
plusminutes: "+%{timeDelta} minutes",
minusminutes: "-%{timeDelta} minutes",
plushour: "+%{timeDelta} hour",
minushour: "-%{timeDelta} hour",
} as const;

export default dict;
7 changes: 7 additions & 0 deletions src/lang/fr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const dict = {
today: "Aujourd'hui",
tomorrow: "Demain",
yesterday: "Hier",
} as const;

export default dict;
23 changes: 23 additions & 0 deletions src/lang/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import i18n from 'roddeh-i18n';

import en from './en';
import ja from './ja';
import fr from './fr';
import pt from './pt';
import de from './de';
import nl from './nl';

const notFoundDefault = "NOTFOUND" as const;

export default function t(key: string, lang: string, variables?: Record<string, string>): string {
const languages = {
en: i18n.create({ values: en }),
ja: i18n.create({ values: ja }),
fr: i18n.create({ values: fr }),
pt: i18n.create({ values: pt }),
de: i18n.create({ values: de }),
nl: i18n.create({ values: nl }),
};
const translation = languages[lang](key, notFoundDefault, variables);
return translation === notFoundDefault ? languages["en"](key, variables) : translation;
}
7 changes: 7 additions & 0 deletions src/lang/ja.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const dict = {
today: "今日",
tomorrow: "明日",
yesterday: "昨日",
} as const;

export default dict;
35 changes: 35 additions & 0 deletions src/lang/nl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const dict = {
today: "Vandaag",
tomorrow: "Morgen",
yesterday: "Gisteren",
next: "volgende?",
last: "vorige|laatste",
this: "deze|dit",
in: "over",
week: "week",
month: "maand",
year: "jaar",
sunday: "zondag",
monday: "maandag",
tuesday: "dinsdag",
wednesday: "woensdag",
thursday: "donderdag",
friday: "vrijdag",
saturday: "zaterdag",
inminutes: "over %{timeDelta} minuten",
inhours: "over %{timeDelta} uren",
indays: "over %{timeDelta} dagen",
inweeks: "over %{timeDelta} weken",
inmonths: "over %{timeDelta} maanden",
daysago: "%{timeDelta} dagen geleden",
weeksago: "%{timeDelta} weken geleden",
monthsago: "%{timeDelta} maanden geleden",
time: "tijd",
now: "nu",
plusminutes: "+%{timeDelta} minuten",
minusminutes: "-%{timeDelta} minuten",
plushour: "+%{timeDelta} uur",
minushour: "-%{timeDelta} uur",
} as const;

export default dict;
7 changes: 7 additions & 0 deletions src/lang/pt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const dict = {
today: "Hoja",
tomorrow: "Amanhã",
yesterday: "Ontem",
} as const;

export default dict;
6 changes: 5 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,14 @@ export default class NaturalLanguageDates extends Plugin {

this.app.workspace.onLayoutReady(() => {
// initialize the parser when layout is ready so that the correct locale is used
this.parser = new NLDParser();
this.resetParser();
});
}

async resetParser(): Promise<void> {
this.parser = new NLDParser(this.settings.languages);
}

onunload(): void {
console.log("Unloading natural language date parser plugin");
}
Expand Down
89 changes: 38 additions & 51 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import chrono, { Chrono, Parser } from "chrono-node";
import chrono, { Chrono, Parser, ParsedResult, ParsingOption } from "chrono-node";
import type { Moment } from "moment";
import getChronos from "./chrono";

import { DayOfWeek } from "./settings";
import {
ORDINAL_NUMBER_PATTERN,
getLastDayOfMonth,
getLocaleWeekStart,
getWeekNumber,
parseOrdinalNumberPattern,
} from "./utils";

export interface NLDResult {
Expand All @@ -16,52 +15,40 @@ export interface NLDResult {
moment: Moment;
}

function getLocalizedChrono(): Chrono {
const locale = window.moment.locale();

switch (locale) {
case "en-gb":
return new Chrono(chrono.en.createCasualConfiguration(true));
default:
return new Chrono(chrono.en.createCasualConfiguration(false));
}
}
export default class NLDParser {
chronos: Chrono[];

function getConfiguredChrono(): Chrono {
const localizedChrono = getLocalizedChrono();
localizedChrono.parsers.push({
pattern: () => {
return /\bChristmas\b/i;
},
extract: () => {
return {
day: 25,
month: 12,
};
},
});

localizedChrono.parsers.push({
pattern: () => new RegExp(ORDINAL_NUMBER_PATTERN),
extract: (_context, match) => {
return {
day: parseOrdinalNumberPattern(match[0]),
month: window.moment().month(),
};
},
} as Parser);
return localizedChrono;
}
constructor(languages: string[]) {
this.chronos = getChronos(languages);
}

export default class NLDParser {
chrono: Chrono;
getParsedDateResult(text: string, referenceDate?: Date, option?: ParsingOption): Date {
let result: Date;
this.chronos.forEach(c => {
const parsedDate = c.parseDate(text, referenceDate, option);
if (parsedDate) {
result = parsedDate;
return;
}
});
return result;
}

constructor() {
this.chrono = getConfiguredChrono();
getParsedResult(text: string): ParsedResult[] {
let result: ParsedResult[];
this.chronos.forEach(c => {
const parsedResult = c.parse(text);
if (parsedResult) {
result = parsedResult;
return;
}
});
return result;
}

getParsedDate(selectedText: string, weekStartPreference: DayOfWeek): Date {
const parser = this.chrono;
const parser = this.chronos[0];
const initialParse = parser.parse(selectedText);
const weekdayIsCertain = initialParse[0]?.start.isCertain("weekday");

Expand All @@ -88,46 +75,46 @@ export default class NLDParser {
}

if (nextDateMatch && nextDateMatch[1] === "week") {
return parser.parseDate(`next ${weekStart}`, referenceDate, {
return this.getParsedDateResult(`next ${weekStart}`, referenceDate,{
forwardDate: true,
});
}

if (nextDateMatch && nextDateMatch[1] === "month") {
const thisMonth = parser.parseDate("this month", new Date(), {
const thisMonth = this.getParsedDateResult("this month", new Date(),{
forwardDate: true,
});
return parser.parseDate(selectedText, thisMonth, {
return this.getParsedDateResult(selectedText, thisMonth, {
forwardDate: true,
});
}

if (nextDateMatch && nextDateMatch[1] === "year") {
const thisYear = parser.parseDate("this year", new Date(), {
const thisYear = this.getParsedDateResult("this year", new Date(), {
forwardDate: true,
});
return parser.parseDate(selectedText, thisYear, {
return this.getParsedDateResult(selectedText, thisYear, {
forwardDate: true,
});
}

if (lastDayOfMatch) {
const tempDate = parser.parse(lastDayOfMatch[2]);
const tempDate = this.getParsedResult(lastDayOfMatch[2]);
const year = tempDate[0].start.get("year");
const month = tempDate[0].start.get("month");
const lastDay = getLastDayOfMonth(year, month);

return parser.parseDate(`${year}-${month}-${lastDay}`, new Date(), {
return this.getParsedDateResult(`${year}-${month}-${lastDay}`, new Date(), {
forwardDate: true,
});
}

if (midOf) {
return parser.parseDate(`${midOf[1]} 15th`, new Date(), {
return this.getParsedDateResult(`${midOf[1]} 15th`, new Date(), {
forwardDate: true,
});
}

return parser.parseDate(selectedText, referenceDate, { locale });
return this.getParsedDateResult(selectedText, referenceDate, { locale });
}
}
Loading