summaryrefslogtreecommitdiff
path: root/docs/src/contribs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/contribs.rs')
-rw-r--r--docs/src/contribs.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/docs/src/contribs.rs b/docs/src/contribs.rs
new file mode 100644
index 00000000..58a730e2
--- /dev/null
+++ b/docs/src/contribs.rs
@@ -0,0 +1,86 @@
+use std::cmp::Reverse;
+use std::collections::HashMap;
+use std::fmt::Write;
+
+use serde::{Deserialize, Serialize};
+
+use crate::{Html, Resolver};
+
+/// Build HTML detailing the contributors between two tags.
+pub fn contributors(resolver: &dyn Resolver, from: &str, to: &str) -> Option<Html> {
+ let staff = ["laurmaedje", "reknih"];
+
+ // Determine number of contributions per person.
+ let mut contributors = HashMap::<String, Contributor>::new();
+ for commit in resolver.commits(from, to) {
+ contributors
+ .entry(commit.author.login.clone())
+ .or_insert_with(|| Contributor {
+ login: commit.author.login,
+ avatar: commit.author.avatar_url,
+ contributions: 0,
+ })
+ .contributions += 1;
+ }
+
+ // Keep only non-staff people.
+ let mut contributors: Vec<_> = contributors
+ .into_values()
+ .filter(|c| !staff.contains(&c.login.as_str()))
+ .collect();
+
+ // Sort by highest number of commits.
+ contributors.sort_by_key(|c| (Reverse(c.contributions), c.login.clone()));
+ if contributors.is_empty() {
+ return None;
+ }
+
+ let mut html = "Thanks to everyone who contributed to this release!".to_string();
+ html += "<ul class=\"contribs\">";
+
+ for Contributor { login, avatar, contributions } in contributors {
+ let login = login.replace('\"', "&quot;").replace('&', "&amp;");
+ let avatar = avatar.replace("?v=", "?s=64&v=");
+ let s = if contributions > 1 { "s" } else { "" };
+ write!(
+ html,
+ r#"<li>
+ <a href="https://github.com/{login}" target="_blank">
+ <img
+ width="64"
+ height="64"
+ src="{avatar}"
+ alt="GitHub avatar of {login}"
+ title="@{login} made {contributions} contribution{s}"
+ crossorigin="anonymous"
+ >
+ </a>
+ </li>"#
+ )
+ .unwrap();
+ }
+
+ html += "</ul>";
+
+ Some(Html::new(html))
+}
+
+#[derive(Debug)]
+struct Contributor {
+ login: String,
+ avatar: String,
+ contributions: usize,
+}
+
+/// A commit on the `typst` repository.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Commit {
+ author: Author,
+}
+
+/// A commit author.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Author {
+ login: String,
+ avatar_url: String,
+}