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[], }