Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3df01c6ede | |||
| 537198c4f1 | |||
| 68e7b3ab04 |
@@ -2,11 +2,6 @@
|
||||
|
||||
An Obsidian plugin that adds dynamic date calculations to your notes using `date-calc` fenced code blocks and inline code.
|
||||
|
||||
|
||||
## Todo
|
||||
- [ ] Add custom language (default to Obsidian language, overridable)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
### Fenced Code Blocks
|
||||
@@ -18,7 +13,6 @@ type: birthday
|
||||
birthday: 1992-08-16
|
||||
```
|
||||
|
||||
|
||||
### Inline Code
|
||||
|
||||
Use inline code for quick calculations: `date-calc: birthday=1992-08-16`
|
||||
@@ -27,16 +21,16 @@ Use inline code for quick calculations: `date-calc: birthday=1992-08-16`
|
||||
|
||||
## Supported Calculation Types
|
||||
|
||||
### Birthday (`birthday`)
|
||||
### Birthday (`birthday`, `bday`, `age`)
|
||||
|
||||
Calculates age and time until next birthday, with an optional custom label and automatic personalization from your note's frontmatter.
|
||||
Calculates age and time until next birthday.
|
||||
|
||||
**Fields:**
|
||||
|
||||
- `birthday` (or `birthdate`, `date`): Birth date in YYYY-MM-DD format
|
||||
- `label` (optional): Custom label (defaults to "Age:")
|
||||
- `birthday` (or `birthdate`, `date`): Birth date
|
||||
- `label` (optional): Full prefix text, used verbatim — include your own punctuation (defaults to `Age:`)
|
||||
|
||||
**Frontmatter Support:** If not provided in the code block, the plugin reads `birthday`/`birthdate` from the note's frontmatter. If no `label` is set, a frontmatter `name` property becomes the default label automatically (e.g. `name: John` → "John's age:").
|
||||
**Frontmatter Support:** If not provided in the code block, reads `birthday`/`birthdate` from the note's frontmatter. If no `label` is set, a frontmatter `name` property personalizes the default label automatically (e.g. `name: John` → `John's age:`).
|
||||
|
||||
**Examples:**
|
||||
|
||||
@@ -51,41 +45,35 @@ birthday: 2000-05-21
|
||||
label: "John's age:"
|
||||
```
|
||||
|
||||
### Countdown (`countdown`, `until`, `remaining`)
|
||||
|
||||
### Countdown (`countdown` or `until`)
|
||||
|
||||
Shows time remaining until a target date.
|
||||
Time remaining until a target date, **always measured from now**. For a comparison between two fixed dates, use `diff` instead.
|
||||
|
||||
**Fields:**
|
||||
|
||||
- `to` (or `date`, `until`): Target date/time
|
||||
- `from` (optional): Starting date/time (defaults to now)
|
||||
- `label` (optional): Prefix label for the output
|
||||
- `label` (optional): Full prefix text, used verbatim (e.g. `label: "New Year:"`)
|
||||
|
||||
**Examples:**
|
||||
**Frontmatter Support:** If `to` isn't provided in the code block, reads `to`/`deadline` from the note's frontmatter.
|
||||
|
||||
**Example:**
|
||||
|
||||
```date-calc
|
||||
type: countdown
|
||||
label: New Year
|
||||
label: "New Year:"
|
||||
to: 2025-12-31 23:59
|
||||
```
|
||||
|
||||
```date-calc
|
||||
type: countdown
|
||||
label: Sprint ends
|
||||
to: 2025-10-15 17:00
|
||||
from: 2025-10-01 09:00
|
||||
```
|
||||
### Since (`since`, `elapsed`)
|
||||
|
||||
|
||||
### Since (`since`)
|
||||
|
||||
Shows time elapsed since an event (or time until if the event is in the future).
|
||||
Time elapsed since an event (or time until, if the event is in the future) — always measured against now.
|
||||
|
||||
**Fields:**
|
||||
|
||||
- `since` (or `from`, `date`): Event date/time
|
||||
|
||||
**Frontmatter Support:** If not provided in the code block, reads `since`/`created` from the note's frontmatter.
|
||||
|
||||
**Example:**
|
||||
|
||||
```date-calc
|
||||
@@ -93,16 +81,17 @@ type: since
|
||||
since: 2024-12-20
|
||||
```
|
||||
|
||||
### Difference (`diff`, `difference`)
|
||||
|
||||
### Difference (`diff`)
|
||||
|
||||
Calculates the time difference between two specific dates.
|
||||
The time difference between two fixed dates — neither has to be "now". For a countdown relative to the present moment, use `countdown` instead.
|
||||
|
||||
**Fields:**
|
||||
|
||||
- `from` (or `start`): Start date/time
|
||||
- `to` (or `end`): End date/time
|
||||
|
||||
**Frontmatter Support:** If not provided in the code block, reads `from`/`start` and `to`/`end` from the note's frontmatter.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```date-calc
|
||||
@@ -117,25 +106,32 @@ from: 2025-09-19 08:00
|
||||
to: 2025-09-19 16:30
|
||||
```
|
||||
|
||||
|
||||
## Inline Usage
|
||||
|
||||
You can use inline code for quick calculations:
|
||||
|
||||
- `date-calc: birthday=1992-08-16` → Birthday summary
|
||||
- `date-calc: to=2025-12-31 label="New Year"` → Countdown
|
||||
- `date-calc: to=2025-12-31 label="New Year:"` → Countdown
|
||||
- `date-calc: since=2024-12-20` → Time since event
|
||||
- `date-calc: from=2025-09-19 to=2025-09-20` → Date difference
|
||||
|
||||
**YAML Format:** Inline code also accepts YAML/inline-map format:
|
||||
`date-calc: {type: birthday, birthday: 1992-08-16}`
|
||||
**Formats:** Inline code accepts key=value pairs (`birthday=1992-08-16`) or a flow-mapping YAML object (`{type: birthday, birthday: 1992-08-16}`).
|
||||
|
||||
**Frontmatter Integration:** For inline birthday calculations, if no date is provided, the plugin will use the note's frontmatter `birthday`/`birthdate` property.
|
||||
**Frontmatter Integration:** Applies to every type, not just birthday — see each type's "Frontmatter Support" above.
|
||||
|
||||
## Date Formats
|
||||
|
||||
- **Timezone:** All calculations use your local timezone
|
||||
- **Birthday Calculations:** Normalized to local midnight to avoid timezone inconsistencies
|
||||
| Format | Example | Notes |
|
||||
| :------------------ | :------------------------------ | :----------------------------------------- |
|
||||
| Date only | `2026-12-31` | — |
|
||||
| Date + time | `2026-12-31 23:59` | — |
|
||||
| ISO 8601 | `2026-12-31T23:59:00` | — |
|
||||
| Relative keyword | `today`, `now`, `tomorrow`, `yesterday` | Resolved at render time |
|
||||
| Relative offset | `+7d`, `-3mo`, `+2w`, `-1y` | Units: `d`, `w`, `mo`, `y`, `h`, `m` (minutes) — always relative to now |
|
||||
|
||||
All dates use your local timezone. Birthday calculations normalize to midnight to avoid timezone edge cases; `today`/relative keywords resolve to your local time at render.
|
||||
|
||||
Relative dates are most useful with `diff`, since `countdown`/`since` are already anchored to now by default — e.g. `type: diff` with `from: today` and `to: +30d` gives a fixed 30-day window that doesn't need updating.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
@@ -158,70 +154,44 @@ verbose: true
|
||||
- `verbose: true` → "Countdown: 1 year, 2 months, 15 days"
|
||||
- `verbose: false` → "1y 2mo 15d"
|
||||
|
||||
|
||||
### Hide While Editing
|
||||
|
||||
Settings → "Hide result while cursor inside" prevents rendered output from showing while you're editing the code, keeping the raw syntax visible.
|
||||
|
||||
## Date Formats
|
||||
|
||||
| Format | Example | Use Case |
|
||||
| :---------- | :-------------------- | :-------------------- |
|
||||
| Date only | `2026-12-31` | Birthdays, countdowns |
|
||||
| Date + time | `2026-12-31 23:59` | Precise countdowns |
|
||||
| ISO 8601 | `2026-12-31T23:59:00` | Also supported |
|
||||
|
||||
All dates use your local timezone. Birthday calculations normalize to midnight to avoid timezone edge cases.
|
||||
|
||||
## Field Reference
|
||||
|
||||
### Birthday
|
||||
|
||||
- `birthday` / `birthdate` / `date` — Birth date
|
||||
- `verbose` — Override output format (optional)
|
||||
|
||||
- `birthday` / `birthdate` / `date` — Birth date (falls back to frontmatter `birthday`/`birthdate`)
|
||||
- `label` — Full prefix, verbatim (defaults to `Age:`, or `<frontmatter name>'s age:` if set)
|
||||
- `verbose` — Override output format
|
||||
|
||||
### Countdown
|
||||
|
||||
- `to` / `until` / `date` — Target date/time
|
||||
- `from` — Start date (defaults to now)
|
||||
- `label` — Custom prefix
|
||||
- `to` / `until` / `date` — Target date/time (falls back to frontmatter `to`/`deadline`)
|
||||
- `label` — Full prefix, verbatim
|
||||
- `verbose` — Override output format
|
||||
|
||||
|
||||
### Since
|
||||
|
||||
- `since` / `from` / `date` — Event date/time
|
||||
- `since` / `from` / `date` — Event date/time (falls back to frontmatter `since`/`created`)
|
||||
- `verbose` — Override output format
|
||||
|
||||
|
||||
### Diff
|
||||
|
||||
- `from` / `start` — Start date/time
|
||||
- `to` / `end` — End date/time
|
||||
- `from` / `start` — Start date/time (falls back to frontmatter `from`/`start`)
|
||||
- `to` / `end` — End date/time (falls back to frontmatter `to`/`end`)
|
||||
- `verbose` — Override output format
|
||||
|
||||
|
||||
## Type Aliases
|
||||
|
||||
For convenience, use these shortcuts:
|
||||
|
||||
- `birthday` = `bday`
|
||||
- `countdown` = `until`
|
||||
- `birthday` = `bday` = `age`
|
||||
- `countdown` = `until` = `remaining`
|
||||
- `since` = `elapsed`
|
||||
- `diff` = `difference`
|
||||
|
||||
|
||||
## Inline Syntax Formats
|
||||
|
||||
All three formats work:
|
||||
|
||||
**Key=value:** ```date-calc: birthday=1992-08-16```
|
||||
**YAML-like:** ```date-calc: type: birthday, birthday: 1992-08-16```
|
||||
**Compact:** ```date-calc: {type: birthday, birthday: 1992-08-16}```
|
||||
|
||||
|
||||
|
||||
|
||||
## Custom Styling
|
||||
|
||||
Target these CSS classes in your snippets:
|
||||
@@ -241,9 +211,7 @@ Target these CSS classes in your snippets:
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Commands
|
||||
|
||||
- **Toggle debug** — Log decoration activity to console
|
||||
- **Toggle verbose** — Switch global verbose mode
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "date-calc",
|
||||
"name": "Date calculator",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Calculate ages, countdowns, and date differences dynamically in your notes using inline code or fenced blocks.",
|
||||
"author": "Olivier Legendre",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "date-calculator",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "Calculate ages, countdowns, and date differences dynamically in your notes using inline code or fenced blocks.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
+52
-13
@@ -27,11 +27,11 @@ export function calculateDateResult(
|
||||
case "birthday":
|
||||
return calculateBirthday(cfg, app, sourcePath, useVerbose);
|
||||
case "countdown":
|
||||
return calculateCountdown(cfg, useVerbose);
|
||||
return calculateCountdown(cfg, app, sourcePath, useVerbose);
|
||||
case "diff":
|
||||
return calculateDiff(cfg, useVerbose);
|
||||
return calculateDiff(cfg, app, sourcePath, useVerbose);
|
||||
case "since":
|
||||
return calculateSince(cfg, useVerbose);
|
||||
return calculateSince(cfg, app, sourcePath, useVerbose);
|
||||
default:
|
||||
return { text: "date-calc: Unknown type. Supported: birthday, countdown, diff, since" };
|
||||
}
|
||||
@@ -76,17 +76,29 @@ function calculateBirthday(
|
||||
|
||||
const ageStr = verbose ? `${age} years old` : `${age}y`;
|
||||
// Custom label > frontmatter-name personalization > plain "Age:" default.
|
||||
// Labels are always used verbatim, including their own trailing punctuation.
|
||||
const name = frontmatterField(fm, "name");
|
||||
const label = cfg.label ?? (typeof name === "string" ? `${name}'s age:` : "Age:");
|
||||
return { text: `${label} ${ageStr}. ${msg}`, tooltip: bd.format("MMMM Do, YYYY") };
|
||||
}
|
||||
|
||||
function calculateCountdown(cfg: DateCalcConfig, verbose: boolean): DateCalcResult {
|
||||
const to = parseMoment(cfg.to ?? cfg.date ?? cfg.until);
|
||||
/** Always relative to now — for a fixed two-point comparison, use `diff`. */
|
||||
function calculateCountdown(
|
||||
cfg: DateCalcConfig,
|
||||
app: App,
|
||||
sourcePath: string,
|
||||
verbose: boolean
|
||||
): DateCalcResult {
|
||||
const fm = app.metadataCache.getCache(sourcePath)?.frontmatter;
|
||||
|
||||
const to = parseMoment(
|
||||
cfg.to ?? cfg.date ?? cfg.until ??
|
||||
frontmatterField(fm, "to") ?? frontmatterField(fm, "deadline")
|
||||
);
|
||||
if (!to) return { text: `date-calc: Missing or invalid "to" date.` };
|
||||
|
||||
const from = parseMoment(cfg.from) ?? moment();
|
||||
const label = cfg.label ? `${cfg.label}: ` : "";
|
||||
const from = moment();
|
||||
const label = cfg.label ? `${cfg.label} ` : "";
|
||||
const span = formatSpan(from, to, verbose);
|
||||
|
||||
const text = !span.isNegative
|
||||
@@ -96,9 +108,21 @@ function calculateCountdown(cfg: DateCalcConfig, verbose: boolean): DateCalcResu
|
||||
return { text };
|
||||
}
|
||||
|
||||
function calculateDiff(cfg: DateCalcConfig, verbose: boolean): DateCalcResult {
|
||||
const from = parseMoment(cfg.from ?? cfg.start);
|
||||
const to = parseMoment(cfg.to ?? cfg.end);
|
||||
/** A neutral two-point comparison — for "time until X from now", use `countdown`. */
|
||||
function calculateDiff(
|
||||
cfg: DateCalcConfig,
|
||||
app: App,
|
||||
sourcePath: string,
|
||||
verbose: boolean
|
||||
): DateCalcResult {
|
||||
const fm = app.metadataCache.getCache(sourcePath)?.frontmatter;
|
||||
|
||||
const from = parseMoment(
|
||||
cfg.from ?? cfg.start ?? frontmatterField(fm, "from") ?? frontmatterField(fm, "start")
|
||||
);
|
||||
const to = parseMoment(
|
||||
cfg.to ?? cfg.end ?? frontmatterField(fm, "to") ?? frontmatterField(fm, "end")
|
||||
);
|
||||
if (!from || !to) return { text: `date-calc: Provide valid "from" and "to" dates.` };
|
||||
|
||||
const span = formatSpan(from, to, verbose);
|
||||
@@ -110,8 +134,18 @@ function calculateDiff(cfg: DateCalcConfig, verbose: boolean): DateCalcResult {
|
||||
return { text };
|
||||
}
|
||||
|
||||
function calculateSince(cfg: DateCalcConfig, verbose: boolean): DateCalcResult {
|
||||
const since = parseMoment(cfg.since ?? cfg.from ?? cfg.date);
|
||||
function calculateSince(
|
||||
cfg: DateCalcConfig,
|
||||
app: App,
|
||||
sourcePath: string,
|
||||
verbose: boolean
|
||||
): DateCalcResult {
|
||||
const fm = app.metadataCache.getCache(sourcePath)?.frontmatter;
|
||||
|
||||
const since = parseMoment(
|
||||
cfg.since ?? cfg.from ?? cfg.date ??
|
||||
frontmatterField(fm, "since") ?? frontmatterField(fm, "created")
|
||||
);
|
||||
if (!since) return { text: `date-calc: Missing or invalid "since" date.` };
|
||||
|
||||
const now = moment();
|
||||
@@ -137,7 +171,12 @@ export function processInlineCode(
|
||||
const cfg = parseConfig(paramsRaw);
|
||||
const norm = normalizeConfig(paramsRaw, cfg);
|
||||
|
||||
if (!norm.type) return { text: "" };
|
||||
if (!norm.type) {
|
||||
// Surface a visible error instead of silently rendering nothing — the
|
||||
// author clearly meant to invoke date-calc (the prefix matched), so a
|
||||
// vanished result is far more confusing than an explicit message.
|
||||
return { text: 'date-calc: Missing or unrecognized "type" (birthday/countdown/diff/since).' };
|
||||
}
|
||||
|
||||
return calculateDateResult(norm.type, norm.cfg, app, sourcePath, settings.verbose);
|
||||
}
|
||||
|
||||
+4
-3
@@ -84,12 +84,13 @@ export function normalizeConfig(
|
||||
if (resolved.birthday || resolved.birthdate) type = "birthday";
|
||||
else if ((resolved.from && resolved.to) || (resolved.start && resolved.end)) type = "diff";
|
||||
else if (resolved.to || resolved.until) type = "countdown";
|
||||
else if (resolved.since) type = "since";
|
||||
else if (resolved.since || resolved.from) type = "since";
|
||||
}
|
||||
|
||||
if (type === "bday") type = "birthday";
|
||||
if (type === "until") type = "countdown";
|
||||
if (type === "bday" || type === "age") type = "birthday";
|
||||
if (type === "until" || type === "remaining") type = "countdown";
|
||||
if (type === "difference") type = "diff";
|
||||
if (type === "elapsed") type = "since";
|
||||
|
||||
return { type, cfg: resolved };
|
||||
}
|
||||
|
||||
+29
-2
@@ -1,9 +1,22 @@
|
||||
import { moment } from "obsidian";
|
||||
import type { M } from "./types";
|
||||
|
||||
/** Relative-offset shorthand: +7d, -3mo, +2w, etc. (always relative to now). */
|
||||
const RELATIVE_RE = /^([+-]\d+)\s*(d|days?|w|weeks?|mo|months?|y|years?|h|hours?|m|min|minutes?)$/i;
|
||||
|
||||
const RELATIVE_UNIT: Record<string, moment.unitOfTime.DurationConstructor> = {
|
||||
d: "days", day: "days", days: "days",
|
||||
w: "weeks", week: "weeks", weeks: "weeks",
|
||||
mo: "months", month: "months", months: "months",
|
||||
y: "years", year: "years", years: "years",
|
||||
h: "hours", hour: "hours", hours: "hours",
|
||||
m: "minutes", min: "minutes", minute: "minutes", minutes: "minutes",
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a date-ish input (frontmatter Date object, "YYYY-MM-DD" string, or any
|
||||
* moment-parseable string) into a moment. Returns null if unparseable.
|
||||
* Parse a date-ish input (frontmatter Date object, "YYYY-MM-DD" string, a
|
||||
* relative keyword/offset, or any moment-parseable string) into a moment.
|
||||
* Returns null if unparseable.
|
||||
*/
|
||||
export function parseMoment(input: unknown): M | null {
|
||||
if (input == null || input === "") return null;
|
||||
@@ -29,6 +42,20 @@ export function parseMoment(input: unknown): M | null {
|
||||
}
|
||||
|
||||
const s = String(input).trim();
|
||||
const lower = s.toLowerCase();
|
||||
|
||||
if (lower === "now") return moment();
|
||||
if (lower === "today") return moment().startOf("day");
|
||||
if (lower === "tomorrow") return moment().add(1, "day").startOf("day");
|
||||
if (lower === "yesterday") return moment().subtract(1, "day").startOf("day");
|
||||
|
||||
const rel = RELATIVE_RE.exec(s);
|
||||
if (rel) {
|
||||
const amount = parseInt(rel[1], 10);
|
||||
const unit = RELATIVE_UNIT[rel[2].toLowerCase()];
|
||||
return moment().add(amount, unit);
|
||||
}
|
||||
|
||||
const dateOnly = moment(s, "YYYY-MM-DD", true);
|
||||
if (dateOnly.isValid()) return dateOnly.startOf("day");
|
||||
|
||||
|
||||
+61
-38
@@ -1,6 +1,8 @@
|
||||
import { App, PluginSettingTab, Setting } from "obsidian";
|
||||
import type DateCalcPlugin from "../main";
|
||||
|
||||
const README_URL = "https://gitea.mithrilforge.dev/olivier/date-calculator";
|
||||
|
||||
export class DateCalcSettingTab extends PluginSettingTab {
|
||||
constructor(app: App, private plugin: DateCalcPlugin) {
|
||||
super(app, plugin);
|
||||
@@ -12,14 +14,10 @@ export class DateCalcSettingTab extends PluginSettingTab {
|
||||
|
||||
containerEl.createEl("h2", { text: "Date Calc" });
|
||||
|
||||
// Documentation link
|
||||
const docsDiv = containerEl.createDiv({
|
||||
cls: "setting-item-description date-calc-settings-docs",
|
||||
});
|
||||
docsDiv.createEl("a", {
|
||||
text: "📖 View Full Documentation",
|
||||
href: "https://github.com/thelegend09/date-calculator",
|
||||
});
|
||||
docsDiv.createEl("a", { text: "📖 Full syntax reference (README)", href: README_URL });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Debug logging")
|
||||
@@ -53,43 +51,68 @@ export class DateCalcSettingTab extends PluginSettingTab {
|
||||
})
|
||||
);
|
||||
|
||||
// Usage examples section
|
||||
containerEl.createEl("h3", { text: "Usage Examples" });
|
||||
containerEl.createEl("h3", { text: "Syntax at a glance" });
|
||||
const tldr = containerEl.createDiv({ cls: "date-calc-examples" });
|
||||
|
||||
const examplesDiv = containerEl.createDiv({ cls: "date-calc-examples" });
|
||||
tldr.createEl("p", {
|
||||
text: "Use `date-calc: ...` inline, or a fenced ```date-calc block with type: set explicitly (or inferred from which fields you give).",
|
||||
});
|
||||
|
||||
// Inline examples
|
||||
examplesDiv.createEl("h4", { text: "Inline Code (single backticks)" });
|
||||
const inlineList = examplesDiv.createEl("ul");
|
||||
inlineList.createEl("li").setText("`date-calc: birthday=2003-02-15`");
|
||||
inlineList.createEl("li").setText("`date-calc: countdown to=2026-12-31 label=\"New Year\"`");
|
||||
inlineList.createEl("li").setText("`date-calc: since=2024-01-01`");
|
||||
inlineList.createEl("li").setText("`date-calc: diff from=2024-01-01 to=2024-12-31`");
|
||||
inlineList.createEl("li").setText("`date-calc: birthday=1992-08-16 verbose=true`");
|
||||
|
||||
// Block examples
|
||||
examplesDiv.createEl("h4", { text: "Fenced Blocks (triple backticks)" });
|
||||
|
||||
examplesDiv
|
||||
.createEl("pre", { cls: "date-calc-example-block" })
|
||||
.setText("```date-calc\ntype: birthday\nbirthday: 1992-08-16\n```");
|
||||
|
||||
examplesDiv
|
||||
.createEl("pre", { cls: "date-calc-example-block" })
|
||||
.setText(
|
||||
"```date-calc\ntype: countdown\nto: 2026-12-31 23:59\nlabel: New Year\nverbose: true\n```"
|
||||
// Types table
|
||||
const typesList = tldr.createEl("ul");
|
||||
const addType = (name: string, aliases: string, desc: string, fields: string) => {
|
||||
const li = typesList.createEl("li");
|
||||
li.createEl("strong", { text: name });
|
||||
li.appendText(` (${aliases}) — ${desc} `);
|
||||
li.createEl("br");
|
||||
li.createEl("code", { text: fields });
|
||||
};
|
||||
addType(
|
||||
"birthday", "bday, age",
|
||||
"age + days until next birthday.",
|
||||
"birthday/birthdate/date, label"
|
||||
);
|
||||
addType(
|
||||
"countdown", "until, remaining",
|
||||
"time until a date, always from now.",
|
||||
"to/until/date, label"
|
||||
);
|
||||
addType(
|
||||
"since", "elapsed",
|
||||
"time since a date, always from now.",
|
||||
"since/from/date"
|
||||
);
|
||||
addType(
|
||||
"diff", "difference",
|
||||
"time between two fixed dates (neither has to be now).",
|
||||
"from/start, to/end"
|
||||
);
|
||||
|
||||
examplesDiv
|
||||
.createEl("pre", { cls: "date-calc-example-block" })
|
||||
.setText("```date-calc\ntype: diff\nfrom: 2024-01-01\nto: 2024-12-31\n```");
|
||||
tldr.createEl("h4", { text: "Relative dates" });
|
||||
tldr.createEl("p", {
|
||||
text: "today, now, tomorrow, yesterday, or an offset like +7d / -3mo / +2w (always relative to now).",
|
||||
});
|
||||
|
||||
// Tips section
|
||||
examplesDiv.createEl("h4", { text: "Tips" });
|
||||
const tipsList = examplesDiv.createEl("ul");
|
||||
tipsList.createEl("li").setText("Use YYYY-MM-DD format for dates");
|
||||
tipsList.createEl("li").setText("Add time with YYYY-MM-DD HH:mm for precise countdowns");
|
||||
tipsList.createEl("li").setText("Supported types: birthday, countdown, since, diff");
|
||||
tipsList.createEl("li").setText("Add verbose=true/false to override global setting");
|
||||
tldr.createEl("h4", { text: "Frontmatter fallback" });
|
||||
tldr.createEl("p", {
|
||||
text: "Every type reads its date(s) from frontmatter if not given inline: birthday/birthdate, to/deadline, since/created, from/start + to/end.",
|
||||
});
|
||||
|
||||
tldr.createEl("h4", { text: "Examples" });
|
||||
const examplesList = tldr.createEl("ul");
|
||||
examplesList.createEl("li").createEl("code", { text: "date-calc: birthday=1992-08-16" });
|
||||
examplesList.createEl("li").createEl("code", { text: "date-calc: to=2026-12-31 label=\"New Year:\"" });
|
||||
examplesList.createEl("li").createEl("code", { text: "date-calc: since=2024-01-01" });
|
||||
examplesList.createEl("li").createEl("code", { text: "date-calc: from=2024-01-01 to=today" });
|
||||
|
||||
examplesList
|
||||
.createEl("li")
|
||||
.createEl("pre", { cls: "date-calc-example-block" })
|
||||
.setText("```date-calc\ntype: countdown\nto: +30d\nlabel: \"Sprint:\"\nverbose: true\n```");
|
||||
|
||||
const fullDocs = tldr.createEl("p");
|
||||
fullDocs.appendText("Full field reference, custom styling, and more examples: ");
|
||||
fullDocs.createEl("a", { text: "README on Gitea", href: README_URL });
|
||||
fullDocs.appendText(".");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"1.0.0": "0.15.0",
|
||||
"1.1.0": "0.15.0"
|
||||
"1.1.0": "0.15.0",
|
||||
"1.2.0": "0.15.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user