diff --git a/src/app/resources/markmark/links.mark.md b/src/app/resources/markmark/links.mark.md
index 33d7f4e..87271c3 100644
--- a/src/app/resources/markmark/links.mark.md
+++ b/src/app/resources/markmark/links.mark.md
@@ -33,7 +33,7 @@ Tech projects that I found interesting, funny, or wanted to experiment with late
# Blogs & Posts
-- Dan Luu #dev
+- Dan Luu (2023-11-20) #dev
- https://danluu.com/
- https://danluu.com/everything-is-broken/
- The Case of a Curious SQL Query - Justing Jaffray #dev
diff --git a/src/app/resources/views/links.pug b/src/app/resources/views/links.pug
index 16c9210..d9f7854 100644
--- a/src/app/resources/views/links.pug
+++ b/src/app/resources/views/links.pug
@@ -27,4 +27,5 @@ block append style
*:not(li) > ul > li { margin-top: 20px; }
.markmark.link-tags { margin-left: 30px; }
- .markmark.link-tag { color: var(--c-font-muted); }
+ .markmark.link-tag { color: var(--c-font-muted); font-size: 0.8em; }
+ .markmark.link-date { margin-left: 30px; color: var(--c-font-muted); font-size: 0.8em; }
diff --git a/src/markmark/html.renderer.ts b/src/markmark/html.renderer.ts
index 753363b..c963d27 100644
--- a/src/markmark/html.renderer.ts
+++ b/src/markmark/html.renderer.ts
@@ -20,6 +20,11 @@ export class HtmlRenderer {
for ( const link of section.links ) {
let linkTitle = `${link.title}`
+
+ if ( link.date ) {
+ linkTitle += ` (${this.formatDate(link.date)})`
+ }
+
if ( link.tags.length ) {
linkTitle += ` ${link.tags.map(x => '#' + x + '').join(' ')}`
}
@@ -39,4 +44,11 @@ export class HtmlRenderer {
return mmLines.join('\n')
}
+
+ private formatDate(date: Date): string {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-based
+ const day = String(date.getDate()).padStart(2, '0');
+ return `${year}-${month}-${day}`;
+ }
}
diff --git a/src/markmark/parser.ts b/src/markmark/parser.ts
index fa9ac3d..dd0a714 100644
--- a/src/markmark/parser.ts
+++ b/src/markmark/parser.ts
@@ -61,8 +61,10 @@ export class Parser {
// If we're parsing a section list and we're NOT parsing a link's URL list
// and we encounter some text, assume it's the name of a link and start parsing it
if ( sectionListItemsRemaining && !linkListItemsRemaining && token.type === 'text' && (token as any).mmIsSectionLevel ) {
+ const [title, date] = this.parseTitleAndDate(token.text.split(' #')[0].trim())
currentLink = {
- title: token.text.split(' #')[0].trim(),
+ title,
+ date,
tags: this.parseTags(token.text),
urls: [],
}
@@ -129,6 +131,24 @@ export class Parser {
return fm
}
+ protected parseTitleAndDate(text: string): [string, Date|undefined] {
+ text = text.trim()
+
+ const dateMatcher = /(.*)\(([0-9\-+:TZ]+)\)$/g
+ const result = dateMatcher.exec(text)
+ if ( !result ) {
+ return [text, undefined]
+ }
+
+ const [, title, dateString] = result
+ const date = new Date(dateString)
+ if ( isNaN(date.getTime()) ) {
+ return [text, undefined]
+ }
+
+ return [title.trim(), date]
+ }
+
protected parseTags(text: string): string[] {
const matcher = /#([a-zA-Z0-9_\-]+)/g
return [...text.matchAll(matcher)].map(x => x[1])
diff --git a/src/markmark/types.ts b/src/markmark/types.ts
index 7bb7b5c..e2119a1 100644
--- a/src/markmark/types.ts
+++ b/src/markmark/types.ts
@@ -21,6 +21,7 @@ export const isNamedSection = (what: Section): what is NamedSection =>
export type Link = {
title: string,
+ date?: Date,
tags: string[],
urls: string[],
}