From c03dcfdbbc5a99abdb7517a03482bccf875d1953 Mon Sep 17 00:00:00 2001 From: Yuiki Saito Date: Mon, 12 May 2025 00:11:07 +0900 Subject: feat: Add NETSCAPE-Bookmark-file-1 export format support (#1374) * Add function to export bookmarks in NETSCAPE-Bookmark-file-1 format * Update export endpoint to support NETSCAPE format * Add format selection to export UI * include tags in the export --------- Co-authored-by: Mohamed Bassem --- apps/web/lib/exportBookmarks.ts | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'apps/web/lib/exportBookmarks.ts') diff --git a/apps/web/lib/exportBookmarks.ts b/apps/web/lib/exportBookmarks.ts index 45db104f..67b0b5da 100644 --- a/apps/web/lib/exportBookmarks.ts +++ b/apps/web/lib/exportBookmarks.ts @@ -58,3 +58,52 @@ export function toExportFormat( note: bookmark.note ?? null, }; } + +export function toNetscapeFormat(bookmarks: ZBookmark[]): string { + const header = ` + + +Bookmarks +

Bookmarks

+

`; + + const footer = `

`; + + const bookmarkEntries = bookmarks + .map((bookmark) => { + if (bookmark.content?.type !== BookmarkTypes.LINK) { + return ""; + } + const addDate = bookmark.createdAt + ? `ADD_DATE="${Math.floor(bookmark.createdAt.getTime() / 1000)}"` + : ""; + + const tagNames = bookmark.tags.map((t) => t.name).join(","); + const tags = tagNames.length > 0 ? `TAGS="${tagNames}"` : ""; + + const encodedUrl = encodeURI(bookmark.content.url); + const displayTitle = bookmark.title ?? bookmark.content.url; + const encodedTitle = escapeHtml(displayTitle); + + return `

${encodedTitle}`; + }) + .filter(Boolean) + .join("\n"); + + return `${header}\n${bookmarkEntries}\n${footer}`; +} + +function escapeHtml(input: string): string { + const escapeMap: Record = { + "&": "&", + "'": "'", + "`": "`", + '"': """, + "<": "<", + ">": ">", + }; + + return input.replace(/[&'`"<>]/g, (match) => escapeMap[match] || ""); +} -- cgit v1.2.3-70-g09d2