Skip to content

Commit 060a753

Browse files
authored
refactor(schema): move font config to schema (@fehmer) (monkeytypegame#6780)
- **refactor(schema): move font config to schema (@fehmer)** - **styles**
1 parent e32155e commit 060a753

File tree

23 files changed

+453
-459
lines changed

23 files changed

+453
-459
lines changed

.github/pull_request_template.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
- [ ] Make sure to include translations for the quotes in the description (or another comment) so we can verify their content.
99
- [ ] Adding a language?
1010
- Make sure to follow the [languages documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
11-
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
11+
- [ ] Add language to `packages/schemas/src/languages.ts`
1212
- [ ] Add language to exactly one group in `frontend/src/ts/constants/languages.ts`
1313
- [ ] Add language json file to `frontend/static/languages`
1414
- [ ] Adding a theme?
1515
- Make sure to follow the [themes documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
16-
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
16+
- [ ] Add theme to `packages/schemas/src/themes.ts`
1717
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
1818
- [ ] Add theme css file to `frontend/static/themes`
19-
- Also please add a screenshot of the theme, it would be extra awesome if you do so!
19+
- [ ] Add some screenshot of the theme, especially with different test settings (colorful, flip colors) to your pull request
2020
- [ ] Adding a layout?
2121
- [ ] Make sure to follow the [layouts documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
22-
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
22+
- [ ] Add layout to `packages/schemas/src/layouts.ts`
2323
- [ ] Add layout json file to `frontend/static/layouts`
24+
- [ ] Adding a font?
25+
- Make sure to follow the [themes documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/FONTS.md)
26+
- [ ] Add font file to `frontend/static/webfonts`
27+
- [ ] Add font to `packages/schemas/src/fonts.ts`
28+
- [ ] Add font to `frontend/src/ts/constants/fonts.ts`
2429
- [ ] Check if any open issues are related to this PR; if so, be sure to tag them below.
2530
- [ ] Make sure the PR title follows the Conventional Commits standard. (https://www.conventionalcommits.org for more info)
2631
- [ ] Make sure to include your GitHub username prefixed with @ inside parentheses at the end of the PR title.

docs/FONTS.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
### **Table of Contents**
2+
3+
- [Forking Monkeytype](#forking-monkeytype)
4+
- [Adding fonts](#adding-fonts)
5+
- [Committing Languages](#committing-languages)
6+
- [Language Guidelines](#language-guidelines)
7+
8+
### Forking Monkeytype
9+
10+
First, you will have to make a personal copy of the Monkeytype repository, also known as "forking". Go to the [Monkeytype repo](https://github.com/monkeytypegame/monkeytype/) and then click the "fork" button.
11+
12+
<img width="1552" alt="Screenshot showing location of the fork button on GitHub." src="https://user-images.githubusercontent.com/83455454/149194972-23343642-7a1f-4c0c-b5f2-36f4b39a2639.png">
13+
14+
## Adding Fonts
15+
16+
Once you have forked the repository you can now add your font. Place the font file in `./frontend/static/webfonts` e.g. `My-Font.woff2`.
17+
18+
> [!NOTE]
19+
> Your font needs to be in the `.woff2` format. Your filename cannot include spaces.
20+
21+
Open `./packages/schemas/src/fonts.ts` and add the new font at the _end_ of the `KnownFontNameSchema` list like this:
22+
23+
```typescript
24+
const KnownFontNameSchema = z.enum(
25+
[
26+
"Roboto_Mono",
27+
"Noto_Naskh_Arabic",
28+
...
29+
"My_Font",
30+
```
31+
32+
Call it whatever you want but make sure you replace spaces with underscores.
33+
34+
Then, go to `./frontend/src/ts/constants/fonts.ts` and add the following code to the _end_ of the `Fonts` object near to the very end of the file:
35+
36+
```typescript
37+
export const Fonts: Record<KnownFontName, FontConfig> = {
38+
...
39+
My_Font: {
40+
fileName: "My-Font.woff2",
41+
}
42+
```
43+
44+
### Committing Languages
45+
46+
Once you have created your language, you now need to create a pull request to the main Monkeytype repository. Go to the branch where you created your languages on GitHub. Then make sure your branch is up to date. Once it is up to date, click "contribute".
47+
48+
Update branch:
49+
<img width="1552" alt="Screenshot showing how to update the fork to match the main Monkeytype repository" src="https://user-images.githubusercontent.com/83455454/149186547-5b9fe4fd-b944-4eed-a959-db43f96198bf.png">
50+
51+
Create a pull request:
52+
<img width="1552" alt="Screenshot showing how to create a pull request to the main Monkeytype repository" src="https://user-images.githubusercontent.com/83455454/149186637-66dae488-05ae-45c4-9217-65bc36c4927b.png">
53+
54+
## Language Guidelines
55+
56+
Make sure your language follows the [Language guidelines](./CONTRIBUTING.md#language-guidelines).
57+

docs/LANGUAGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The contents of the file should be as follows:
3131
It is recommended that you familiarize yourselves with JSON before adding a language. For the `name` field, put the name of your language. `rightToLeft` indicates how the language is written. If it is written right to left then put `true`, otherwise put `false`.
3232
`ligatures` A ligature occurs when multiple letters are joined together to form a character [more details](<https://en.wikipedia.org/wiki/Ligature_(writing)>). If there's joining in the words, which is the case in languages like (Arabic, Malayalam, Persian, Sanskrit, Central_Kurdish... etc.), then set the value to `true`, otherwise set it to `false`. For `bcp47` put your languages [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). If the words you're adding are ordered by frequency (most common words at the top, least at the bottom) set the value of `orderedByFrequency` to `true`, otherwise `false`. Finally, add your list of words to the `words` field.
3333

34-
Then, go to `packages/contracts/src/schemas/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language.
34+
Then, go to `packages/schemas/src/languages.ts` and add your new language name at the _end_ of the `LanguageSchema` enum. Make sure to end the line with a comma. Make sure to add all your language names if you have created multiple word lists of differing lengths in the same language.
3535

3636
```typescript
3737
export const LanguageSchema = z.enum([

docs/LAYOUTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ For iso the number of keys need to be exactly thirteen for `row1`, twelve for `r
9898

9999

100100

101-
In addition to the layout file you need to add your layout to the `packages/contracts/src/schemas/layouts.ts` file. Just append your layout name (without the `.json`) at the __end__ of the `LayoutNameSchema`. Remember to add a comma like this:
101+
In addition to the layout file you need to add your layout to the `packages/schemas/src/layouts.ts` file. Just append your layout name (without the `.json`) at the __end__ of the `LayoutNameSchema`. Remember to add a comma like this:
102102

103103
```ts
104104
export const LayoutNameSchema = z.enum([

docs/THEMES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Here is an image showing what all the properties correspond to:
3737
<img width="1552" alt="Screenshot showing the page elements controlled by each color property" src="https://user-images.githubusercontent.com/83455454/149196967-abb69795-0d38-466b-a867-5aaa46452976.png">
3838

3939
Change the corresponding hex codes to create your theme.
40-
Then, go to `./packages/contracts/src/schemas/themes.ts` and add your new theme name at the _end_ of the `ThemeNameSchema` enum. Make sure to end the line with a comma.
40+
Then, go to `./packages/schemas/src/themes.ts` and add your new theme name at the _end_ of the `ThemeNameSchema` enum. Make sure to end the line with a comma.
4141

4242
```typescript
4343
export const ThemeNameSchema = z.enum([
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Fonts } from "../../src/ts/constants/fonts";
2+
import { readdirSync } from "fs";
3+
const ignoredFonts = new Set([
4+
"GallaudetRegular.woff2", //used for asl
5+
"Vazirmatn-Regular.woff2", //default font
6+
]);
7+
describe("fonts", () => {
8+
it("should have all related font files", () => {
9+
const fontFiles = listFontFiles();
10+
const expectedFontFiles = Object.entries(Fonts)
11+
.filter(([_name, config]) => !config.systemFont)
12+
.map(([_name, config]) => config.fileName as string);
13+
14+
const missingFontFiles = expectedFontFiles
15+
.filter((fileName) => !fontFiles.includes(fileName))
16+
.map((name) => `fontend/static/webfonts/${name}`);
17+
18+
expect(missingFontFiles, "missing font files").toEqual([]);
19+
});
20+
21+
it("should not have additional font files", () => {
22+
const fontFiles = listFontFiles();
23+
24+
const expectedFontFiles = new Set(
25+
Object.entries(Fonts)
26+
.filter(([_name, config]) => !config.systemFont)
27+
.map(([_name, config]) => config.fileName as string)
28+
);
29+
30+
const additionalFontFiles = fontFiles
31+
.filter((name) => !expectedFontFiles.has(name))
32+
.map((name) => `fontend/static/webfonts/${name}`);
33+
34+
expect(
35+
additionalFontFiles,
36+
"additional font files not declared in frontend/src/ts/constants/fonts.ts"
37+
).toEqual([]);
38+
});
39+
});
40+
41+
function listFontFiles() {
42+
return readdirSync(import.meta.dirname + "/../../static/webfonts").filter(
43+
(it) => !ignoredFonts.has(it)
44+
);
45+
}

frontend/scripts/font-preview.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import * as fs from "fs";
22
import * as path from "path";
33
import { fileURLToPath } from "url";
4-
import Fonts from "../static/fonts/_list.json";
4+
55
import subsetFont from "subset-font";
6+
import { Fonts } from "../src/ts/constants/fonts";
7+
import { KnownFontName } from "@monkeytype/schemas/fonts";
68

79
const __filename = fileURLToPath(import.meta.url);
810
const __dirname = path.dirname(__filename);
@@ -14,31 +16,23 @@ export async function generatePreviewFonts(
1416
const targetDir = __dirname + "/../static/webfonts-preview";
1517
fs.mkdirSync(targetDir, { recursive: true });
1618

17-
const srcFiles = fs.readdirSync(srcDir);
18-
19-
for (const font of Fonts) {
19+
for (const name of Object.keys(Fonts)) {
20+
const font = Fonts[name as KnownFontName];
2021
if (font.systemFont) continue;
2122

22-
const display = (font.display ?? font.name) + "Fontfamily";
23+
const includedCharacters =
24+
(font.display ?? name.replaceAll("_", " ")) + "Fontfamily";
2325

24-
const fileNames = srcFiles.filter((it) =>
25-
it.startsWith(font.name.replaceAll(" ", "") + "-")
26-
);
27-
28-
if (fileNames.length !== 1)
29-
throw new Error(
30-
`cannot find font file for ${font.name}. Candidates: ${fileNames}`
31-
);
32-
const fileName = fileNames[0];
26+
const fileName = font.fileName;
3327

3428
await generateSubset(
3529
srcDir + "/" + fileName,
3630
targetDir + "/" + fileName,
37-
display
31+
includedCharacters
3832
);
3933
if (debug) {
4034
console.log(
41-
`Processing ${font.name} with file ${fileName} to display "${display}".`
35+
`Processing ${name} with file ${fileName} to display "${includedCharacters}".`
4236
);
4337
}
4438
}
@@ -47,10 +41,10 @@ export async function generatePreviewFonts(
4741
async function generateSubset(
4842
source: string,
4943
target: string,
50-
name: string
44+
includedCharacters: string
5145
): Promise<void> {
5246
const font = fs.readFileSync(source);
53-
const subset = await subsetFont(font, name, {
47+
const subset = await subsetFont(font, includedCharacters, {
5448
targetFormat: "woff2",
5549
});
5650
fs.writeFileSync(target, subset);

frontend/scripts/json-validation.cjs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,6 @@ function findDuplicates(words) {
2020

2121
function validateOthers() {
2222
return new Promise((resolve, reject) => {
23-
//fonts
24-
const fontsData = JSON.parse(
25-
fs.readFileSync("./static/fonts/_list.json", {
26-
encoding: "utf8",
27-
flag: "r",
28-
})
29-
);
30-
const fontsSchema = {
31-
type: "array",
32-
items: {
33-
type: "object",
34-
properties: {
35-
name: {
36-
type: "string",
37-
},
38-
},
39-
required: ["name"],
40-
},
41-
};
42-
const fontsValidator = ajv.compile(fontsSchema);
43-
if (fontsValidator(fontsData)) {
44-
console.log("Fonts JSON schema is \u001b[32mvalid\u001b[0m");
45-
} else {
46-
console.log("Fonts JSON schema is \u001b[31minvalid\u001b[0m");
47-
return reject(new Error(fontsValidator.errors[0].message));
48-
}
49-
5023
//challenges
5124
const challengesSchema = {
5225
type: "array",

0 commit comments

Comments
 (0)