chat_sdk-telegram 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/chat_sdk/telegram/format_converter.rb +117 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f873b2a03fd234639c59a872229bcd2942abc6169b1c970023ceaa16cb239062
|
|
4
|
+
data.tar.gz: 9e41b3269dc1116e2bc7169b146770337e8f9bbb6020b85f7f36c575828cf678
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 331146db0c5788c64ce2c7da1a097ff0ae54d2ad946d471be832fdb8123439db92feb7e3db213c023bed0f61cc3121822e6cf26560fc1ec6bd8962ec0082fbe3
|
|
7
|
+
data.tar.gz: 9843eee8e48fab1a345487035beac68a014bc558e343346dc1cfe6a170f7799b9170f9cff2e10d9bc8fdb738c4cc73fa118731558508baf8970509e54aeea3e2
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChatSDK
|
|
4
|
+
module Telegram
|
|
5
|
+
class FormatConverter < ChatSDK::Format::Converter
|
|
6
|
+
SPECIAL_CHARS = %w[_ * [ ] ( ) ~ \\ ` > # + - = | { } . !].freeze
|
|
7
|
+
|
|
8
|
+
# Telegram MarkdownV2 → standard Markdown
|
|
9
|
+
def to_markdown(platform_text)
|
|
10
|
+
text = platform_text.to_s
|
|
11
|
+
return "" if text.empty?
|
|
12
|
+
|
|
13
|
+
# Convert Telegram user links: [text](tg://user?id=123) → @123
|
|
14
|
+
text = text.gsub(/\[([^\]]*)\]\(tg:\/\/user\?id=(\d+)\)/, '@\2')
|
|
15
|
+
|
|
16
|
+
# Strip underline markers: __text__ → text
|
|
17
|
+
# Use a loop to handle nested cases
|
|
18
|
+
text = text.gsub(/(?<!_)__(?!_)(.+?)(?<!_)__(?!_)/m, '\1')
|
|
19
|
+
|
|
20
|
+
# Strip spoiler markers: ||text|| → text
|
|
21
|
+
text = text.gsub(/\|\|(.+?)\|\|/m, '\1')
|
|
22
|
+
|
|
23
|
+
# Unescape all backslash-escaped characters
|
|
24
|
+
text.gsub(/\\(.)/, '\1')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Standard Markdown → Telegram MarkdownV2
|
|
28
|
+
def from_markdown(markdown)
|
|
29
|
+
text = markdown.to_s
|
|
30
|
+
return "" if text.empty?
|
|
31
|
+
|
|
32
|
+
parts = split_code_blocks(text)
|
|
33
|
+
parts.map.with_index { |part, i| i.odd? ? part : escape_special_chars(part) }.join
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# Escape Telegram MarkdownV2 special chars outside of markdown syntax.
|
|
39
|
+
# Preserves bold (**), italic (*), strikethrough (~~), links, etc.
|
|
40
|
+
def escape_special_chars(text)
|
|
41
|
+
result = +""
|
|
42
|
+
i = 0
|
|
43
|
+
chars = text.chars
|
|
44
|
+
|
|
45
|
+
while i < chars.length
|
|
46
|
+
char = chars[i]
|
|
47
|
+
|
|
48
|
+
# Bold: **text** — pass through
|
|
49
|
+
if char == "*" && chars[i + 1] == "*"
|
|
50
|
+
close = text.index("**", i + 2)
|
|
51
|
+
if close
|
|
52
|
+
inner = text[(i + 2)...close]
|
|
53
|
+
result << "**#{escape_special_chars(inner)}**"
|
|
54
|
+
i = close + 2
|
|
55
|
+
next
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Italic: *text* (single asterisk, not preceded/followed by another *)
|
|
60
|
+
if char == "*" && chars[i + 1] != "*"
|
|
61
|
+
close = find_single_asterisk_close(chars, i + 1)
|
|
62
|
+
if close
|
|
63
|
+
inner = chars[(i + 1)...close].join
|
|
64
|
+
result << "*#{escape_special_chars(inner)}*"
|
|
65
|
+
i = close + 1
|
|
66
|
+
next
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Strikethrough: ~~text~~
|
|
71
|
+
if char == "~" && chars[i + 1] == "~"
|
|
72
|
+
close = text.index("~~", i + 2)
|
|
73
|
+
if close
|
|
74
|
+
inner = text[(i + 2)...close]
|
|
75
|
+
result << "~~#{escape_special_chars(inner)}~~"
|
|
76
|
+
i = close + 2
|
|
77
|
+
next
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Links: [text](url) — pass through
|
|
82
|
+
if char == "["
|
|
83
|
+
link_match = text[i..].match(/\A\[([^\]]*)\]\(([^)]*)\)/)
|
|
84
|
+
if link_match
|
|
85
|
+
result << link_match[0]
|
|
86
|
+
i += link_match[0].length
|
|
87
|
+
next
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Escape special characters
|
|
92
|
+
result << if SPECIAL_CHARS.include?(char)
|
|
93
|
+
"\\#{char}"
|
|
94
|
+
else
|
|
95
|
+
char
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
i += 1
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
result
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Find closing single * that isn't part of **
|
|
105
|
+
def find_single_asterisk_close(chars, start)
|
|
106
|
+
i = start
|
|
107
|
+
while i < chars.length
|
|
108
|
+
if chars[i] == "*" && chars[i + 1] != "*" && (i == start || chars[i - 1] != "*")
|
|
109
|
+
return i
|
|
110
|
+
end
|
|
111
|
+
i += 1
|
|
112
|
+
end
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: chat_sdk-telegram
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Quentin Rousseau
|
|
@@ -48,6 +48,7 @@ files:
|
|
|
48
48
|
- lib/chat_sdk/telegram/adapter.rb
|
|
49
49
|
- lib/chat_sdk/telegram/api_client.rb
|
|
50
50
|
- lib/chat_sdk/telegram/event_parser.rb
|
|
51
|
+
- lib/chat_sdk/telegram/format_converter.rb
|
|
51
52
|
- lib/chat_sdk/telegram/keyboard_renderer.rb
|
|
52
53
|
homepage: https://github.com/rootlyhq/chat-sdk
|
|
53
54
|
licenses:
|