Class: ChatSDK::Teams::FormatConverter

Inherits:
Format::Converter
  • Object
show all
Defined in:
lib/chat_sdk/teams/format_converter.rb

Instance Method Summary collapse

Instance Method Details

#from_markdown(markdown) ⇒ Object

Markdown → Teams HTML



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/chat_sdk/teams/format_converter.rb', line 56

def from_markdown(markdown)
  text = markdown.to_s
  return "" if text.empty?

  # Protect fenced code blocks first
  code_blocks = []
  text = text.gsub(/```\n?(.*?)\n?```/m) do
    code_blocks << Regexp.last_match(1)
    "\x00CODEBLOCK#{code_blocks.size - 1}\x00"
  end

  # Protect inline code spans
  code_spans = []
  text = text.gsub(/`([^`]+)`/) do
    code_spans << Regexp.last_match(1)
    "\x00CODESPAN#{code_spans.size - 1}\x00"
  end

  # Convert markdown formatting to HTML
  text = text.gsub(/\*\*(.+?)\*\*/m, '<b>\1</b>')
  text = text.gsub(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/m, '<i>\1</i>')
  text = text.gsub(/~~(.+?)~~/m, '<s>\1</s>')
  text = text.gsub(/\[([^\]]+)\]\(([^)]+)\)/, '<a href="\2">\1</a>')
  text = text.gsub("\n", "<br>")

  # Restore inline code spans
  code_spans.each_with_index do |content, i|
    text = text.sub("\x00CODESPAN#{i}\x00", "<code>#{content}</code>")
  end

  # Restore code blocks
  code_blocks.each_with_index do |content, i|
    text = text.sub("\x00CODEBLOCK#{i}\x00", "<pre>#{content}</pre>")
  end

  text
end

#to_markdown(platform_text) ⇒ Object

Teams HTML → Markdown



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/chat_sdk/teams/format_converter.rb', line 7

def to_markdown(platform_text)
  text = platform_text.to_s
  return "" if text.empty?

  # Protect <pre> blocks first — extract them before processing inline HTML
  pre_blocks = []
  text = text.gsub(%r{<pre>(.*?)</pre>}mi) do
    pre_blocks << Regexp.last_match(1)
    "\x00PRE#{pre_blocks.size - 1}\x00"
  end

  # Protect <code> spans
  code_spans = []
  text = text.gsub(%r{<code>(.*?)</code>}mi) do
    code_spans << Regexp.last_match(1)
    "\x00CODE#{code_spans.size - 1}\x00"
  end

  # Convert block-level elements
  text = convert_lists_to_markdown(text)

  # Convert inline formatting
  text = text.gsub(%r{<(?:b|strong)>(.*?)</(?:b|strong)>}mi, '**\1**')
  text = text.gsub(%r{<(?:i|em)>(.*?)</(?:i|em)>}mi, '*\1*')
  text = text.gsub(%r{<(?:s|strike|del)>(.*?)</(?:s|strike|del)>}mi, '~~\1~~')
  text = text.gsub(%r{<a\s+href="([^"]*)"[^>]*>(.*?)</a>}mi, '[\2](\1)')
  text = text.gsub(%r{<at>(.*?)</at>}mi, '@\1')
  text = text.gsub(%r{<br\s*/?>}i, "\n")

  # Decode HTML entities
  text = decode_html_entities(text)

  # Strip any remaining HTML tags
  text = text.gsub(/<[^>]+>/, "")

  # Restore code spans
  code_spans.each_with_index do |content, i|
    text = text.sub("\x00CODE#{i}\x00", "`#{content}`")
  end

  # Restore pre blocks
  pre_blocks.each_with_index do |content, i|
    text = text.sub("\x00PRE#{i}\x00", "```\n#{content}\n```")
  end

  text
end