Skip to content

Commit

Permalink
feat: add new markdown formatters (#9613)
Browse files Browse the repository at this point in the history
* feat: add new markdown formatters

Co-authored-by: Jaw0r3k <jaw0r3k.g@gmail.com>

* Update packages/formatters/src/formatters.ts

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>

* refactor: remove unnecessary index tracking and rename 'array' to 'items'

Co-authored-by: Almeida <almeidx@pm.me>

* refactor: rename 'array' to 'items'

Co-authored-by: Almeida <almeidx@pm.me>

* refactor(heading): consolidate heading functions into a single function

Also correct param names from array to items.

Co-authored-by: Jaw0r3k <jaw0r3k.g@gmail.com>

* refactor: add HeadingLevel enum and use switch case

* fix: export HeadingLevel enum

Co-authored-by: Jaw0r3k <jaworekwiadomosci@gmail.com>

* feat(heading): add missing documentation for level parameter

* refactor: update list formatters

* docs: correct heading formatter description

* refactor: update list formatters

* fix(heading): remove unnecessary space

* refactor: move list callback function to outer scope

* test: add tests

* refactor: requested changes

* refactor: suggested changes

* docs: add missing documentation

* style: suggested change

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>

* refactor: use math max method instead

Co-authored-by: Almeida <almeidx@pm.me>

---------

Co-authored-by: Jaw0r3k <jaw0r3k.g@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Jaw0r3k <jaworekwiadomosci@gmail.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: space <spaceeec@yahoo.com>
  • Loading branch information
7 people authored Aug 25, 2023
1 parent 50106c7 commit 0d787e9
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
40 changes: 40 additions & 0 deletions packages/formatters/__tests__/formatters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@ import {
codeBlock,
Faces,
formatEmoji,
heading,
HeadingLevel,
hideLinkEmbed,
hyperlink,
inlineCode,
italic,
messageLink,
orderedList,
quote,
roleMention,
spoiler,
strikethrough,
time,
TimestampStyles,
underscore,
unorderedList,
userMention,
} from '../src/index.js';

Expand Down Expand Up @@ -202,6 +206,42 @@ describe('Message formatters', () => {
});
});

describe('heading', () => {
test('GIVEN "discord.js" THEN returns "# discord.js"', () => {
expect<'# discord.js'>(heading('discord.js')).toEqual('# discord.js');
});

test('GIVEN "discord.js" AND a heading level 2 from number THEN returns "## discord.js"', () => {
expect<'## discord.js'>(heading('discord.js', 2)).toEqual('## discord.js');
});

test('GIVEN "discord.js" AND a heading level 3 from enum THEN returns "### discord.js"', () => {
expect<'### discord.js'>(heading('discord.js', HeadingLevel.Three)).toEqual('### discord.js');
});
});

describe('orderedList', () => {
test('GIVEN ["discord.js", "discord.js 2", ["discord.js 3"]] THEN returns "1. discord.js\n1. discord.js 2\n 1. discord.js"', () => {
expect(orderedList(['discord.js', 'discord.js 2', ['discord.js 3']])).toEqual(
'1. discord.js\n1. discord.js 2\n 1. discord.js 3',
);
});

test('GIVEN ["discord.js", "discord.js 2", ["discord.js 3"]] AND a startNumber THEN returns "${startNumber}. discord.js\n${startNumber}. discord.js 2\n ${startNumber}. discord.js"', () => {
expect(orderedList(['discord.js', 'discord.js 2', ['discord.js 3']], 50)).toEqual(
'50. discord.js\n50. discord.js 2\n 50. discord.js 3',
);
});
});

describe('unorderedList', () => {
test('GIVEN ["discord.js", "discord.js 2", ["discord.js 3"]] THEN returns "- discord.js\n- discord.js 2\n - discord.js"', () => {
expect(unorderedList(['discord.js', 'discord.js 2', ['discord.js 3']])).toEqual(
'- discord.js\n- discord.js 2\n - discord.js 3',
);
});
});

describe('time', () => {
test('GIVEN no arguments THEN returns "<t:${bigint}>"', () => {
vitest.useFakeTimers();
Expand Down
93 changes: 93 additions & 0 deletions packages/formatters/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,99 @@ export function messageLink<C extends Snowflake, M extends Snowflake, G extends
return `${guildId === undefined ? channelLink(channelId) : channelLink(channelId, guildId)}/${messageId}`;
}

/**
* The heading levels for expanded markdown.
*/
export enum HeadingLevel {
/**
* The first heading level.
*/
One = 1,
/**
* The second heading level.
*/
Two,
/**
* The third heading level.
*/
Three,
}

/**
* Formats the content into a heading level.
*
* @typeParam C - This is inferred by the supplied content
* @param content - The content to wrap
* @param level - The heading level
*/
export function heading<C extends string>(content: C, level?: HeadingLevel.One): `# ${C}`;

/**
* Formats the content into a heading level.
*
* @typeParam C - This is inferred by the supplied content
* @param content - The content to wrap
* @param level - The heading level
*/
export function heading<C extends string>(content: C, level: HeadingLevel.Two): `## ${C}`;

/**
* Formats the content into a heading level.
*
* @typeParam C - This is inferred by the supplied content
* @param content - The content to wrap
* @param level - The heading level
*/
export function heading<C extends string>(content: C, level: HeadingLevel.Three): `### ${C}`;

export function heading(content: string, level?: HeadingLevel) {
switch (level) {
case HeadingLevel.Three:
return `### ${content}`;
case HeadingLevel.Two:
return `## ${content}`;
default:
return `# ${content}`;
}
}

/**
* A type that recursively traverses into arrays.
*/
export type RecursiveArray<T> = readonly (RecursiveArray<T> | T)[];

/**
* Callback function for list formatters.
*
* @internal
*/
function listCallback(element: RecursiveArray<string>, startNumber?: number, depth = 0): string {
if (Array.isArray(element)) {
return element.map((element) => listCallback(element, startNumber, depth + 1)).join('\n');
}

return `${' '.repeat(depth - 1)}${startNumber ? `${startNumber}.` : '-'} ${element}`;
}

/**
* Formats the elements in the array to an ordered list.
*
* @param list - The array of elements to list
* @param startNumber - The starting number for the list
*/
export function orderedList(list: RecursiveArray<string>, startNumber = 1): string {
return listCallback(list, Math.max(startNumber, 1));
}

/**
* Formats the elements in the array to an unordered list.
*
* @param list - The array of elements to list
*/
export function unorderedList(list: RecursiveArray<string>): string {
return listCallback(list);
}

/**
* Formats a date into a short date-time string.
*
Expand Down

0 comments on commit 0d787e9

Please sign in to comment.