Public
Edited
Mar 16
Paused
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
entries = parseChangelog(await fetch(url).then(r => r.text()))
Insert cell
entriesInRange = !versionRange ? entries : entries.filter(d => d.version && semver.satisfies(d.version, versionRange))
Insert cell
params = Object.fromEntries(new URL(document.baseURI).searchParams)
Insert cell
Insert cell
Insert cell
semver = (await import("https://esm.sh/semver@7.7.1")).default
Insert cell
function parseChangelog(text) {
let version = null;
let category = null;
const entries = [];
for(const line of text.split(/\n+/).filter(d => d.trim())) {
switch(line.match(/^[^ ]+ /)?.[0]) {
case "# ": continue;
case "## ": version = line.slice(3); category = null; continue;
case "### ": category = line.slice(4); continue;
case "- ": {
const _line = line.slice(2);
const split = _line.match(/^[a-z\s]+: /)?.[0].length;
const type = split ? _line.slice(0, split - 2).trim() : null;
const content = split ? _line.slice(split) : _line;
entries.push({version, category, type, content});
break;
}
default:
entries.push({version, category, type: null, content: line});
}
}
return entries;
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more