Skip to content

Instantly share code, notes, and snippets.

@devster31
Last active March 19, 2023 01:31
Embed
What would you like to do?
Bookmark parser for the NETSCAPE-Bookmark-file-1 format in node. Don't hesitate to comment with feedback.
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<!-- This is an automatically generated file.
It will be read and overwritten.
Do Not Edit! -->
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
<DT><A HREF="https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html#//apple_ref/doc/-%20uid/TP40014508" ADD_DATE="1414706885" PRIVATE="0" TAGS="javascript,mac,osx,yosemite">JavaScript for Automation Release Notes</A>
<DD>This article describes JavaScript for Automation, a new feature in OS X Yosemite.
<DT><A HREF="https://rails-assets.org/" ADD_DATE="1414632840" PRIVATE="0" TAGS="ruby,bundler,bower,development">Rails Assets</A>
<DD>"Rails Assets is the frictionless proxy between Bundler and Bower. It automatically converts the packaged components into gems that are easily droppable into your asset pipeline and stay up to date."
<DT><A HREF="http://css-tricks.com/mega-list-svg-information/" ADD_DATE="1414511531" PRIVATE="0" TAGS="svg,reference">A Compendium of SVG Information | CSS-Tricks</A>
<DT><A HREF="http://www.nbcnews.com/pop-culture/movies/zach-braff-sold-his-movie-kickstarter-backers-await-rewards-n14031" ADD_DATE="1413224537" PRIVATE="0" TAGS="kickstarter,jasongarber,zachbraff">Zach Braff Sold His Movie, Kickstarter Backers Await Rewards - NBC News.com</A>
<DT><A HREF="http://blog.sourcing.io/structuring-sinatra" ADD_DATE="1412913363" PRIVATE="0" TAGS="ruby,sinatra,tutorial">Structuring Sinatra Applications</A>
<DT><A HREF="http://joshsymonds.com/blog/2012/07/04/rails-concerns-ii-taggable/" ADD_DATE="1412871378" PRIVATE="0" TAGS="ruby,development,activerecord,concerns">Rails Concerns II: Taggable</A>
<DT><A HREF="https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns" ADD_DATE="1412871345" PRIVATE="0" TAGS="ruby,activerecord,development">Put chubby models on a diet with concerns</A>
<DT><A HREF="http://www.brentmc79.com/posts/polymorphic-many-to-many-associations-in-rails" ADD_DATE="1412870458" PRIVATE="0" TAGS="ruby,polymorphism,activerecord,tutorial,development">Polymorphic many-to-many associations in Rails</A>
<DT><A HREF="http://youmightnotneedjquery.com/#parse_html" ADD_DATE="1412348136" PRIVATE="0" TAGS="javascript,development,reference">You Might Not Need jQuery</A>
<DT><A HREF="http://fontfamily.io/" ADD_DATE="1412085559" PRIVATE="0" TAGS="@font-face,os,typography">fontfamily.io</A>
<DD>Compatibility tables for default local fonts.
<DT><H3 ADD_DATE="1461089902" LAST_MODIFIED="1461089903">medicina</H3>
<DL><p>
<DT><A HREF="http://www.cdc.gov/getsmart/community/for-hcp/outpatient-hcp/pediatric-treatment-rec.html" ADD_DATE="1461089902" LAST_MODIFIED="1461089903">Get Smart About Antibiotics | Pediatric Treatment Recommendations | CDC</A>
<DD>Antibiotic prescribing guidelines for children in outpatient settings are to ensure appropriate treatment of common illnesses and improve patient outcomes.
<DT><A HREF="http://www.cdc.gov/getsmart/community/for-hcp/outpatient-hcp/adult-treatment-rec.html" ADD_DATE="1461089903" LAST_MODIFIED="1461089903">Get Smart About Antibiotics | Adult Treatment Recommendations | CDC</A>
<DD>Antibiotic prescribing guidelines for adults in outpatient settings are used to ensure appropriate treatment of common illnesses and improve patient outcomes.
<DT><A HREF="http://youmightnotneedjquery.com/#parse_html" ADD_DATE="1412348136" PRIVATE="0" TAGS="javascript,development,reference">You Might Not Need jQuery</A>
<DT><H3 ADD_DATE="1461089902" LAST_MODIFIED="1461089903">medicina_nest</H3>
<DL><p>
<DT><A HREF="http://www.nbcnews.com/pop-culture/movies/zach-braff-sold-his-movie-kickstarter-backers-await-rewards-n14031" ADD_DATE="1413224537" PRIVATE="0" TAGS="kickstarter,jasongarber,zachbraff">Zach Braff Sold His Movie, Kickstarter Backers Await Rewards - NBC News.com</A>
<DT><A HREF="http://youmightnotneedjquery.com/#parse_html" ADD_DATE="1412348136" PRIVATE="0" TAGS="javascript,development,reference">You Might Not Need jQuery</A>
</DL><p>
</DL><p>
</DL><p>
[
{
"description": "This article describes JavaScript for Automation, a new feature in OS X Yosemite.",
"title": "JavaScript for Automation Release Notes",
"url": "https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html#//apple_ref/doc/-%20uid/TP40014508",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"javascript",
"mac",
"osx",
"yosemite"
],
"last_modified": null,
"add_date": "2014-10-30T22:08:05.000Z"
},
{
"description": "\"Rails Assets is the frictionless proxy between Bundler and Bower. It automatically converts the packaged components into gems that are easily droppable into your asset pipeline and stay up to date.\"",
"title": "Rails Assets",
"url": "https://rails-assets.org/",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"ruby",
"bundler",
"bower",
"development"
],
"last_modified": null,
"add_date": "2014-10-30T01:34:00.000Z"
},
{
"description": "",
"title": "A Compendium of SVG Information | CSS-Tricks",
"url": "http://css-tricks.com/mega-list-svg-information/",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"svg",
"reference"
],
"last_modified": null,
"add_date": "2014-10-28T15:52:11.000Z"
},
{
"description": "",
"title": "Zach Braff Sold His Movie, Kickstarter Backers Await Rewards - NBC News.com",
"url": "http://www.nbcnews.com/pop-culture/movies/zach-braff-sold-his-movie-kickstarter-backers-await-rewards-n14031",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"kickstarter",
"jasongarber",
"zachbraff"
],
"last_modified": null,
"add_date": "2014-10-13T18:22:17.000Z"
},
{
"description": "",
"title": "Structuring Sinatra Applications",
"url": "http://blog.sourcing.io/structuring-sinatra",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"ruby",
"sinatra",
"tutorial"
],
"last_modified": null,
"add_date": "2014-10-10T03:56:03.000Z"
},
{
"description": "",
"title": "Rails Concerns II: Taggable",
"url": "http://joshsymonds.com/blog/2012/07/04/rails-concerns-ii-taggable/",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"ruby",
"development",
"activerecord",
"concerns"
],
"last_modified": null,
"add_date": "2014-10-09T16:16:18.000Z"
},
{
"description": "",
"title": "Put chubby models on a diet with concerns",
"url": "https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"ruby",
"activerecord",
"development"
],
"last_modified": null,
"add_date": "2014-10-09T16:15:45.000Z"
},
{
"description": "",
"title": "Polymorphic many-to-many associations in Rails",
"url": "http://www.brentmc79.com/posts/polymorphic-many-to-many-associations-in-rails",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"ruby",
"polymorphism",
"activerecord",
"tutorial",
"development"
],
"last_modified": null,
"add_date": "2014-10-09T16:00:58.000Z"
},
{
"description": "",
"title": "You Might Not Need jQuery",
"url": "http://youmightnotneedjquery.com/#parse_html",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"javascript",
"development",
"reference"
],
"last_modified": null,
"add_date": "2014-10-03T14:55:36.000Z"
},
{
"description": "Compatibility tables for default local fonts.",
"title": "fontfamily.io",
"url": "http://fontfamily.io/",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
}
],
"tags": [
"@font-face",
"os",
"typography"
],
"last_modified": null,
"add_date": "2014-09-30T13:59:19.000Z"
},
{
"description": "Antibiotic prescribing guidelines for children in outpatient settings are to ensure appropriate treatment of common illnesses and improve patient outcomes.",
"title": "Get Smart About Antibiotics | Pediatric Treatment Recommendations | CDC",
"url": "http://www.cdc.gov/getsmart/community/for-hcp/outpatient-hcp/pediatric-treatment-rec.html",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
},
{
"name": "medicina",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 2
}
],
"tags": [],
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z"
},
{
"description": "Antibiotic prescribing guidelines for adults in outpatient settings are used to ensure appropriate treatment of common illnesses and improve patient outcomes.",
"title": "Get Smart About Antibiotics | Adult Treatment Recommendations | CDC",
"url": "http://www.cdc.gov/getsmart/community/for-hcp/outpatient-hcp/adult-treatment-rec.html",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
},
{
"name": "medicina",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 2
}
],
"tags": [],
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:23.000Z"
},
{
"description": "",
"title": "You Might Not Need jQuery",
"url": "http://youmightnotneedjquery.com/#parse_html",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
},
{
"name": "medicina",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 2
}
],
"tags": [
"javascript",
"development",
"reference"
],
"last_modified": null,
"add_date": "2014-10-03T14:55:36.000Z"
},
{
"description": "",
"title": "Zach Braff Sold His Movie, Kickstarter Backers Await Rewards - NBC News.com",
"url": "http://www.nbcnews.com/pop-culture/movies/zach-braff-sold-his-movie-kickstarter-backers-await-rewards-n14031",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
},
{
"name": "medicina",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 2
},
{
"name": "medicina_nest",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 3
}
],
"tags": [
"kickstarter",
"jasongarber",
"zachbraff"
],
"last_modified": null,
"add_date": "2014-10-13T18:22:17.000Z"
},
{
"description": "",
"title": "You Might Not Need jQuery",
"url": "http://youmightnotneedjquery.com/#parse_html",
"categories": [
{
"name": "Bookmarks",
"last_modified": null,
"add_date": null,
"level": 1
},
{
"name": "medicina",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 2
},
{
"name": "medicina_nest",
"last_modified": "2016-04-19T18:18:23.000Z",
"add_date": "2016-04-19T18:18:22.000Z",
"level": 3
}
],
"tags": [
"javascript",
"development",
"reference"
],
"last_modified": null,
"add_date": "2014-10-03T14:55:36.000Z"
}
]
var cli = process.argv.slice(2)
var path = require('path')
var fs = require('fs')
var cheerio = require('cheerio')
var $ = cheerio.load(fs.readFileSync(path.resolve(__dirname, cli[0])))
function getCategories($a) {
var $node = $a.closest('DL').prev();
var title = $node.text();
var add_date = $node.attr("add_date");
var last_modified = $node.attr("last_modified");
if ($node.length > 0 && title.length > 0) {
return [{
'name': title,
'last_modified': typeof last_modified === "undefined" ? null : last_modified ,
'add_date': typeof add_date === "undefined" ? null : add_date,
}].concat(getCategories($node));
} else {
return [];
}
}
var jsonbmArray = []
$('a').each(function(index, a) {
let $a = $(a)
let add_date = $a.attr('add_date')
let last_modified = $a.attr('last_modified')
let description = $a.next('dd').text().split("\n")[0] // ugly but works
let categories = getCategories($a)
// add level information
let new_categories = categories.reverse().map(function(currentValue, index) {
return currentValue['level'] = index + 1, currentValue
})
try {
var tags = $a.attr('tags').split(',') || []
} catch(e) {
var tags = []
}
let jsonbm = {
'description': description,
'title': $a.text(),
'url': $a.attr('href'),
'categories': categories,
'tags': tags,
'last_modified': typeof last_modified === "undefined" ? null : last_modified ,
'add_date': typeof add_date === "undefined" ? null : add_date,
}
jsonbmArray.push(jsonbm)
})
fs.writeFileSync(path.resolve(__dirname, cli[1]), JSON.stringify(jsonbmArray, null, 4))
@Tower450
Copy link

you are a genius thanks a lot.

@trollichon
Copy link

Thanks a lot. Very useful.

Strangely I had to modify line 28
let description = $a.next('dd').text().split("\n")[0] // ugly but works
into
let description = $a.parent().next('dd').text().split("\n")[0] // ugly but works
to get notes|description parsed.
Happy day.

@murtuzaalisurti
Copy link

made a bookmark to PDF converter using your bookmark parser https://bookmarks-pdf.herokuapp.com/
GitHub repo:- https://github.com/murtuzaalisurti/bookmarks

Thank You!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment