diff --git a/.gitignore b/.gitignore index 10eed09..f6aea18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode /*-*.*.*.tgz dist +docs node_modules diff --git a/README.md b/README.md index 27599ad..5cc3b29 100644 --- a/README.md +++ b/README.md @@ -69,97 +69,3 @@ reasons but it behaves a bit differently. `Markdown` still escapes inputs and does not need `format.escape` before. Also nested formatting is not supported by telegram itself. Consider switching to `MarkdownV2` or `HTML` for simplicity reasons. - -## API - -### bold(text) - -#### text - -Type: `string` - -Text to be formatted bold - -### italic(text) - -#### text - -Type: `string` - -Text to be formatted italic - -### strikethrough(text) - -#### text - -Type: `string` - -Text to be striked through - -### underline(text) - -#### text - -Type: `string` - -Text to be underlined - -### monospace(text) - -#### text - -Type: `string` - -Text to be displayed as inline monospace - -### monospaceBlock(text, [programmingLanguage]) - -#### text - -Type: `string` - -Text to be displayed as monospace block - -#### programmingLanguage - -Type: `string` (optional) - -Can be used to specify the programming language of the code - -### url(label, url) - -#### label - -Type: `string` - -Label of the url field - -#### url - -Type: `string` - -Url which is called when the user taps on the label - -### userMention(label, userId) - -#### label - -Type: `string` - -Label of the user mention. Might be used with the first name for example. - -#### userID - -Type: `number` - -User id to which is linked - -### escape(text) - -#### text - -Type: `string` - -Text which should be escaped so it does not interfer with formatting. - -User generated Text should always be escapted to prevent errors. diff --git a/deno.jsonc b/deno.jsonc index e2aa1d7..871028d 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -15,6 +15,7 @@ }, "exclude": [ "./dist/", + "./docs/", "./node_modules/" ], "fmt": { @@ -34,5 +35,8 @@ "no-sparse-arrays" ] } + }, + "tasks": { + "doc": "deno doc --html --name=telegram_format source/mod.ts" } } diff --git a/source/README.md b/source/README.md index fea2b99..5382501 100644 --- a/source/README.md +++ b/source/README.md @@ -1,4 +1,4 @@ # telegram_format See the [README on GitHub](https://github.com/EdJoPaTo/telegram-format#readme) -for more information on this package. +or the [documentation on deno.land](https://deno.land/x/telegram-format?doc). diff --git a/source/html.test.ts b/source/html.test.ts index 063d796..f910122 100644 --- a/source/html.test.ts +++ b/source/html.test.ts @@ -1,6 +1,9 @@ import { strictEqual } from "node:assert"; import { test } from "node:test"; -import { html as format } from "./html.ts"; +import * as format from "./html.ts"; +import { Formatter } from "./types.ts"; + +format satisfies Formatter; test("bold", () => { strictEqual(format.bold("bold"), "bold"); diff --git a/source/html.ts b/source/html.ts index 4206f36..45e05ad 100644 --- a/source/html.ts +++ b/source/html.ts @@ -1,37 +1,49 @@ -import type { Formatter } from "./types.ts"; +/** https://core.telegram.org/bots/api#html-style */ +export const parse_mode = "HTML"; -function escape(text: string): string { +/** Escape the input text to be displayed as it is */ +export function escape(text: string): string { return text .replace(/&/g, "&") .replace(//g, ">"); } -function bold(text: string): string { +/** Format the input text bold */ +export function bold(text: string): string { return `${text}`; } -function italic(text: string): string { +/** Format the input text italic */ +export function italic(text: string): string { return `${text}`; } -function strikethrough(text: string): string { +/** Strikethrough the input text */ +export function strikethrough(text: string): string { return `${text}`; } -function underline(text: string): string { +/** Underline the input text */ +export function underline(text: string): string { return `${text}`; } -function spoiler(text: string): string { +/** Format the input text as spoiler */ +export function spoiler(text: string): string { return `${text}`; } -function monospace(text: string): string { +/** Format the input text as monospace */ +export function monospace(text: string): string { return `${escape(text)}`; } -function monospaceBlock(text: string, programmingLanguage?: string): string { +/** Format the input text as a monospace block optionally with a programming language */ +export function monospaceBlock( + text: string, + programmingLanguage?: string, +): string { if (programmingLanguage) { return `
${
 			escape(text)
@@ -41,25 +53,12 @@ function monospaceBlock(text: string, programmingLanguage?: string): string {
 	return `
${escape(text)}
`; } -function url(label: string, url: string): string { +/** Create an url with a label text */ +export function url(label: string, url: string): string { return `${label}`; } -function userMention(label: string, userId: number): string { +/** Create a user mention with a label text */ +export function userMention(label: string, userId: number): string { return url(label, `tg://user?id=${userId}`); } - -/** https://core.telegram.org/bots/api#html-style */ -export const html = { - parse_mode: "HTML", - escape, - bold, - italic, - strikethrough, - underline, - spoiler, - monospace, - monospaceBlock, - url, - userMention, -} as const satisfies Formatter; diff --git a/source/markdown.test.ts b/source/markdown.test.ts index 0ff4c8a..408e282 100644 --- a/source/markdown.test.ts +++ b/source/markdown.test.ts @@ -1,6 +1,9 @@ import { strictEqual, throws } from "node:assert"; import { test } from "node:test"; -import { markdown as format } from "./markdown.ts"; +import * as format from "./markdown.ts"; +import { Formatter } from "./types.ts"; + +format satisfies Formatter; test("bold", () => { strictEqual(format.bold("bold"), "*bold*"); diff --git a/source/markdown.ts b/source/markdown.ts index 9155d69..99a710a 100644 --- a/source/markdown.ts +++ b/source/markdown.ts @@ -1,40 +1,52 @@ -import type { Formatter } from "./types.ts"; +/** https://core.telegram.org/bots/api#markdown-style */ +export const parse_mode = "Markdown"; -function escape(text: string): string { +/** Escape the input text to be displayed as it is */ +export function escape(text: string): string { return text.replace(/[*_`[\]()]/g, ""); } -function bold(text: string): string { +/** Format the input text bold */ +export function bold(text: string): string { return `*${text.replace(/\*/g, "")}*`; } -function italic(text: string): string { +/** Format the input text italic */ +export function italic(text: string): string { return `_${text.replace(/_/g, "")}_`; } -function strikethrough(_text: string): string { +/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */ +export function strikethrough(_text: string): string { throw new Error( "strikethrough is not supported by Markdown. Use MarkdownV2 instead.", ); } -function underline(_text: string): string { +/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */ +export function underline(_text: string): string { throw new Error( "underline is not supported by Markdown. Use MarkdownV2 instead.", ); } -function spoiler(_text: string): string { +/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */ +export function spoiler(_text: string): string { throw new Error( "spoiler is not supported by Markdown. Use MarkdownV2 instead.", ); } -function monospace(text: string): string { +/** Format the input text as monospace */ +export function monospace(text: string): string { return "`" + text.replace(/`/g, "") + "`"; } -function monospaceBlock(text: string, programmingLanguage?: string): string { +/** Format the input text as a monospace block optionally with a programming language */ +export function monospaceBlock( + text: string, + programmingLanguage?: string, +): string { let result = ""; result += "```"; @@ -49,25 +61,12 @@ function monospaceBlock(text: string, programmingLanguage?: string): string { return result; } -function url(label: string, url: string): string { +/** Create an url with a label text */ +export function url(label: string, url: string): string { return `[${label.replace(/]/, "")}](${url.replace(/\)/, "")})`; } -function userMention(label: string, userId: number): string { +/** Create a user mention with a label text */ +export function userMention(label: string, userId: number): string { return url(label, `tg://user?id=${userId}`); } - -/** https://core.telegram.org/bots/api#markdown-style */ -export const markdown = { - parse_mode: "Markdown", - escape, - bold, - italic, - strikethrough, - underline, - spoiler, - monospace, - monospaceBlock, - url, - userMention, -} as const satisfies Formatter; diff --git a/source/markdownv2.test.ts b/source/markdownv2.test.ts index 8138f89..19264fb 100644 --- a/source/markdownv2.test.ts +++ b/source/markdownv2.test.ts @@ -1,6 +1,9 @@ import { strictEqual } from "node:assert"; import { test } from "node:test"; -import { markdownv2 as format } from "./markdownv2.ts"; +import * as format from "./markdownv2.ts"; +import { Formatter } from "./types.ts"; + +format satisfies Formatter; test("bold", () => { strictEqual(format.bold("bold"), "*bold*"); diff --git a/source/markdownv2.ts b/source/markdownv2.ts index 5518660..8a4d34c 100644 --- a/source/markdownv2.ts +++ b/source/markdownv2.ts @@ -1,38 +1,50 @@ -import type { Formatter } from "./types.ts"; +/** https://core.telegram.org/bots/api#markdownv2-style */ +export const parse_mode = "MarkdownV2"; function escapeInternal(text: string, escapeChars: string): string { return text.replace(new RegExp(`[${escapeChars}\\\\]`, "g"), "\\$&"); } -function escape(text: string): string { +/** Escape the input text to be displayed as it is */ +export function escape(text: string): string { return text.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, "\\$&"); } -function bold(text: string): string { +/** Format the input text bold */ +export function bold(text: string): string { return `*${text}*`; } -function italic(text: string): string { +/** Format the input text italic */ +export function italic(text: string): string { return `_${text}_`; } -function strikethrough(text: string): string { +/** Strikethrough the input text */ +export function strikethrough(text: string): string { return `~${text}~`; } -function underline(text: string): string { +/** Underline the input text */ +export function underline(text: string): string { return `__${text}__`; } -function spoiler(text: string): string { +/** Format the input text as spoiler */ +export function spoiler(text: string): string { return `||${text}||`; } -function monospace(text: string): string { +/** Format the input text as monospace */ +export function monospace(text: string): string { return "`" + escapeInternal(text, "`") + "`"; } -function monospaceBlock(text: string, programmingLanguage?: string): string { +/** Format the input text as a monospace block optionally with a programming language */ +export function monospaceBlock( + text: string, + programmingLanguage?: string, +): string { let result = ""; result += "```"; @@ -47,25 +59,12 @@ function monospaceBlock(text: string, programmingLanguage?: string): string { return result; } -function url(label: string, url: string): string { +/** Create an url with a label text */ +export function url(label: string, url: string): string { return `[${label}](${escapeInternal(url, ")")})`; } -function userMention(label: string, userId: number): string { +/** Create a user mention with a label text */ +export function userMention(label: string, userId: number): string { return url(label, `tg://user?id=${userId}`); } - -/** https://core.telegram.org/bots/api#markdownv2-style */ -export const markdownv2 = { - parse_mode: "MarkdownV2", - escape, - bold, - italic, - strikethrough, - underline, - spoiler, - monospace, - monospaceBlock, - url, - userMention, -} as const satisfies Formatter; diff --git a/source/mod.ts b/source/mod.ts index a35b014..72774d6 100644 --- a/source/mod.ts +++ b/source/mod.ts @@ -1,5 +1,5 @@ export type { Formatter } from "./types.ts"; -export { html } from "./html.ts"; -export { markdown } from "./markdown.ts"; -export { markdownv2 } from "./markdownv2.ts"; +export * as html from "./html.ts"; +export * as markdown from "./markdown.ts"; +export * as markdownv2 from "./markdownv2.ts"; diff --git a/source/types.ts b/source/types.ts index 7db82b5..51c97a8 100644 --- a/source/types.ts +++ b/source/types.ts @@ -1,13 +1,25 @@ -export type Formatter = { +/** All exported formatters satisfy this interface */ +export interface Formatter { + /** parse_mode which can be used on sendMessage */ parse_mode: "HTML" | "Markdown" | "MarkdownV2"; + /** Format the input text bold */ bold: (text: string) => string; + /** Escape the input text to be displayed as it is */ escape: (text: string) => string; + /** Format the input text italic */ italic: (text: string) => string; + /** Format the input text as monospace */ monospace: (text: string) => string; + /** Format the input text as a monospace block optionally with a programming language */ monospaceBlock: (text: string, programmingLanguage?: string) => string; + /** Format the input text as spoiler */ spoiler: (text: string) => string; + /** Strikethrough the input text */ strikethrough: (text: string) => string; + /** Underline the input text */ underline: (text: string) => string; + /** Create an url with a label text */ url: (label: string, url: string) => string; + /** Create a user mention with a label text */ userMention: (label: string, userId: number) => string; -}; +}