AtlatestRepositorysigil-telegram
1;;; (sigil telegram format) - MarkdownV2 Formatting Helpers
2;;;
3;;; Provides escaping and formatting functions for Telegram's MarkdownV2
4;;; parse mode. Dynamic text must be escaped with `tg-escape-markdown`
5;;; before wrapping with formatting helpers.
6
7(define-library (sigil telegram format)
8 (import (sigil core)
9 (sigil string))
11 (export
12 tg-escape-markdown
13 tg-bold
14 tg-italic
15 tg-underline
16 tg-strike
17 tg-code
18 tg-code-block
19 tg-link
20 tg-spoiler)
22 (begin
24 ;; Characters that must be escaped in MarkdownV2 outside of formatting
25 (define %markdown-special-chars
26 '("_" "*" "[" "]" "(" ")" "~" "`" ">" "#"
27 "+" "-" "=" "|" "{" "}" "." "!"))
29 ;;; Escape a string for Telegram MarkdownV2 format.
30 ;;;
31 ;;; Prepends a backslash before each special character that MarkdownV2
32 ;;; requires to be escaped. Call this on dynamic text before wrapping
33 ;;; it with formatting helpers like `tg-bold` or `tg-italic`.
34 ;;;
35 ;;; ```scheme
36 ;;; (tg-escape-markdown "Hello! How are you?")
37 ;;; ; => "Hello\\! How are you\\?"
38 ;;;
39 ;;; (tg-escape-markdown "Price: $5.00 (USD)")
40 ;;; ; => "Price: $5\\.00 \\(USD\\)"
41 ;;; ```
42 (define (tg-escape-markdown text)
43 (: string? -> string?)
44 (fold (lambda (result char)
45 (string-replace result char (string-append "\\" char)))
46 text
47 %markdown-special-chars))
49 ;;; Format text as bold in MarkdownV2.
50 ;;;
51 ;;; ```scheme
52 ;;; (tg-bold "important") ; => "*important*"
53 ;;; ```
54 (define (tg-bold text)
55 (: string? -> string?)
56 (string-append "*" text "*"))
58 ;;; Format text as italic in MarkdownV2.
59 ;;;
60 ;;; ```scheme
61 ;;; (tg-italic "emphasis") ; => "_emphasis_"
62 ;;; ```
63 (define (tg-italic text)
64 (: string? -> string?)
65 (string-append "_" text "_"))
67 ;;; Format text as underlined in MarkdownV2.
68 ;;;
69 ;;; ```scheme
70 ;;; (tg-underline "noted") ; => "__noted__"
71 ;;; ```
72 (define (tg-underline text)
73 (: string? -> string?)
74 (string-append "__" text "__"))
76 ;;; Format text as strikethrough in MarkdownV2.
77 ;;;
78 ;;; ```scheme
79 ;;; (tg-strike "removed") ; => "~removed~"
80 ;;; ```
81 (define (tg-strike text)
82 (: string? -> string?)
83 (string-append "~" text "~"))
85 ;;; Format text as inline code in MarkdownV2.
86 ;;;
87 ;;; ```scheme
88 ;;; (tg-code "variable") ; => "`variable`"
89 ;;; ```
90 (define (tg-code text)
91 (: string? -> string?)
92 (string-append "`" text "`"))
94 ;;; Format text as a code block in MarkdownV2.
95 ;;;
96 ;;; Optionally specify a language for syntax highlighting.
97 ;;;
98 ;;; ```scheme
99 ;;; (tg-code-block "(+ 1 2)")
100 ;;; ; => "```\n(+ 1 2)```"
101 ;;;
102 ;;; (tg-code-block "(+ 1 2)" language: "scheme")
103 ;;; ; => "```scheme\n(+ 1 2)```"
104 ;;; ```
105 (define (tg-code-block text (keys: (language #f)))
106 (: string? (language: (maybe string?)) -> string?)
107 (if language
108 (string-append "```" language "\n" text "```")
109 (string-append "```\n" text "```")))
111 ;;; Format a MarkdownV2 inline link.
112 ;;;
113 ;;; ```scheme
114 ;;; (tg-link "Click here" "https://example.com")
115 ;;; ; => "[Click here](https://example.com)"
116 ;;; ```
117 (define (tg-link text url)
118 (: string? string? -> string?)
119 (string-append "[" text "](" url ")"))
121 ;;; Format text as a spoiler in MarkdownV2.
122 ;;;
123 ;;; ```scheme
124 ;;; (tg-spoiler "hidden text") ; => "||hidden text||"
125 ;;; ```
126 (define (tg-spoiler text)
127 (: string? -> string?)
128 (string-append "||" text "||"))
130 ))