Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e40fade
fix #53 overflow-wrap:anywhere on card titles
braver Jul 28, 2025
39bb97b
fix #54 make inline code wrap, code blocks scroll
braver Jul 28, 2025
7d4c708
further anti-blink optimization
braver Jul 28, 2025
c7e509d
move images from static -> assets
braver Jul 28, 2025
c13dcb8
move the search index to its own dir
braver Jul 28, 2025
31d7765
cache bust js/css by moving the static dir
braver Jul 28, 2025
33f97c2
revert instead of setting the viz value
braver Jul 28, 2025
8672d71
fix #37 clickable authors in lists
braver Jul 28, 2025
f5eaddb
start building static libs page
braver Jul 28, 2025
254977f
link to libs in footer
braver Jul 28, 2025
2450ea3
start adding shields
braver Jul 28, 2025
043068e
maybe just remove this, it's not up to date
braver Jul 29, 2025
fc1e507
library links and shields
braver Jul 30, 2025
d4b3564
add simplified libs search
braver Jul 30, 2025
b7bd3b8
share search value processing
braver Jul 30, 2025
c795518
pagination to reuse active instance of List
braver Jul 30, 2025
102f984
docs
braver Jul 30, 2025
d9aa9b9
Merge branch 'static-libs-page' into ongoing-developments
braver Jul 30, 2025
b94fbb1
fixup: files in search/ should not be copied
braver Jul 30, 2025
16a66fb
move libs position in the footer
braver Jul 30, 2025
c59282f
handle *-x64 etc in platform
braver Jul 30, 2025
562168a
add recommended stylistic eslint rules
braver Jul 30, 2025
ec15a16
modify list heading on libraries search
braver Jul 30, 2025
1133a6e
add link to packages from libraries
braver Jul 30, 2025
e819f7b
link to source/registry for libraries
braver Jul 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 111 additions & 68 deletions .eleventy.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,65 @@
const fs = require("fs");
const fs = require('fs')
const execSync = require('child_process').execSync

const gitHash = execSync('git rev-parse --short HEAD').toString().trim()

// rename macos and remove */any
function cleanupPlatforms(platforms) {
return platforms
.filter(platform => platform !== "*")
.map(platform => platform === "osx" ? "macos" : platform);
.filter(platform => platform !== '*')
.map(platform => platform === 'osx' ? 'macos' : platform)
}

// author can be string or array, convert to all arrays
function cleanupAuthors(author) {
if (typeof author === 'string') {
return [author];
return [author]
}
return author;
return author
}

function minimalPackage(pkg) {
// Create a new array of releases with cleaned platforms
const releases = (pkg.releases || []).map(release => ({
...release,
platforms: cleanupPlatforms(release.platforms)
}));
platforms: cleanupPlatforms(release.platforms),
}))

// sort releases by date, newest first
// secondary by .sublime_text. strip the leading non-digit from that string first, reverse alphabetical
releases.sort((a, b) => {
const dateA = new Date(a.date ?? '1970-01-01 00:00:00');
const dateB = new Date(b.date ?? '1970-01-01 00:00:00');
const dateA = new Date(a.date ?? '1970-01-01 00:00:00')
const dateB = new Date(b.date ?? '1970-01-01 00:00:00')
if (dateA.getTime() !== dateB.getTime()) {
return dateB - dateA; // Newest first
return dateB - dateA // Newest first
}
// Secondary: compare .sublime_text, strip leading non-digit, reverse alphabetical
const verA = (a.sublime_text || '').replace(/^[^\d]*/, '');
const verB = (b.sublime_text || '').replace(/^[^\d]*/, '');
if (verA > verB) return -1;
if (verA < verB) return 1;
return 0;
});
const verA = (a.sublime_text || '').replace(/^[^\d]*/, '')
const verB = (b.sublime_text || '').replace(/^[^\d]*/, '')
if (verA > verB) return -1
if (verA < verB) return 1
return 0
})

// Split releases with same sublime build and same platform set.
// As we're sorted, just keep the first one we see.
const seen = new Set();
const dedupedReleases = [];
const otherReleases = [];
const seen = new Set()
const dedupedReleases = []
const otherReleases = []
for (const release of releases) {
const key = `${release.sublime_text}|${[...release.platforms].sort().join('|')}`;
const key = `${release.sublime_text}|${[...release.platforms].sort().join('|')}`
if (!seen.has(key)) {
seen.add(key);
dedupedReleases.push(release);
} else {
otherReleases.push(release);
seen.add(key)
dedupedReleases.push(release)
}
else {
otherReleases.push(release)
}
}

// Remove duplicate platforms
const allPlatforms = releases.flatMap(release => release.platforms);
const uniquePlatforms = Array.from(new Set(allPlatforms));
const allPlatforms = releases.flatMap(release => release.platforms)
const uniquePlatforms = Array.from(new Set(allPlatforms))

return {
name: pkg.name,
Expand All @@ -64,16 +68,45 @@ function minimalPackage(pkg) {
releases: dedupedReleases,
otherReleases,
labels: pkg.labels,
platforms: uniquePlatforms
platforms: uniquePlatforms,
}
}

function minimalLib(pkg) {
const allPlatforms = pkg.releases.flatMap((release) => {
if (typeof release.platforms !== 'undefined') {
return release.platforms
}
return []
})
const uniquePlatforms = Array.from(new Set(allPlatforms))

const homepage = pkg.issues.replace('/issues', '')
let gh_path = ''
if (homepage.startsWith('https://github.com/')) {
gh_path = homepage.replace('https://github.com/', '')
}

return {
name: pkg.name,
homepage: homepage,
path: gh_path,
author: cleanupAuthors(pkg.author),
description: pkg.description,
releases: pkg.releases,
labels: [],
platforms: uniquePlatforms,
}
}

module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("static");
eleventyConfig.addPassthroughCopy('assets')
eleventyConfig.addPassthroughCopy({ static: 'static_' + gitHash })

const data = JSON.parse(fs.readFileSync("workspace.json", "utf8"));
const libraries = JSON.parse(fs.readFileSync('libraries.json', 'utf8'))
const workspace = JSON.parse(fs.readFileSync('workspace.json', 'utf8'))
// eslint-disable-next-line no-unused-vars
const live_packages = Object.entries(data.packages).map(([id, pkg]) => pkg).filter(pkg => !pkg.removed);
const live_packages = Object.entries(workspace.packages).map(([id, pkg]) => pkg).filter(pkg => !pkg.removed)

// if readme is in pkg
// transform some links
Expand All @@ -87,75 +120,85 @@ module.exports = function (eleventyConfig) {
// => https://bitbucket.org/JeisonJHA/sublime-delphi-language/src/master/README.md
//
// and store the under readme_url
eleventyConfig.addCollection("packages", () => {
return live_packages.map(pkg => {
let readme_url = pkg.readme;
eleventyConfig.addCollection('packages', () => {
return live_packages.map((pkg) => {
let readme_url = pkg.readme
if (typeof readme_url === 'string') {
// GitHub raw to blob
readme_url = readme_url.replace(
/^https:\/\/raw\.githubusercontent\.com\/([^/]+)\/([^/]+)\/([^/]+)\/(.+)$/,
'https://github.com/$1/$2/blob/$3/$4'
);
'https://github.com/$1/$2/blob/$3/$4',
)
// GitLab raw to blob
readme_url = readme_url.replace(
/^https:\/\/gitlab\.com\/([^/]+)\/([^/]+)\/-\/raw\/([^/]+)\/(.+)$/,
'https://gitlab.com/$1/$2/-/blob/$3/$4'
);
'https://gitlab.com/$1/$2/-/blob/$3/$4',
)
// Bitbucket raw to src
readme_url = readme_url.replace(
/^https:\/\/bitbucket\.org\/([^/]+)\/([^/]+)\/raw\/([^/]+)\/(.+)$/,
'https://bitbucket.org/$1/$2/src/$3/$4'
);
'https://bitbucket.org/$1/$2/src/$3/$4',
)
}
return {
...pkg,
...minimalPackage(pkg),
...(readme_url !== pkg.readme ? { readme_url } : {})
};
});
});
...(readme_url !== pkg.readme ? { readme_url } : {}),
}
})
})

eleventyConfig.addCollection("minimal_packages", () => {
eleventyConfig.addCollection('minimal_packages', () => {
return live_packages.map(pkg => ({
description: pkg.description,
...minimalPackage(pkg)
})).sort((a, b) => (b.stars ?? 0) - (a.stars ?? 0));
});
...minimalPackage(pkg),
})).sort((a, b) => (b.stars ?? 0) - (a.stars ?? 0))
})

eleventyConfig.addCollection("updated_packages", () => {
eleventyConfig.addCollection('updated_packages', () => {
return live_packages.map(pkg => ({
last_modified: pkg.last_modified,
...minimalPackage(pkg)
...minimalPackage(pkg),
})).sort((a, b) => {
return new Date(b.last_modified ?? '1970-01-01 00:00:00') - new Date(a.last_modified ?? '1970-01-01 00:00:00')
}).slice(0,9);
});
}).slice(0, 9)
})

eleventyConfig.addCollection("newest_packages", () => {
eleventyConfig.addCollection('newest_packages', () => {
return live_packages.map(pkg => ({
created_at: pkg.created_at,
...minimalPackage(pkg)
...minimalPackage(pkg),
})).sort((a, b) => {
return new Date(b.created_at ?? '1970-01-01 00:00:00') - new Date(a.created_at ?? '1970-01-01 00:00:00')
}).slice(0,9);
});
}).slice(0, 9)
})

eleventyConfig.addCollection('libraries', () => {
return libraries.libraries.map(lib => ({
...minimalLib(lib),
}))
})

// simple to date string for some dates without times
eleventyConfig.addFilter("date_format", (date) => {
if (typeof date !== "string" ) return date;
return (new Date(date)).toDateString();
});

eleventyConfig.addFilter("stars_format", (count) => {
const starsFormatter = new Intl.NumberFormat("en", { notation: "compact" });
return starsFormatter.format(count);
eleventyConfig.addFilter('date_format', (date) => {
if (typeof date !== 'string') return date
return (new Date(date)).toDateString()
})

eleventyConfig.addFilter('stars_format', (count) => {
const starsFormatter = new Intl.NumberFormat('en', { notation: 'compact' })
return starsFormatter.format(count)
})

eleventyConfig.addFilter('bust', (path) => {
return path.replace('static/', 'static_' + gitHash + '/')
})

return {
dir: {
input: ".",
output: "_site",
input: '.',
output: '_site',
},
passthroughFileCopy: true
};
};
passthroughFileCopy: true,
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ _site/*
# Database #
######################
workspace.json
libraries.json
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
build:
npm install
# workspace from https://github.com/packagecontrol/thecrawl
curl -o workspace.json -L "https://github.com/packagecontrol/thecrawl/releases/download/crawler-status/workspace.json"
# libraries repository from https://github.com/packagecontrol/channel
curl -o libraries.json -L "https://raw.githubusercontent.com/packagecontrol/channel/refs/heads/main/repository.json"
npx @11ty/eleventy
curl -o _site/channel.json -L "https://github.com/packagecontrol/thecrawl/releases/download/the-channel/channel.json"
curl -o _site/channel_st3.json -L "https://github.com/packagecontrol/thecrawl/releases/download/the-st3-channel/channel_st3.json"
Expand Down
7 changes: 6 additions & 1 deletion _includes/footer.njk
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% import "packages/macros.njk" as pack %}

<footer>
<img src="/static/logo.webp" width="80" height="80" alt="Package Control R logo">
<img src="/assets/logo.webp" width="80" height="80" alt="Package Control R logo">
<h2>Package Control</h2>

<p>
Expand All @@ -15,6 +15,11 @@
<nav>
<a href="https://github.com/wbond/package_control_channel?tab=readme-ov-file#package-control-default-channel">Submitting packages</a>
<a href="https://packagecontrol.io/docs/usage">Using package control</a>
{% if page.url == "/libraries/" %}
<a href="/">Packages</a>
{% else %}
<a href="/libraries">Libraries</a>
{% endif %}
<a href="https://github.com/packagecontrol/thecrawl/tree/gh-pages">This website on GitHub</a>
</nav>

Expand Down
41 changes: 4 additions & 37 deletions _includes/head.njk
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,15 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

{# handle color scheme without delay #}
<script>
(function(){
const system_theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
const user_pref = localStorage.getItem('theme');
document.documentElement.setAttribute('data-theme', user_pref ?? system_theme);
})();
</script>
{% include "scripts.njk" %}

{# while initializing search, hide package listings,
and change the h1 to indicate this state #}
<script>
(function(){
const q = new URLSearchParams(location.search).get('q');
if (!q) {
return;
};

const setContent = () => {
document.querySelector('[name=q]').value = q;
document.querySelector('h1').innerText = 'Searching…';
}

window.addEventListener('DOMContentLoaded', setContent);

const root = document.documentElement;
root.classList.add('initializing');
root.addEventListener('search-is-done', () => {
root.classList.remove('initializing');
window.removeEventListener('DOMContentLoaded', setContent);
});

})();
</script>

<link rel="stylesheet" href="/static/styles.css">
<link rel="icon" href="/static/favicon.ico">
<link rel="stylesheet" href="{{ '/static/styles.css' | bust}}">
<link rel="icon" href="/assets/favicon.ico">

<meta property="og:title" content="{{ title or 'Package Control R' }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ 'http://packages.sublimetext.io' ~ page.url }}">
<meta property="og:image" content="http://packages.sublimetext.io/static/og.png">
<meta property="og:image" content="http://packages.sublimetext.io/assets/og.png">
<meta property="og:width" content="1200">
<meta property="og:height" content="630">
<meta property="og:description" content="{{ descr }}">
Expand Down
2 changes: 1 addition & 1 deletion _includes/layout.njk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

{% include "footer.njk" %}

<script src="/static/theme.js" type="module"></script>
<script src="{{ '/static/theme.js' | bust }}" type="module"></script>
</body>
</html>
Loading