Skip to content

Instantly share code, notes, and snippets.

@manustays
Forked from unrevised6419/bookmarks-to-notion.js
Last active July 25, 2022 14:19
Show Gist options
  • Select an option

  • Save manustays/d54503ad75484c598b41ebd9c4bc3bec to your computer and use it in GitHub Desktop.

Select an option

Save manustays/d54503ad75484c598b41ebd9c4bc3bec to your computer and use it in GitHub Desktop.

Revisions

  1. manustays revised this gist May 31, 2022. 1 changed file with 19 additions and 6 deletions.
    25 changes: 19 additions & 6 deletions bookmarks-to-notion.js
    Original file line number Diff line number Diff line change
    @@ -29,11 +29,24 @@
    );
    }

    function createBookmark(anchor, tags) {
    function createBookmark(anchor, _tags) {
    let cat = '';
    let tags = JSON.parse(JSON.stringify(_tags));
    if (tags) {
    cat = tags[0];
    tags.shift();
    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", "Tags", "Url"].map((t) => `"${t}"`);
    const titles = ["Name", "Created", "Status", "Category", "Tags", "Url"].map((t) => `"${t}"`);

    const entries = array.map((e) =>
    [e.Name, e.Created, e.Tags, e.Url]
    [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.replace(/"/g, `""`)}"`)
    .map((f) => `"${f ? f.replace(/"/g, `""`) : ''}"`)
    .join(",")
    );

  2. manustays revised this gist May 30, 2022. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions bookmarks-to-notion.js
    Original file line number Diff line number Diff line change
    @@ -30,14 +30,17 @@
    }

    function createBookmark(anchor, tags) {
    let cat = tags[0];
    tags.shift();
    let cat = '';
    if (tags) {
    cat = tags[0];
    tags.shift();
    }
    return {
    Name: anchor.innerText,
    Created: getDate(anchor),
    Status: "Stale",
    Category: cat,
    Tags: tags.join(", "),
    Tags: tags ? tags.join(", ") : '',
    // Make sure URL's are encoded, otherwise, Notion may fail to import
    Url: encodeURI(anchor.href),
    };
  3. manustays revised this gist May 30, 2022. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions bookmarks-to-notion.js
    Original 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),
  4. Andrew Luca revised this gist Feb 23, 2021. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions bookmarks-to-notion.js
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@
    const csvString = arrayToCsv(bookmarks);
    downloadString(csvString);

    function getBookmarks(def, tags = new Set()) {
    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: Array.from(tags).join(", "),
    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) tags.add(heading.innerText);
    return tags;
    if (!heading) return tags;
    return [...new Set([...tags, heading.innerText])]
    }

    function arrayToCsv(array) {
  5. Andrew Luca renamed this gist Feb 22, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion bookmarks-to-csv.js
    Original 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));
    }
    })();
    })();
  7. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    (function downloadCsv() {
    (function bookmarksExportToCsv() {
    const bookmarks = getBookmarks(document.body);
    const csvString = arrayToCsv(bookmarks);
    downloadString(csvString);
  8. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 15 additions and 2 deletions.
    17 changes: 15 additions & 2 deletions bookmarks-to-csv.js
    Original 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
    ? createBookmark(anchor, tags)
    : getBookmarks(child, getNewTags(tags, child));
    ? // 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));
  9. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    const csvString = arrayToCsv(bookmarks);
    downloadString(csvString);

    function getBookmarks(def, tags = []) {
    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: tags.join(", "),
    Tags: Array.from(tags).join(", "),
    Url: encodeURI(anchor.href),
    };
    }
    @@ -42,8 +42,8 @@
    ":scope > h6",
    ].join(",")
    );
    if (!heading) return tags;
    return [...new Set([...tags, heading.innerText])];
    if (heading) tags.add(heading.innerText);
    return tags;
    }

    function arrayToCsv(array) {
  10. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,8 @@
    downloadString(csvString);

    function getBookmarks(def, tags = []) {
    return [...def.querySelectorAll(":scope > dl, :scope > dt")].flatMap(
    (child) => {
    return Array.from(def.querySelectorAll(":scope > dl, :scope > dt")).flatMap(
    function (child) {
    const anchor = child.querySelector(":scope > a");
    return anchor
    ? createBookmark(anchor, tags)
  11. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 24 additions and 24 deletions.
    48 changes: 24 additions & 24 deletions bookmarks-to-csv.js
    Original 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 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) {
    const titles = ["Name", "Created", "Tags", "Url"].map((t) => `"${t}"`);

    @@ -61,8 +65,4 @@
    a.click();
    window.setTimeout(() => window.URL.revokeObjectURL(a.href));
    }

    const bookmarks = getBookmarks(document.body);
    const csvString = arrayToCsv(bookmarks);
    downloadString(csvString);
    })();
  12. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 28 additions and 27 deletions.
    55 changes: 28 additions & 27 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,44 +1,45 @@
    (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();
    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(headingPath);
    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])];
    }

    const createBookmark = (anchor, tags) => ({
    Name: anchor.innerText,
    Created: getDate(anchor),
    Tags: tags.join(", "),
    Url: encodeURI(anchor.href),
    });
    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(defPath)].flatMap((child) => {
    const anchor = child.querySelector(anchorPath);
    return anchor
    ? createBookmark(anchor, tags)
    : getBookmarks(child, getNewTags(tags, child));
    });
    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) {
  13. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -42,9 +42,7 @@
    }

    function arrayToCsv(array) {
    const titles = ["Name", "Created", "Tags", "Url"].map((t) =>
    JSON.stringify(t)
    );
    const titles = ["Name", "Created", "Tags", "Url"].map((t) => `"${t}"`);

    const entries = array.map((e) =>
    [e.Name, e.Created, e.Tags, e.Url]
  14. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 68 additions and 54 deletions.
    122 changes: 68 additions & 54 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,55 +1,69 @@
    (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' })

    function getBookmarks(dts, tags = []) {
    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
    )
    }

    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),
    }
    })
    }

    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)
    })()
    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);
    })();
  15. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    (function downloadCsv() {
    const aPath = ':scope > a'
    const dtPath = ':scope > dl > dt'
    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 tag = dt.querySelector(hPath).innerText
    const h = dt.querySelector(hPath)
    return getBookmarks(
    [...dt.querySelectorAll(dtPath)],
    [...new Set([...tags, tag])]
    h ? [...new Set([...tags, h.innerText])] : tags
    )
    }

  16. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions bookmarks-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -7,9 +7,6 @@

    function getBookmarks(dts, tags = []) {
    return dts.flatMap(function (dt) {
    /**
    * @type HTMLAnchorElement
    */
    const anchor = dt.querySelector(aPath)
    if (!anchor) {
    const tag = dt.querySelector(hPath).innerText
  17. Andrew Luca revised this gist Feb 22, 2021. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions bookmarks-to-csv.js
    Original 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 = new Date(Number(anchor.getAttribute('add_date')) * 1000)
    const date = anchor.getAttribute('add_date')
    const Created = date ? new Date(Number(date) * 1000) : new Date()
    return {
    Name: anchor.innerText,
    Created: `${dateF.format(date)} ${hourF.format(date)}`,
    Created: `${dateF.format(Created)} ${hourF.format(Created)}`,
    Tags: tags.join(', '),
    Url: encodeURI(anchor.href),
    }
  18. Andrew Luca renamed this gist Feb 21, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  19. Andrew Luca revised this gist Feb 21, 2021. 1 changed file with 11 additions and 11 deletions.
    22 changes: 11 additions & 11 deletions bookmarklet-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,15 @@
    (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' })
    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.trim().toLowerCase().split(' ').join('-')
    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: anchor.href,
    Url: encodeURI(anchor.href),
    }
    })
    }
    @@ -33,8 +33,8 @@
    e.Name,
    e.Created,
    e.Tags,
    encodeURI(e.Url),
    ].map(f => JSON.stringify(f.replace(/"/g, `""`))).join(','))
    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))
    }

    let bookmarks = getBookmarks([document.body])
    let csvString = arrayToCsv(bookmarks)
    const bookmarks = getBookmarks([document.body])
    const csvString = arrayToCsv(bookmarks)

    downloadString(csvString)
    })()
  20. Andrew Luca revised this gist Feb 21, 2021. 1 changed file with 54 additions and 53 deletions.
    107 changes: 54 additions & 53 deletions bookmarklet-to-csv.js
    Original file line number Diff line number Diff line change
    @@ -1,53 +1,54 @@
    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)

    (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)
    })()
  21. Andrew Luca revised this gist Feb 21, 2021. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions bookmarklet-to-csv.js
    Original 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)).join(','))

    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.download = "Bookmarks.csv"
    a.click()
    window.setTimeout(() => window.URL.revokeObjectURL(a.href))
    }
  22. Andrew Luca created this gist Feb 21, 2021.
    46 changes: 46 additions & 0 deletions bookmarklet-to-csv.js
    Original 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)