-
-
Save manustays/d54503ad75484c598b41ebd9c4bc3bec to your computer and use it in GitHub Desktop.
Revisions
-
manustays revised this gist
May 31, 2022 . 1 changed file with 19 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,11 +29,24 @@ ); } function createBookmark(anchor, _tags) { let cat = ''; let tags = JSON.parse(JSON.stringify(_tags)); if (tags) { if (typeof tags === 'string') { cat = tags; tags = ''; } else { cat = tags[0]; tags.shift(); if (cat === "Favourites Bar") { cat = ''; if (tags) { cat = tags[0]; tags.shift(); } } } } return { Name: anchor.innerText, @@ -73,13 +86,13 @@ } function arrayToCsv(array) { const titles = ["Name", "Created", "Status", "Category", "Tags", "Url"].map((t) => `"${t}"`); const entries = array.map((e) => [e.Name, e.Created, e.Status, e.Category, e.Tags, e.Url] // We use double quotes as data wrapper // We escape double quotes inside using another double quote as RFC says .map((f) => `"${f ? f.replace(/"/g, `""`) : ''}"`) .join(",") ); -
manustays revised this gist
May 30, 2022 . 1 changed file with 6 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,14 +30,17 @@ } function createBookmark(anchor, tags) { let cat = ''; if (tags) { cat = tags[0]; tags.shift(); } return { Name: anchor.innerText, Created: getDate(anchor), Status: "Stale", Category: cat, Tags: tags ? tags.join(", ") : '', // Make sure URL's are encoded, otherwise, Notion may fail to import Url: encodeURI(anchor.href), }; -
manustays revised this gist
May 30, 2022 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,9 +30,13 @@ } function createBookmark(anchor, tags) { let cat = tags[0]; tags.shift(); return { Name: anchor.innerText, Created: getDate(anchor), Status: "Stale", Category: cat, Tags: tags.join(", "), // Make sure URL's are encoded, otherwise, Notion may fail to import Url: encodeURI(anchor.href), -
Andrew Luca revised this gist
Feb 23, 2021 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,7 +12,7 @@ const csvString = arrayToCsv(bookmarks); downloadString(csvString); function getBookmarks(def, tags = []) { // Chromium browsers exports dl first // Safari browser exports dt first // We take both into consideration @@ -33,7 +33,7 @@ return { Name: anchor.innerText, Created: getDate(anchor), Tags: tags.join(", "), // Make sure URL's are encoded, otherwise, Notion may fail to import Url: encodeURI(anchor.href), }; @@ -61,8 +61,8 @@ ":scope > h6", ].join(",") ); if (!heading) return tags; return [...new Set([...tags, heading.innerText])] } function arrayToCsv(array) { -
Andrew Luca renamed this gist
Feb 22, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 10 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,13 @@ (function bookmarksExportToCsv() { /** * 1. Export bookmarks from browser (supported any Chromium based browsers and Safari) (chrome://bookmarks) * 2. Open exported html file again in the browser * 3. Copy paste this entire file in console, and execute it (hit enter) * 4. You will be prompted to save a CSV file. Save it. * 5. Open Notion. Click Import -> CSV * 6. Select saved CSV file. Wait for import * 7. You have a new database with all your bookmarks */ const bookmarks = getBookmarks(document.body); const csvString = arrayToCsv(bookmarks); downloadString(csvString); @@ -78,4 +87,4 @@ a.click(); window.setTimeout(() => window.URL.revokeObjectURL(a.href)); } })(); -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ (function bookmarksExportToCsv() { const bookmarks = getBookmarks(document.body); const csvString = arrayToCsv(bookmarks); downloadString(csvString); -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 15 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,12 +4,18 @@ downloadString(csvString); function getBookmarks(def, tags = new Set()) { // Chromium browsers exports dl first // Safari browser exports dt first // We take both into consideration return Array.from(def.querySelectorAll(":scope > dl, :scope > dt")).flatMap( function (child) { // Find for a bookmark const anchor = child.querySelector(":scope > a"); return anchor ? // if found create a bookmark object from it createBookmark(anchor, tags) : // if not, we go down in the tree, adding a new tag in tags getBookmarks(child, getNewTags(tags, child)); } ); } @@ -19,19 +25,23 @@ Name: anchor.innerText, Created: getDate(anchor), Tags: Array.from(tags).join(", "), // Make sure URL's are encoded, otherwise, Notion may fail to import Url: encodeURI(anchor.href), }; } function getDate(anchor) { const stringDate = anchor.getAttribute("add_date"); // Safari does not add an add_date attribute, default to new Date const date = stringDate ? new Date(Number(stringDate) * 1000) : new Date(); const dateF = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" }); const hourF = new Intl.DateTimeFormat("en-US", { timeStyle: "short" }); // Notion it seems to support it this way return `${dateF.format(date)} ${hourF.format(date)}`; } function getNewTags(tags, def) { // Depending on depth level heading can be different const heading = def.querySelector( [ ":scope > h1", @@ -51,6 +61,8 @@ const entries = array.map((e) => [e.Name, e.Created, e.Tags, e.Url] // We use double quotes as data wrapper // We escape double quotes inside using another double quote as RFC says .map((f) => `"${f.replace(/"/g, `""`)}"`) .join(",") ); @@ -61,6 +73,7 @@ function downloadString(text) { const a = document.createElement("a"); a.href = window.URL.createObjectURL(new Blob([text], { type: "text/csv" })); // When importing in Notion it will use file name without extension as page name a.download = "Bookmarks.csv"; a.click(); window.setTimeout(() => window.URL.revokeObjectURL(a.href)); -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ const csvString = arrayToCsv(bookmarks); downloadString(csvString); function getBookmarks(def, tags = new Set()) { return Array.from(def.querySelectorAll(":scope > dl, :scope > dt")).flatMap( function (child) { const anchor = child.querySelector(":scope > a"); @@ -18,7 +18,7 @@ return { Name: anchor.innerText, Created: getDate(anchor), Tags: Array.from(tags).join(", "), Url: encodeURI(anchor.href), }; } @@ -42,8 +42,8 @@ ":scope > h6", ].join(",") ); if (heading) tags.add(heading.innerText); return tags; } function arrayToCsv(array) { -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,8 +4,8 @@ downloadString(csvString); function getBookmarks(def, tags = []) { return Array.from(def.querySelectorAll(":scope > dl, :scope > dt")).flatMap( function (child) { const anchor = child.querySelector(":scope > a"); return anchor ? createBookmark(anchor, tags) -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 24 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,28 @@ (function downloadCsv() { const bookmarks = getBookmarks(document.body); const csvString = arrayToCsv(bookmarks); downloadString(csvString); function getBookmarks(def, tags = []) { return [...def.querySelectorAll(":scope > dl, :scope > dt")].flatMap( (child) => { const anchor = child.querySelector(":scope > a"); return anchor ? createBookmark(anchor, tags) : getBookmarks(child, getNewTags(tags, child)); } ); } function createBookmark(anchor, tags) { return { Name: anchor.innerText, Created: getDate(anchor), Tags: tags.join(", "), Url: encodeURI(anchor.href), }; } function getDate(anchor) { const stringDate = anchor.getAttribute("add_date"); const date = stringDate ? new Date(Number(stringDate) * 1000) : new Date(); @@ -22,26 +46,6 @@ return [...new Set([...tags, heading.innerText])]; } function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map((t) => `"${t}"`); @@ -61,8 +65,4 @@ a.click(); window.setTimeout(() => window.URL.revokeObjectURL(a.href)); } })(); -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 28 additions and 27 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,44 +1,45 @@ (function downloadCsv() { function getDate(anchor) { const stringDate = anchor.getAttribute("add_date"); const date = stringDate ? new Date(Number(stringDate) * 1000) : new Date(); const dateF = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" }); const hourF = new Intl.DateTimeFormat("en-US", { timeStyle: "short" }); return `${dateF.format(date)} ${hourF.format(date)}`; } function getNewTags(tags, def) { const heading = def.querySelector( [ ":scope > h1", ":scope > h2", ":scope > h3", ":scope > h4", ":scope > h5", ":scope > h6", ].join(",") ); if (!heading) return tags; return [...new Set([...tags, heading.innerText])]; } function createBookmark(anchor, tags) { return { Name: anchor.innerText, Created: getDate(anchor), Tags: tags.join(", "), Url: encodeURI(anchor.href), }; } function getBookmarks(def, tags = []) { return [...def.querySelectorAll(":scope > dl, :scope > dt")].flatMap( (child) => { const anchor = child.querySelector(":scope > a"); return anchor ? createBookmark(anchor, tags) : getBookmarks(child, getNewTags(tags, child)); } ); } function arrayToCsv(array) { -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 1 addition and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -42,9 +42,7 @@ } function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map((t) => `"${t}"`); const entries = array.map((e) => [e.Name, e.Created, e.Tags, e.Url] -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 68 additions and 54 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,55 +1,69 @@ (function downloadCsv() { const anchorPath = ":scope > a"; const defPath = [":scope > dl", ":scope > dt"].join(","); const headingPath = [ ":scope > h1", ":scope > h2", ":scope > h3", ":scope > h4", ":scope > h5", ":scope > h6", ].join(","); const dateF = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" }); const hourF = new Intl.DateTimeFormat("en-US", { timeStyle: "short" }); function getDate(anchor) { const stringDate = anchor.getAttribute("add_date"); const date = stringDate ? new Date(Number(stringDate) * 1000) : new Date(); return `${dateF.format(date)} ${hourF.format(date)}`; } function getNewTags(tags, def) { const heading = def.querySelector(headingPath); if (!heading) return tags; return [...new Set([...tags, heading.innerText])]; } const createBookmark = (anchor, tags) => ({ Name: anchor.innerText, Created: getDate(anchor), Tags: tags.join(", "), Url: encodeURI(anchor.href), }); function getBookmarks(def, tags = []) { return [...def.querySelectorAll(defPath)].flatMap((child) => { const anchor = child.querySelector(anchorPath); return anchor ? createBookmark(anchor, tags) : getBookmarks(child, getNewTags(tags, child)); }); } function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map((t) => JSON.stringify(t) ); const entries = array.map((e) => [e.Name, e.Created, e.Tags, e.Url] .map((f) => `"${f.replace(/"/g, `""`)}"`) .join(",") ); return `${titles.join(",")}\n${entries.join("\n")}`; } function downloadString(text) { const a = document.createElement("a"); a.href = window.URL.createObjectURL(new Blob([text], { type: "text/csv" })); a.download = "Bookmarks.csv"; a.click(); window.setTimeout(() => window.URL.revokeObjectURL(a.href)); } const bookmarks = getBookmarks(document.body); const csvString = arrayToCsv(bookmarks); downloadString(csvString); })(); -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ (function downloadCsv() { const aPath = ':scope > a' const dtPath = ':scope > dl, :scope > dt' const hPath = ':scope > h1, :scope > h2, :scope > h3, :scope > h4, :scope > h5, :scope > h6' const dateF = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }) const hourF = new Intl.DateTimeFormat('en-US', { timeStyle: 'short' }) @@ -9,10 +9,10 @@ return dts.flatMap(function (dt) { const anchor = dt.querySelector(aPath) if (!anchor) { const h = dt.querySelector(hPath) return getBookmarks( [...dt.querySelectorAll(dtPath)], h ? [...new Set([...tags, h.innerText])] : tags ) } -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 0 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,9 +7,6 @@ function getBookmarks(dts, tags = []) { return dts.flatMap(function (dt) { const anchor = dt.querySelector(aPath) if (!anchor) { const tag = dt.querySelector(hPath).innerText -
Andrew Luca revised this gist
Feb 22, 2021 . 1 changed file with 6 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,9 @@ function getBookmarks(dts, tags = []) { return dts.flatMap(function (dt) { /** * @type HTMLAnchorElement */ const anchor = dt.querySelector(aPath) if (!anchor) { const tag = dt.querySelector(hPath).innerText @@ -16,10 +19,11 @@ ) } const date = anchor.getAttribute('add_date') const Created = date ? new Date(Number(date) * 1000) : new Date() return { Name: anchor.innerText, Created: `${dateF.format(Created)} ${hourF.format(Created)}`, Tags: tags.join(', '), Url: encodeURI(anchor.href), } -
Andrew Luca renamed this gist
Feb 21, 2021 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Andrew Luca revised this gist
Feb 21, 2021 . 1 changed file with 11 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,15 +1,15 @@ (function downloadCsv() { const aPath = ':scope > a' const dtPath = ':scope > dl > dt' const hPath = ':scope > h1, :scope > h2, :scope > h3, :scope > h4, :scope > h5, :scope > h6' const dateF = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }) const hourF = new Intl.DateTimeFormat('en-US', { timeStyle: 'short' }) function getBookmarks(dts, tags = []) { return dts.flatMap(function (dt) { const anchor = dt.querySelector(aPath) if (!anchor) { const tag = dt.querySelector(hPath).innerText return getBookmarks( [...dt.querySelectorAll(dtPath)], [...new Set([...tags, tag])] @@ -21,7 +21,7 @@ Name: anchor.innerText, Created: `${dateF.format(date)} ${hourF.format(date)}`, Tags: tags.join(', '), Url: encodeURI(anchor.href), } }) } @@ -33,8 +33,8 @@ e.Name, e.Created, e.Tags, e.Url, ].map(f => `"${f.replace(/"/g, `""`)}"`).join(',')) return `${titles.join(',')}\n${entries.join('\n')}` } @@ -47,8 +47,8 @@ window.setTimeout(() => window.URL.revokeObjectURL(a.href)) } const bookmarks = getBookmarks([document.body]) const csvString = arrayToCsv(bookmarks) downloadString(csvString) })() -
Andrew Luca revised this gist
Feb 21, 2021 . 1 changed file with 54 additions and 53 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,53 +1,54 @@ (function downloadCsv() { let aPath = ':scope > a' let dtPath = ':scope > dl > dt' let hPath = ':scope > h1, :scope > h2, :scope > h3, :scope > h4, :scope > h5, :scope > h6' let dateF = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }) let hourF = new Intl.DateTimeFormat('en-US', { timeStyle: 'short' }) function getBookmarks(dts, tags = []) { return dts.flatMap(function (dt) { const anchor = dt.querySelector(aPath) if (!anchor) { const tag = dt.querySelector(hPath).innerText.trim().toLowerCase().split(' ').join('-') return getBookmarks( [...dt.querySelectorAll(dtPath)], [...new Set([...tags, tag])] ) } const date = new Date(Number(anchor.getAttribute('add_date')) * 1000) return { Name: anchor.innerText, Created: `${dateF.format(date)} ${hourF.format(date)}`, Tags: tags.join(', '), Url: anchor.href, } }) } function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map(t => JSON.stringify(t)) const entries = array.map(e => [ e.Name, e.Created, e.Tags, encodeURI(e.Url), ].map(f => JSON.stringify(f.replace(/"/g, `""`))).join(',')) return `${titles.join(',')}\n${entries.join('\n')}` } function downloadString(text) { const a = document.createElement('a') a.href = window.URL.createObjectURL(new Blob([text], { type: 'text/csv' })); a.download = "Bookmarks.csv" a.click() window.setTimeout(() => window.URL.revokeObjectURL(a.href)) } let bookmarks = getBookmarks([document.body]) let csvString = arrayToCsv(bookmarks) downloadString(csvString) })() -
Andrew Luca revised this gist
Feb 21, 2021 . 1 changed file with 9 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -27,14 +27,21 @@ function getBookmarks(dts, tags = []) { function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map(t => JSON.stringify(t)) const entries = array.map(e => [ e.Name, e.Created, e.Tags, encodeURI(e.Url), ].map(f => JSON.stringify(f.replace(/"/g, `""`))).join(',')) return `${titles.join(',')}\n${entries.join('\n')}` } function downloadString(text) { const a = document.createElement('a') a.href = window.URL.createObjectURL(new Blob([text], { type: 'text/csv' })); a.download = "Bookmarks.csv" a.click() window.setTimeout(() => window.URL.revokeObjectURL(a.href)) } -
Andrew Luca created this gist
Feb 21, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ let aPath = ':scope > a' let dtPath = ':scope > dl > dt' let hPath = ':scope > h1, :scope > h2, :scope > h3, :scope > h4, :scope > h5, :scope > h6' let dateF = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }) let hourF = new Intl.DateTimeFormat('en-US', { timeStyle: 'short' }) function getBookmarks(dts, tags = []) { return dts.flatMap(function (dt) { const anchor = dt.querySelector(aPath) if (!anchor) { const tag = dt.querySelector(hPath).innerText.trim().toLowerCase().split(' ').join('-') return getBookmarks( [...dt.querySelectorAll(dtPath)], [...new Set([...tags, tag])] ) } const date = new Date(Number(anchor.getAttribute('add_date')) * 1000) return { Name: anchor.innerText, Created: `${dateF.format(date)} ${hourF.format(date)}`, Tags: tags.join(', '), Url: anchor.href, } }) } function arrayToCsv(array) { const titles = ["Name", "Created", "Tags", "Url"].map(t => JSON.stringify(t)) const entries = array.map(e => [e.Name, e.Created, e.Tags, encodeURI(e.Url)].map(f => JSON.stringify(f)).join(',')) return `${titles.join(',')}\n${entries.join('\n')}` } function downloadString(text) { const a = document.createElement('a') a.href = window.URL.createObjectURL(new Blob([text], { type: 'text/csv' })); a.download = "bookmarks.csv" a.click() window.setTimeout(() => window.URL.revokeObjectURL(a.href)) } let bookmarks = getBookmarks([document.body]) let csvString = arrayToCsv(bookmarks) downloadString(csvString)