diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-04-20 14:23:26 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-04-20 14:23:36 +0200 |
| commit | c117e2dc276d19b022abccac0d252bd7fc1cd44e (patch) | |
| tree | 10884ac2ecd4d01053b2d38856c395e2e115775c /docs | |
| parent | 2a682f0008b91e7c33c6e65b3ecfc690268ab405 (diff) | |
List contributors in changelog
Co-Authored-By: Martin Haug <mhaug@live.de>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/Cargo.toml | 1 | ||||
| -rw-r--r-- | docs/src/contribs.rs | 97 | ||||
| -rw-r--r-- | docs/src/general/changelog.md | 6 | ||||
| -rw-r--r-- | docs/src/html.rs | 28 | ||||
| -rw-r--r-- | docs/src/lib.rs | 2 |
5 files changed, 128 insertions, 6 deletions
diff --git a/docs/Cargo.toml b/docs/Cargo.toml index a2e64f99..a5885a8a 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -22,3 +22,4 @@ heck = "0.4" yaml-front-matter = "0.1" unicode_names2 = "0.6.0" once_cell = "1" +ureq = { version = "2.6", features = ["json"] } diff --git a/docs/src/contribs.rs b/docs/src/contribs.rs new file mode 100644 index 00000000..df1d4944 --- /dev/null +++ b/docs/src/contribs.rs @@ -0,0 +1,97 @@ +use std::cmp::Reverse; +use std::collections::HashMap; +use std::fmt::Write; + +use serde::Deserialize; + +use super::Html; + +/// Build HTML detailing the contributors between two tags. +pub fn contributors(from: &str, to: &str) -> Option<Html> { + let staff = ["laurmaedje", "reknih"]; + + let url = format!("https://api.github.com/repos/typst/typst/compare/{from}...{to}"); + let response: Response = ureq::get(&url) + .set("X-GitHub-Api-Version", "2022-11-28") + .call() + .ok()? + .into_json() + .ok()?; + + // Determine number of contributions per person. + let mut contributors = HashMap::<String, Contributor>::new(); + for commit in response.commits { + 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)); + 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('\"', """).replace('&', "&"); + 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, +} + +#[derive(Debug, Deserialize)] +struct Response { + commits: Vec<Commit>, +} + +#[derive(Debug, Deserialize)] +struct Commit { + author: Author, +} + +#[derive(Debug, Deserialize)] +struct Author { + login: String, + avatar_url: String, +} diff --git a/docs/src/general/changelog.md b/docs/src/general/changelog.md index 22f4147b..1b28bc09 100644 --- a/docs/src/general/changelog.md +++ b/docs/src/general/changelog.md @@ -45,6 +45,8 @@ description: | - [Ratios]($type/ratio) can now be multiplied with more types and be converted to [floats]($type/float) with the [`float`]($func/float) function +<contributors from="v0.1.0" to="v0.2.0" /> + ## April 04, 2023 (v0.1.0) - **Breaking changes:** - When using the CLI, you now have to use subcommands: @@ -113,7 +115,7 @@ description: | - Fixed line number in error message for CSV parsing - Fixed invalid autocompletion after certain markup elements -Thanks to everybody who contributed to this release! +<contributors from="v23-03-28" to="v0.1.0" /> ## March 28, 2023 - **Breaking changes:** @@ -153,7 +155,7 @@ Thanks to everybody who contributed to this release! - Links in bibliographies are now affected by link styling - Fixed hovering over comments in web app -Thanks to everybody who contributed to this release! +<contributors from="v23-03-21" to="v23-03-28" /> ## March 21, 2023 - Reference and bibliography management diff --git a/docs/src/html.rs b/docs/src/html.rs index b189a09c..d3566b07 100644 --- a/docs/src/html.rs +++ b/docs/src/html.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use comemo::Prehashed; use md::escape::escape_html; use pulldown_cmark as md; @@ -108,16 +110,21 @@ impl<'a> Handler<'a> { // Rewrite HTML images. md::Event::Html(html) if html.starts_with("<img") => { - let needle = "src=\""; - let offset = html.find(needle).unwrap() + needle.len(); - let len = html[offset..].find('"').unwrap(); - let range = offset..offset + len; + let range = html_attr_range(html, "src").unwrap(); let path = &html[range.clone()]; let mut buf = html.to_string(); buf.replace_range(range, &self.handle_image(path)); *html = buf.into(); } + // Rewrite contributor sectinos. + md::Event::Html(html) if html.starts_with("<contributors") => { + let from = html_attr(html, "from").unwrap(); + let to = html_attr(html, "to").unwrap(); + let Some(output) = contributors(from, to) else { return false }; + *html = output.raw.into(); + } + // Rewrite links. md::Event::Start(md::Tag::Link(ty, dest, _)) => { assert!( @@ -327,6 +334,19 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html { resolver.example(highlighted, &frames) } +/// Extract an attribute value from an HTML element. +fn html_attr<'a>(html: &'a str, attr: &str) -> Option<&'a str> { + html.get(html_attr_range(html, attr)?) +} + +/// Extract the range of the attribute value of an HTML element. +fn html_attr_range(html: &str, attr: &str) -> Option<Range<usize>> { + let needle = format!("{attr}=\""); + let offset = html.find(&needle)? + needle.len(); + let len = html[offset..].find('"')?; + Some(offset..offset + len) +} + /// World for example compilations. struct DocWorld(Source); diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 4a20a008..7333090d 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -1,7 +1,9 @@ //! Documentation provider for Typst. +mod contribs; mod html; +pub use contribs::contributors; pub use html::Html; use std::fmt::{self, Debug, Formatter}; |
