Skip to content

Commit 7ff7662

Browse files
committed
Address most review feedback
1 parent 26b76e9 commit 7ff7662

30 files changed

+166
-2360
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ git pull --recurse-submodules
3434

3535
To make a change to a document, edit the corresponding Markdown file in [src](src). The file path matches the URL path after `/docs`, but if you have trouble finding the page you're looking for, you can click the "Edit on GitHub" button at the top of page on the website.
3636

37+
Please note that standard library documentation is auto-generated from our standard library source with our documentation tool `grain doc`. If you'd like to make an edit to the standard library docs please do so in the corresponding source file in the main compiler monorepo found [here](https://github.com/grain-lang/grain/tree/main/stdlib). After editing the source file, you can run `grain doc stdlib -o stdlib --current-version=$(grain -v)` from the project root directory to generate the `.md` docs. The changes will be reflected on the website the next time we deploy changes for the next release!
38+
3739
### Adding a New Document
3840

39-
Create your new Markdown file in the desired location within `src/content/docs`. Each document starts with some front-matter, which is a bit of yml that is given to the renderer. Since the title of the page is an `h1`, headers in your document should begin at level 2:
41+
Create your new Markdown file in the desired location within `src/content/docs`. Each document starts with some front-matter, which is a bit of yaml that is given to the renderer. Since the title of the page is an `h1`, headers in your document should begin at level 2:
4042

4143
```markdown
4244
---

scripts/generateContributors.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
import { Octokit } from "octokit";
2-
import fs from "node:fs";
2+
import fs from "node:fs/promises";
33
import path from "node:path";
44
import url from "node:url";
55

66
async function generateContributors() {
77
const octokit = new Octokit({ auth: process.env.GITHUB_ACCESS_TOKEN });
88

9-
const results = await octokit.paginate(octokit.rest.repos.listContributors, {
10-
owner: "grain-lang",
11-
repo: "grain",
12-
per_page: 25,
9+
const repos = await octokit.paginate(octokit.rest.repos.listForOrg, {
10+
org: "grain-lang",
11+
per_page: 100,
1312
});
1413

14+
const repoContributions = await Promise.all(
15+
repos
16+
.filter(repo => !repo.fork)
17+
.map(repo => octokit.paginate(octokit.rest.repos.listContributors, {
18+
owner: "grain-lang",
19+
repo: repo.name,
20+
per_page: 100,
21+
}))
22+
);
23+
24+
const contributionsFlattened = repoContributions.flat();
25+
26+
const groupedByLogin = Object.groupBy(contributionsFlattened, c => c.login);
27+
const results = Object.entries(groupedByLogin).map(([login, contributionInfos]) => ({
28+
login,
29+
profileUrl: contributionInfos[0].html_url,
30+
avatarUrl: contributionInfos[0].avatar_url,
31+
count: contributionInfos.reduce((acc, c) => acc + c.contributions, 0)
32+
}))
33+
1534
const cwd = path.dirname(url.fileURLToPath(import.meta.url));
16-
fs.writeFileSync(path.join(cwd, "..", "contributors.json"), JSON.stringify(results, undefined, 4));
35+
await fs.writeFile(path.join(cwd, "..", "contributors.json"), JSON.stringify(results, undefined, 4));
1736
}
1837

1938
await generateContributors();

src/blogAuthors.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ImageMetadata } from "astro";
2+
import type { BlogAuthor } from "./types";
3+
4+
import oscarHeadshot from "./images/headshots/oscar-headshot-square.jpg";
5+
import philipHeadshot from "./images/headshots/philip-headshot-square.jpg";
6+
import blaineHeadshot from "./images/headshots/blaine-headshot-square.jpg";
7+
import marcusHeadshot from "./images/headshots/marcus-headshot-square.jpg";
8+
9+
export const authorInfo: Record<BlogAuthor, { xLink: string; github: string; headshot: ImageMetadata }> = {
10+
"Oscar Spencer": { xLink: "oscar_spen", github: "ospencer", headshot: oscarHeadshot },
11+
"Philip Blair": { xLink: "Philip_E_Blair", github: "peblair", headshot: philipHeadshot },
12+
"Blaine Bublitz": { xLink: "BlaineBublitz", github: "phated", headshot: blaineHeadshot },
13+
"Marcus Roberts": { xLink: "marcusr", github: "marcusroberts", headshot: marcusHeadshot },
14+
};

src/components/BlogAuthor.astro

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
11
---
22
import { Image } from "astro:assets";
3-
import oscarHeadshot from "../images/headshots/oscar-headshot-square.jpg";
4-
import philipHeadshot from "../images/headshots/philip-headshot-square.jpg";
5-
import blaineHeadshot from "../images/headshots/blaine-headshot-square.jpg";
6-
import marcusHeadshot from "../images/headshots/marcus-headshot-square.jpg";
73
import type { CollectionEntry } from "astro:content";
84
import type { BlogAuthor } from "../types";
9-
10-
const headshotMap: Record<BlogAuthor, ImageMetadata> = {
11-
"Oscar Spencer": oscarHeadshot,
12-
"Philip Blair": philipHeadshot,
13-
"Blaine Bublitz": blaineHeadshot,
14-
"Marcus Roberts": marcusHeadshot,
15-
};
5+
import { authorInfo } from "../blogAuthors";
166
177
interface Props {
188
entry: CollectionEntry<"blog">;
@@ -26,7 +16,7 @@ const { entry, imgClass, nameClass, dateClass } = Astro.props;
2616

2717
<div class="flex items-center gap-3 w-fit">
2818
<Image
29-
src={headshotMap[entry.data.author as BlogAuthor]}
19+
src={authorInfo[entry.data.author as BlogAuthor].headshot}
3020
alt={entry.data.author}
3121
class={`rounded-full object-cover ${imgClass ?? ""}`}
3222
/>

src/components/BlogEntry.astro

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,11 @@
22
import type { CollectionEntry } from "astro:content"
33
import TypographyContainer from "./TypographyContainer.astro";
44
import ArrowLeft from "./icons/ArrowLeft.astro";
5-
import TwitterIcon from "./icons/TwitterIcon.astro";
65
import GithubIcon from "./icons/GithubIcon.astro";
7-
import oscarHeadshot from "../images/headshots/oscar-headshot-square.jpg";
8-
import philipHeadshot from "../images/headshots/philip-headshot-square.jpg";
9-
import blaineHeadshot from "../images/headshots/blaine-headshot-square.jpg";
10-
import marcusHeadshot from "../images/headshots/marcus-headshot-square.jpg";
116
import type { BlogAuthor } from "../types";
127
import { Image } from "astro:assets";
13-
14-
const authorInfo: Record<BlogAuthor, { twitter: string; github: string; headshot: ImageMetadata }> = {
15-
"Oscar Spencer": { twitter: "oscar_spen", github: "ospencer", headshot: oscarHeadshot },
16-
"Philip Blair": { twitter: "Philip_E_Blair", github: "peblair", headshot: philipHeadshot },
17-
"Blaine Bublitz": { twitter: "BlaineBublitz", github: "phated", headshot: blaineHeadshot },
18-
"Marcus Roberts": { twitter: "marcusr", github: "marcusroberts", headshot: marcusHeadshot },
19-
};
8+
import { authorInfo } from "../blogAuthors";
9+
import NewsletterSignup from "./NewsletterSignup.astro";
2010
2111
interface Props {
2212
entry: CollectionEntry<"blog">;
@@ -47,8 +37,8 @@ const { entry } = Astro.props;
4737
<p class="uppercase text-xs font-semibold">Author</p>
4838
<div class="flex gap-2 items-center">
4939
{entry.data.author}
50-
<a class="hidden md:block" href={`https://twitter.com/${authorInfo[entry.data.author as BlogAuthor].twitter}`}><TwitterIcon class="w-4" /></a>
51-
<a class="hidden md:block" href={`https://github.com/${authorInfo[entry.data.author as BlogAuthor].github}`}><GithubIcon class="w-4" /></a>
40+
<a class="hidden md:block" href={`https://x.com/${authorInfo[entry.data.author as BlogAuthor].xLink}`} aria-label="X link"><span class="font-bold text-xl">𝕏</span></a>
41+
<a class="hidden md:block" href={`https://github.com/${authorInfo[entry.data.author as BlogAuthor].github}`} aria-label="GitHub link"><GithubIcon class="w-4" /></a>
5242
</div>
5343
</div>
5444
</div>
@@ -68,4 +58,6 @@ const { entry } = Astro.props;
6858
<TypographyContainer>
6959
<slot />
7060
</TypographyContainer>
61+
<hr class="border-color-dim-2 my-10 md:my-16" />
62+
<NewsletterSignup />
7163
</div>

src/components/BlogHero.astro

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { CollectionEntry } from "astro:content";
33
import { Image } from "astro:assets";
44
import BlogAuthor from "./BlogAuthor.astro";
55
import ChevronRightIcon from "./icons/ChevronRightIcon.astro";
6-
import TwitterIcon from "./icons/TwitterIcon.astro";
76
import DiscordIcon from "./icons/DiscordIcon.astro";
87
import GrainLogo from "./icons/GrainLogo.astro";
98
@@ -20,23 +19,25 @@ const { entry } = Astro.props;
2019
<GrainLogo class="w-8 h-8 md:w-12 md:h-12 inline-block align-middle fill-color-accent" />
2120
<span class="md:pl-1 text-2xl md:text-4xl font-semibold align-middle">The Grain Blog</span>
2221
</div>
23-
<div class="flex md:hidden gap-4 text-color-accent">
22+
<div class="flex md:hidden gap-4 text-color-accent items-center">
2423
<a
25-
href="https://twitter.com/grain_lang"
24+
href="https://x.com/grain_lang"
2625
target="_blank"
26+
aria-label="X link"
2727
>
28-
<TwitterIcon class="w-7 h-7 fill-color-accent" />
28+
<span class="font-bold text-3xl text-color-accent">𝕏</span>
2929
</a>
3030
<a
31-
href="https://twitter.com/grain_lang"
31+
href="https://discord.com/invite/grain-lang"
3232
target="_blank"
33+
aria-label="Discord link"
3334
>
3435
<DiscordIcon class="w-7 h-7 fill-color-accent" />
3536
</a>
3637
</div>
3738
<div class="hidden md:block text-color-accent">
3839
Also find us on
39-
<a href="https://twitter.com/grain_lang" class="underline">Twitter</a>
40+
<a href="https://x.com/grain_lang" class="underline">X</a>
4041
and
4142
<a href="https://discord.com/invite/grain-lang" class="underline">Discord</a>
4243
</div>

src/components/CodeExamples.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ const lang = grainLang as any;
6767
))}
6868
</div>
6969
<div class="flex justify-between items-center text-purple-40 w-full lg:w-3/5 mx-auto">
70-
<button id="prev" class="inline-block border border-purple-40 hover:bg-purple-80 rounded-full p-3 rotate-180">
70+
<button id="prev" class="inline-block border border-purple-40 hover:bg-purple-80 rounded-full p-3 rotate-180" aria-label="Previous example">
7171
<ChevronRightIcon class="h-3.5" />
7272
</button>
7373
<p id="selected-example" class="text-lg"></p>
74-
<button id="next" class="inline-block border border-purple-40 hover:bg-purple-80 rounded-full p-3">
74+
<button id="next" class="inline-block border border-purple-40 hover:bg-purple-80 rounded-full p-3" aria-label="Next example">
7575
<ChevronRightIcon class="h-3.5" />
7676
</button>
7777
</div>

src/components/Contributors.astro

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ const excludeList = [
99
"ng-marcus",
1010
"alex-snezhko",
1111
"spotandjake",
12-
"github-actions[bot]"
12+
"github-actions[bot]",
13+
"grainbot",
14+
"dependabot[bot]",
1315
];
1416
1517
const special = [
@@ -24,13 +26,28 @@ const special = [
2426
</h2>
2527
{contributors
2628
.filter(x => !excludeList.includes(x.login))
29+
.toSorted((x, y) => {
30+
const xSpecial = special.includes(x.login);
31+
const ySpecial = special.includes(y.login);
32+
if (xSpecial && !ySpecial) {
33+
return -1;
34+
} else if (!xSpecial && ySpecial) {
35+
return 1;
36+
} else {
37+
return y.count - x.count;
38+
}
39+
})
2740
.map(contributor => (
2841
<div class="inline-block relative">
29-
<a href={contributor.html_url} class="p-0.5 inline-block">
30-
<img class={`w-14 h-14 rounded-full p-0.5 border ${special.includes(contributor.login) ? "shadow-[0_0px_8px_1px_rgb(0_0_0/0.1)] border-amber-600 shadow-amber-500" : "shadow-md border-color-dim-2"} dark:shadow-purple-80`} src={contributor.avatar_url} alt={`Image of ${contributor.login}`} />
42+
<a href={contributor.profileUrl} class="p-0.5 inline-block">
43+
<img
44+
class={`w-14 h-14 rounded-full p-0.5 border ${special.includes(contributor.login) ? "shadow-[0_0px_8px_1px_rgb(0_0_0/0.1)] border-amber-600 shadow-amber-500" : "shadow-md border-color-dim-2"} dark:shadow-purple-80`}
45+
src={contributor.avatarUrl}
46+
alt={`Image of ${contributor.login}`}
47+
/>
3148
</a>
3249
{special.includes(contributor.login) && (
33-
<a href={contributor.html_url} class="absolute text-2xl bottom-0 right-0 text-yellow-500 [text-shadow:0_0_2px_#000]">🌾</a>
50+
<a href={contributor.profileUrl} class="absolute text-2xl bottom-0 right-0 text-yellow-500 [text-shadow:0_0_2px_#000]">🌾</a>
3451
)}
3552
</div>
3653
))}

src/components/CoreTeamMemberInfo.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const { profileImage, name, title, role, githubUsername } = Astro.props;
5353
<div class="-z-10 transition duration-300 opacity-0 peer-hover:opacity-100 absolute top-20 left-44 bg-color-blurb-3 w-36 h-[26rem] rounded-full rotate-[10deg] blur-3xl" data-desc="color-ellipsis" />
5454

5555
<div class="px-2 mt-5">
56-
<h2 class="text-2xl font-bold mb-2"><span class="align-middle">{name}</span> <a href={`https://github.com/${githubUsername}`}><GithubIcon class="inline w-6 h-6 ml-1 align-middle" /></a></h2>
56+
<h2 class="text-2xl font-bold mb-2"><span class="align-middle">{name}</span> <a href={`https://github.com/${githubUsername}`} aria-label="GitHub link"><GithubIcon class="inline w-6 h-6 ml-1 align-middle" /></a></h2>
5757
<h3 class="text-lg">{title}</h3>
5858
<h3 class="text-lg text-gray-50">{role}</h3>
5959
</div>

src/components/DocLinkGroup.astro

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import type { CollectionEntry } from "astro:content";
33
import DocLink from "./DocLink.astro";
4+
import path from "node:path";
45
56
interface Props {
67
title: string | null;
@@ -14,5 +15,14 @@ const { title, entries } = Astro.props;
1415
<h2 class="text-xl font-semibold mt-6 mb-2">{title}</h2>
1516
)}
1617
<div class="border-l-2 border-color-dim-3">
17-
{entries.map(x => <DocLink id={x.id}>{x.data.title}</DocLink>)}
18+
{entries.map(x => {
19+
const pathParts = x.id.split(path.sep);
20+
const pathPrefixes = pathParts.slice(1, -1);
21+
return path.dirname(x.id) !== pathParts[0] && pathPrefixes.length > 0
22+
? (
23+
<DocLink id={x.id}><span class="text-color-dim-1">{pathPrefixes.join("/")} / </span><span>{x.data.title}</span></DocLink>
24+
) : (
25+
<DocLink id={x.id}>{x.data.title}</DocLink>
26+
)
27+
})}
1828
</div>

0 commit comments

Comments
 (0)