(refactor) use buildPronounsUsage in banner generation

This commit is contained in:
Valentyne Stigloher 2024-10-03 23:23:36 +02:00
parent e5d184160a
commit 5c63b58324
6 changed files with 24 additions and 54 deletions

View File

@ -108,7 +108,7 @@
<ExpandableList :values="pronounOpinions" :limit="16" class="list-unstyled" :is-static="isStatic" :expand="expandLinks">
<template #default="s">
<Opinion
:word="s.el.short"
:word="s.el.short.options.join(s.el.short.glue)"
:opinion="s.el.opinion"
:link="`${config.pronouns.prefix || ''}/${s.el.link}`"
:custom-opinions="profile.opinions"

View File

@ -5,7 +5,7 @@ import type { CanvasRenderingContext2D, Image } from 'canvas';
import { rootDir } from '../paths.ts';
import { loadSuml, loadSumlFromBase } from '../loader.ts';
import avatar from '../avatar.ts';
import { buildPronoun, parsePronounGroups, parsePronouns } from '../../src/buildPronoun.ts';
import { buildPronounUsage, parsePronounGroups, parsePronouns } from '../../src/buildPronoun.ts';
import { PronounLibrary } from '../../src/classes.ts';
import { loadTsv } from '../../src/tsv.ts';
import { handleErrorAsync } from '../../src/helpers.ts';
@ -40,36 +40,6 @@ const drawCircle = (context: CanvasRenderingContext2D, image: Image, x: number,
context.restore();
};
// TODO combine logic with buildPronounUsage
const getPronounNameOptions = (pronounName: string): string[] | undefined => {
if (global.config.pronouns.any && pronounName === global.config.pronouns.any) {
return [translator.translate('pronouns.any.short')];
}
const prefix = `${global.config.pronouns.any}:`;
if (global.config.pronouns.any && pronounName.startsWith(prefix)) {
const merged = pronounLibrary.byKey()[pronounName.substring(prefix.length)];
if (merged) {
return [merged.short(translator)];
}
}
if (global.config.pronouns.null && global.config.pronouns.null.routes?.includes(pronounName)) {
return [pronounName];
}
if (global.config.pronouns.mirror && pronounName === global.config.pronouns.mirror.route) {
return [global.config.pronouns.mirror.name];
}
return buildPronoun(
pronouns,
pronounName,
global.config,
translator,
)?.nameOptions();
};
const router = Router();
router.get('/banner/:pronounName*.png', handleErrorAsync(async (req, res) => {
@ -124,8 +94,8 @@ router.get('/banner/:pronounName*.png', handleErrorAsync(async (req, res) => {
return canvas.toBuffer(mime);
}
const pronounNameOptions = getPronounNameOptions(pronounName);
if (pronounName === 'zaimki' || pronounNameOptions === undefined) {
const usage = buildPronounUsage(pronounLibrary, pronounName, config, translator);
if (pronounName === 'zaimki' || usage === null) {
await fallback();
return canvas.toBuffer(mime);
}
@ -134,11 +104,11 @@ router.get('/banner/:pronounName*.png', handleErrorAsync(async (req, res) => {
context.font = `regular 48pt '${fontName}'`;
context.fillText(`${translations.pronouns.intro}:`, width / leftRatio + imageSize / 1.5, height / 2 - 36);
context.font = `bold ${pronounNameOptions.length <= 2 ? '70' : '36'}pt '${fontName}'`;
context.font = `bold ${usage.short.options.length <= 2 ? '70' : '36'}pt '${fontName}'`;
context.fillText(
pronounNameOptions.map((o) => o.replace(/ ?\[[^\]]+] ?/g, '').trim()).join('\n'),
usage.short.options.map((o) => o.replace(/ ?\[[^\]]+] ?/g, '').trim()).join('\n'),
width / leftRatio + imageSize / 1.5,
height / 2 + (pronounNameOptions.length <= 2 ? 72 : 24),
height / 2 + (usage.short.options.length <= 2 ? 72 : 24),
);
return canvas.toBuffer(mime);

View File

@ -94,7 +94,7 @@ router.get('/pronouns-name/:pronoun*', handleErrorAsync(async (req, res) => {
if (usage === null) {
return res.status(404).json({ error: 'Not found' });
}
return res.json(usage.short);
return res.json(usage.short.options.join(usage.short.glue));
}));
router.get('/remote-pronouns-name/:locale/:pronoun*', handleErrorAsync(async (req, res) => {

View File

@ -265,27 +265,27 @@ export const buildPronounUsage = (
}
if (config.pronouns.null && config.pronouns.null.routes?.includes(path)) {
return { short: path };
return { short: { options: [path] } };
}
if (config.pronouns.mirror && config.pronouns.mirror.route === path) {
return { short: path };
return { short: { options: [path] } };
}
if (config.pronouns.any) {
if (config.pronouns.any === path) {
return { short: translator.translate('pronouns.any.short') };
return { short: { options: [translator.translate('pronouns.any.short')] } };
}
const prefix = `${config.pronouns.any}:`;
if (path.startsWith(prefix)) {
const merged = pronounLibrary.byKey()[path.substring(prefix.length)];
if (merged) {
return { short: merged.short(translator) };
return { short: { options: [merged.short(translator)] } };
}
}
}
const pronoun = buildPronoun(pronounLibrary.pronouns, path, config, translator);
if (pronoun) {
return { short: pronoun.name(` ${translator.translate('pronouns.or')} `), pronoun };
return { short: { options: pronoun.nameOptions(), glue: ` ${translator.translate('pronouns.or')} ` }, pronoun };
}
return null;
};

View File

@ -400,7 +400,7 @@ const escape = (s: string[] | string | null): string => {
};
export interface PronounUsage {
short: string;
short: { options: string[], glue?: string };
pronoun?: Pronoun;
}

View File

@ -386,24 +386,24 @@ describe('building the short of a pronoun usage', () => {
test('of a canonical pronoun', () => {
const actual = buildPronounUsage(pronounLibrary, 'she', config, translator);
expect(actual).toEqual({ short: 'she/her', pronoun: pronouns.she });
expect(actual).toEqual({ short: { options: ['she/her'], glue: ' or ' }, pronoun: pronouns.she });
});
test('of a generated pronoun in slash format', () => {
config.pronouns.honorifics = true;
config.pronouns.generator!.slashes = true;
const actual = buildPronounUsage(pronounLibrary, 'ae/aer/aer/aers/aerself', config, translator);
expect(actual).toEqual({ short: 'ae/aer', pronoun: generatedPronouns.aer(config) });
expect(actual).toEqual({ short: { options: ['ae/aer'], glue: ' or ' }, pronoun: generatedPronouns.aer(config) });
});
test('of interchangeable', () => {
const actual = buildPronounUsage(pronounLibrary, 'he&they', config, translator);
expect(actual).toMatchObject({ short: 'he/him or they/them' });
expect(actual).toMatchObject({ short: { options: ['he/him', 'they/them'], glue: ' or ' } });
});
test('of null pronoun', () => {
config.pronouns.null = nullPronounsConfig;
const actual = buildPronounUsage(pronounLibrary, ':A', config, translator);
expect(actual).toMatchObject({ short: 'A/A\'s' });
expect(actual).toMatchObject({ short: { options: ['A/A\'s'], glue: ' or ' } });
});
test('of null route', () => {
config.pronouns.null = {
@ -413,13 +413,13 @@ describe('building the short of a pronoun usage', () => {
};
const actual = buildPronounUsage(pronounLibrary, 'avoiding', config, translator);
expect(actual).toEqual({ short: 'avoiding' });
expect(actual).toEqual({ short: { options: ['avoiding'] } });
});
test('of emojiself', () => {
config.pronouns.emoji = emojiPronounsConfig;
const actual = buildPronounUsage(pronounLibrary, '💫', config, translator);
expect(actual).toMatchObject({ short: '💫/💫\'s' });
expect(actual).toMatchObject({ short: { options: ['💫/💫\'s'] } });
});
test('of mirrorpronouns', () => {
config.pronouns.mirror = {
@ -434,15 +434,15 @@ describe('building the short of a pronoun usage', () => {
};
const actual = buildPronounUsage(pronounLibrary, 'mirror', config, translator);
expect(actual).toEqual({ short: 'mirror' });
expect(actual).toEqual({ short: { options: ['mirror'] } });
});
test('of any route', () => {
const actual = buildPronounUsage(pronounLibrary, 'any', config, translator);
expect(actual).toEqual({ short: 'any' });
expect(actual).toEqual({ short: { options: ['any'] } });
});
test('of any group without specific translation', () => {
const actual = buildPronounUsage(pronounLibrary, 'any:normative', config, translator);
expect(actual).toEqual({ short: 'any normative' });
expect(actual).toEqual({ short: { options: ['any normative'] } });
});
test('of any group with specific translation', () => {
translations.pronouns.any.group = {
@ -452,6 +452,6 @@ describe('building the short of a pronoun usage', () => {
};
const actual = buildPronounUsage(pronounLibrary, 'any:normative', config, translator);
expect(actual).toEqual({ short: 'both binaries' });
expect(actual).toEqual({ short: { options: ['both binaries'] } });
});
});