nbff-parser
Version:
A simple parser for the Netscape Bookmark file format
77 lines (59 loc) • 1.89 kB
JavaScript
import { joinAttrs } from './attrs.js'
const template = (title, content) => `<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>${title}</H1>
<DL><p>\n${content}</DL><p>\n`
const INDENT = ' '
const pad = lvl => INDENT.repeat(lvl)
// eslint-disable-next-line no-unused-vars
const createItem = ({ description, id, items, pid, title, ...attrs }) => ({
attrs: joinAttrs(attrs),
description,
title
})
const openFolder = (folder, lvl) => {
const { attrs, title } = createItem(folder)
const indent = pad(lvl)
return `${indent}<DT><H3${attrs}>${title}</H3>\n${indent}<DL><p>\n`
}
const closeFolder = lvl => `${pad(lvl)}</DL><p>\n`
const addBookmark = (bookmark, lvl) => {
const { attrs, description, title } = createItem(bookmark)
const indent = pad(lvl)
let result = `${indent}<DT><A${attrs}>${title}</A>\n`
description && (result += `${indent}<DD>${description}\n`)
return result
}
const createContent = items => {
let res = ''
const stack = []
for (let idx = items.length - 1; idx >= 0; idx--) {
stack.push({ item: items[idx], lvl: 0 })
}
while (stack.length) {
const { item, lvl, out } = stack.pop()
if (out) {
res += closeFolder(lvl)
continue
}
const lvlUp = lvl + 1
if (Object.hasOwn(item, 'items')) {
stack.push({ item, lvl: lvlUp, out: true })
for (let idx = item.items.length - 1; idx >= 0; idx--) {
stack.push({ item: item.items[idx], lvl: lvlUp })
}
res += openFolder(item, lvlUp)
} else {
res += addBookmark(item, lvlUp)
}
}
return res
}
export const stringify = ({ items, title }) => {
const content = createContent(items)
return template(title, content)
}