Skip to content

Instantly share code, notes, and snippets.

@kkirby
Last active September 10, 2020 21:15
Show Gist options
  • Save kkirby/f63c8e696b823248c71230f212674fe7 to your computer and use it in GitHub Desktop.
Save kkirby/f63c8e696b823248c71230f212674fe7 to your computer and use it in GitHub Desktop.
PegJS NETSCAPE Bookmark file parser

This is a simple parser used with PegJS to parse a NETSCAPE-Bookmark-file. I've only tested this with safari export.

You have to remove these tags:

<HTML>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<Title>Bookmarks</Title>
<H1>Bookmarks</H1>
</HTML>

Example valid input:

<!DOCTYPE NETSCAPE-Bookmark-file-1>
<DT><H3 FOLDED>Favorites</H3>
<DL><p>
	<DT><A HREF="....">.....</A>
	<DT><A HREF="....">.....</A>
</DL><p>
<DT><H3 FOLDED>Bookmarks Menu</H3>
<DL><p>
	<DT><H3 FOLDED>ABC</H3>
	<DL><p>
		<DT><A HREF="....">.....</A>
		<DT><A HREF="....">.....</A>
		<DT><A HREF="....">.....</A>
		<DT><H3 FOLDED>ABC</H3>
		<DL><p>
			<DT><A HREF="....">.....</A>
		</DL><p>
	</DL><p>
</DL><p>

Output:

[
   {
      "type": "folder",
      "name": "Favorites",
      "items": [
         {
            "type": "link",
            "url": "....",
            "label": "....."
         },
         {
            "type": "link",
            "url": "....",
            "label": "....."
         }
      ]
   },
   {
      "type": "folder",
      "name": "Bookmarks Menu",
      "items": [
         {
            "type": "folder",
            "name": "ABC",
            "items": [
               {
                  "type": "link",
                  "url": "....",
                  "label": "....."
               },
               {
                  "type": "link",
                  "url": "....",
                  "label": "....."
               },
               {
                  "type": "link",
                  "url": "....",
                  "label": "....."
               },
               {
                  "type": "folder",
                  "name": "ABC",
                  "items": [
                     {
                        "type": "link",
                        "url": "....",
                        "label": "....."
                     }
                  ]
               }
            ]
         }
      ]
   }
]
Document = Doctype _ root:Items _ {
return root;
}
Doctype = "<!DOCTYPE NETSCAPE-Bookmark-file-1>"
TAG_OPEN = "<"
TAG_CLOSE = ">"
BS = "/"
EQ = "="
DT = TAG_OPEN "DT" TAG_CLOSE
DL_START = TAG_OPEN "DL" TAG_CLOSE
DL_END = TAG_OPEN BS "DL" TAG_CLOSE
P = TAG_OPEN "p" TAG_CLOSE
A_OPEN = TAG_OPEN "A" _ "HREF" EQ '"' url:$(! '"' .)+ '"' TAG_CLOSE {
return {url};
}
A_CLOSE = TAG_OPEN BS "A" TAG_CLOSE
A = open:A_OPEN _ label:$(! A_CLOSE .)+ _ A_CLOSE {
return {
...open,
label
}
}
FOLDED_START = TAG_OPEN "H3" _ "FOLDED" _ (! TAG_CLOSE .)* TAG_CLOSE
FOLDED_END = TAG_OPEN BS "H3" TAG_CLOSE
FOLDED = FOLDED_START name:$(! FOLDED_END .)+ FOLDED_END { return name; }
Folder = DT _ name:FOLDED _ DL_START _ P _ items:Items _ DL_END _ P {
return {type:'folder',name,items};
}
Item = _ DT _ base:A _ {
return {
type: 'link',
...base
};
}
Items = items:(_ a:Folder _ { return a; } / _ a: Item _ { return a; } )* {
return items;
}
_ "whitespace"
= [ \t\n\r]* {
return undefined;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment