Skip to content

Commit 08c0ccf

Browse files
committed
Update readme generation
1 parent 08197e3 commit 08c0ccf

File tree

2 files changed

+119
-26
lines changed

2 files changed

+119
-26
lines changed

.github/main.swift

+119-25
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,33 @@
99
import Foundation
1010

1111
let header = """
12-
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine)
12+
<div align="center">
13+
<a href="https://vshymanskyy.github.io/StandWithUkraine">
14+
<img src="https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg" alt="Stand With Ukraine" />
15+
</a>
16+
17+
<img src="./icons/icon.png" width="160" height="160">
18+
<h1>Awesome macOS Open Source Applications</h1>
19+
<p>A curated list of open source applications for macOS</p>
20+
<p>
21+
<a href="https://github.com/sindresorhus/awesome"><img alt="Awesome" src="https://awesome.re/badge.svg" /></a>
22+
<a href="https://gitter.im/open-source-mac-os-apps/Lobby"><img alt="Join the chat at gitter" src="https://badges.gitter.im/Join%20Chat.svg" /></a>
23+
<a href="https://t.me/opensourcemacosapps"><img alt="Telegram Channel" src="https://img.shields.io/badge/Telegram-Channel-blue.svg" /></a>
24+
</p>
25+
</div>
1326
1427
<p align="center">
15-
<img src="./icons/icon.png">
16-
</p>
17-
18-
# Awesome macOS open source applications
19-
20-
<p align="left">
21-
<a href="https://github.com/sindresorhus/awesome"><img alt="Awesome" src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" /></a>
22-
<a href="https://gitter.im/open-source-mac-os-apps/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link"><img alt="Join the chat at gitter" src="https://badges.gitter.im/Join%20Chat.svg" /></a>
28+
<a href="#audio">Audio</a> •
29+
<a href="#backup">Backup</a> •
30+
<a href="#browser">Browser</a> •
31+
<a href="#chat">Chat</a> •
32+
<a href="#cryptocurrency">Crypto</a> •
33+
<a href="#database">Database</a> •
34+
<a href="#development">Dev</a> •
35+
<a href="#editors">Editors</a> •
36+
<a href="#graphics">Graphics</a> •
37+
<a href="#productivity">Productivity</a> •
38+
<a href="#utilities">Utilities</a>
2339
</p>
2440
2541
List of awesome open source applications for macOS. This list contains a lot of native, and cross-platform apps. The main goal of this repository is to find free open source apps and start contributing. Feel free to [contribute](CONTRIBUTING.md) to the list, any suggestions are welcome!
@@ -109,6 +125,8 @@ You can see in which language an app is written. Currently there are following l
109125

110126
let footer = """
111127
128+
<div align="right"><a href="#contents">⬆️ Back to Top</a></div>
129+
112130
## Contributors
113131
114132
Thanks to all the people who contribute:
@@ -248,27 +266,43 @@ class ReadmeGenerator {
248266
print("Start iteration....")
249267

250268
for category in categories {
251-
readmeString.append(String.enter + String.section + String.space + category.title + String.enter)
252-
var categoryApplications = applications.filter({ $0.categories.contains(category.id) })
269+
// Add category header with emoji and count
270+
let categoryApps = applications.filter({ $0.categories.contains(category.id) })
271+
let categoryCount = categoryApps.count
272+
let categoryEmoji = getCategoryEmoji(category.id)
273+
readmeString.append(String.enter + String.section + String.space + categoryEmoji + String.space + category.title + String.space + "(\(categoryCount))" + String.enter)
274+
275+
var categoryApplications = categoryApps
253276
categoryApplications = categoryApplications.sorted(by: { $0.title < $1.title })
254277

255278
for application in categoryApplications {
256279
readmeString.append(application.markdownDescription())
257280
readmeString.append(String.enter)
258281
}
259282

283+
// Add "Back to Top" link at the end of each category
284+
readmeString.append("<div align=\"right\"><a href=\"#contents\">⬆️ Back to Top</a></div>" + String.enter)
285+
260286
var subcategories = subcategories.filter({ $0.parent == category.id })
261287
guard subcategories.count > 0 else { continue }
262288
subcategories = subcategories.sorted(by: { $0.title < $1.title })
263289
for subcategory in subcategories {
264-
readmeString.append(String.enter + String.subsection + String.space + subcategory.title + String.enter)
265-
var categoryApplications = applications.filter({ $0.categories.contains(subcategory.id) })
290+
// Add subcategory header with emoji and count
291+
let subcategoryApps = applications.filter({ $0.categories.contains(subcategory.id) })
292+
let subcategoryCount = subcategoryApps.count
293+
let subcategoryEmoji = getCategoryEmoji(subcategory.id)
294+
readmeString.append(String.enter + String.subsection + String.space + subcategoryEmoji + String.space + subcategory.title + String.space + "(\(subcategoryCount))" + String.enter)
295+
296+
var categoryApplications = subcategoryApps
266297
categoryApplications = categoryApplications.sorted(by: { $0.title < $1.title })
267298

268299
for application in categoryApplications {
269300
readmeString.append(application.markdownDescription())
270301
readmeString.append(String.enter)
271302
}
303+
304+
// Add "Back to Top" link at the end of each subcategory
305+
readmeString.append("<div align=\"right\"><a href=\"#contents\">⬆️ Back to Top</a></div>" + String.enter)
272306
}
273307
}
274308
print("Finish iteration...")
@@ -298,22 +332,82 @@ extension JSONApplication {
298332
languages.append("![\(lang)\(String.iconPrefix)] ")
299333
}
300334

301-
markdownDescription.append("- [\(self.title)](\(self.repoURL)) - \(self.shortDescription) \(languages)")
302-
/*
303-
if self.screenshots.count > 0 {
304-
var screenshotsString = String.empty
305-
screenshotsString += (String.space + Constants.detailsBeginString + String.space)
306-
self.screenshots.forEach({
307-
screenshotsString += (String.space + (NSString(format: Constants.srcLinePattern as NSString, $0 as CVarArg) as String) + String.space)
308-
})
309-
screenshotsString += (String.space + Constants.detailsEndString + String.space)
310-
markdownDescription.append(screenshotsString)
311-
}
312-
*/
335+
// Create a collapsible section for each application
336+
markdownDescription.append("<details>")
337+
markdownDescription.append("<summary><b>[\(self.title)](\(self.repoURL))</b> - \(self.shortDescription)</summary>")
338+
markdownDescription.append("<p>")
339+
340+
// Add languages
341+
markdownDescription.append("<b>Languages:</b> \(languages)<br>")
342+
343+
// Add official site if available
344+
if !self.officialSite.isEmpty {
345+
markdownDescription.append("<b>Website:</b> <a href=\"\(self.officialSite)\">\(self.officialSite)</a><br>")
346+
}
347+
348+
// Add screenshots with lazy loading to improve page load performance
349+
if self.screenshots.count > 0 {
350+
markdownDescription.append("<b>Screenshots:</b><br>")
351+
352+
// Limit to first 3 screenshots to reduce load time
353+
let limitedScreenshots = self.screenshots.count > 3 ? Array(self.screenshots.prefix(3)) : self.screenshots
354+
355+
limitedScreenshots.forEach({
356+
markdownDescription.append("<img src='\($0)' width='400' loading='lazy'/><br>")
357+
})
358+
359+
// Add a note if there are more screenshots
360+
if self.screenshots.count > 3 {
361+
markdownDescription.append("<em>(\(self.screenshots.count - 3) more screenshots available in the repository)</em><br>")
362+
}
363+
}
364+
365+
markdownDescription.append("</p>")
366+
markdownDescription.append("</details>")
367+
313368
return markdownDescription
314369
}
315370
}
316371

372+
// Helper function to get emoji for categories
373+
func getCategoryEmoji(_ categoryId: String) -> String {
374+
switch categoryId {
375+
case "audio": return "🎵"
376+
case "backup": return "💾"
377+
case "browser": return "🌐"
378+
case "chat": return "💬"
379+
case "cryptocurrency": return "💰"
380+
case "database": return "🗄️"
381+
case "development": return "👨‍💻"
382+
case "downloader": return "⬇️"
383+
case "editors": return "📝"
384+
case "extensions": return "🧩"
385+
case "finder": return "🔍"
386+
case "games": return "🎮"
387+
case "graphics": return "🎨"
388+
case "ide": return "💻"
389+
case "images": return "🖼️"
390+
case "keyboard": return "⌨️"
391+
case "mail": return "📧"
392+
case "menubar": return "📊"
393+
case "music": return "🎧"
394+
case "news": return "📰"
395+
case "notes": return "📔"
396+
case "productivity": return "⏱️"
397+
case "security": return "🔒"
398+
case "sharing-files": return "📤"
399+
case "social-networking": return "👥"
400+
case "system": return "⚙️"
401+
case "terminal": return "📺"
402+
case "utilities": return "🛠️"
403+
case "video": return "🎬"
404+
case "vpn--proxy": return "🔐"
405+
case "wallpaper": return "🖥️"
406+
case "window-management": return "🪟"
407+
default: return "📦"
408+
}
409+
}
410+
317411
enum FilePaths: String {
318412
case readme = "./README.md"
319413
case applications = "./applications.json"

.github/workflows/main.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ jobs:
99
steps:
1010
- uses: actions/checkout@v3
1111
- run: swift ./.github/main.swift
12-
- run: chmod +x ./.github/deploy.sh
1312
- run: git config user.name "serhii-londar"
1413
- run: git config user.email "[email protected]"
1514
- run: git add README.md

0 commit comments

Comments
 (0)