slack_transformer 1.0.0
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 +7 -0
- data/lib/slack_transformer.rb +4 -0
- data/lib/slack_transformer/date.rb +41 -0
- data/lib/slack_transformer/entities.rb +18 -0
- data/lib/slack_transformer/html.rb +31 -0
- data/lib/slack_transformer/html/bold.rb +15 -0
- data/lib/slack_transformer/html/code.rb +15 -0
- data/lib/slack_transformer/html/italics.rb +15 -0
- data/lib/slack_transformer/html/lists.rb +36 -0
- data/lib/slack_transformer/html/preformatted.rb +15 -0
- data/lib/slack_transformer/html/strikethrough.rb +15 -0
- data/lib/slack_transformer/slack.rb +35 -0
- data/lib/slack_transformer/slack/blockquote.rb +42 -0
- data/lib/slack_transformer/slack/bold.rb +48 -0
- data/lib/slack_transformer/slack/code.rb +43 -0
- data/lib/slack_transformer/slack/italics.rb +48 -0
- data/lib/slack_transformer/slack/preformatted.rb +45 -0
- data/lib/slack_transformer/slack/quote.rb +39 -0
- data/lib/slack_transformer/slack/strikethrough.rb +48 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7313982b9621e47723717517eb8a2a889c113270
|
4
|
+
data.tar.gz: 2282671a2714cd2653bfdc565f606a91d055d99c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ee0ac743cea68183d15c70822bc4a556b1fa9a3570547230a78f903118e48138767e31afc9e39efa6a101f41095369a3e6e3fe97813e28dcbb47af5b90ef1a8
|
7
|
+
data.tar.gz: bce104f1a1256d4a25d0d4459b7170011ed9d79a4b3f4874dfb711795b14b2d500ffbc67a63af22ebd6dd42c5f4ba486a8ac6e966c2ec975275fee30d03262a9
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module SlackTransformer
|
5
|
+
class Date
|
6
|
+
attr_reader :input, :format, :link, :fallback
|
7
|
+
|
8
|
+
class InvalidTokenError < StandardError; end
|
9
|
+
|
10
|
+
# See https://api.slack.com/docs/message-formatting#formatting_dates
|
11
|
+
DATE_FORMAT_TOKENS = Set.new(%w[
|
12
|
+
{date_num}
|
13
|
+
{date}
|
14
|
+
{date_short}
|
15
|
+
{date_long}
|
16
|
+
{date_pretty}
|
17
|
+
{date_short_pretty}
|
18
|
+
{date_long_pretty}
|
19
|
+
{time}
|
20
|
+
{time_secs}
|
21
|
+
])
|
22
|
+
|
23
|
+
def initialize(input, format:, link: nil, fallback:)
|
24
|
+
@input = input
|
25
|
+
@format = format
|
26
|
+
@link = link
|
27
|
+
@fallback = fallback
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_slack
|
31
|
+
tokens = format.scan(/(\{\w+\})/).first
|
32
|
+
|
33
|
+
if tokens
|
34
|
+
invalid_tokens = tokens.reject { |t| DATE_FORMAT_TOKENS.include?(t) }
|
35
|
+
raise InvalidTokenError, invalid_tokens.join(', ') unless invalid_tokens.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
"<!date^#{Time.parse(input.to_s).to_i}^#{format}#{"^#{link}" if link}|#{fallback}>"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Entities
|
3
|
+
attr_reader :input
|
4
|
+
|
5
|
+
def initialize(input)
|
6
|
+
@input = input
|
7
|
+
end
|
8
|
+
|
9
|
+
# See https://api.slack.com/docs/message-formatting#how_to_escape_characters
|
10
|
+
# NB: The order matters here. If you were to replace < with < first, for
|
11
|
+
# example, you'd end up with &lt;
|
12
|
+
def to_slack
|
13
|
+
input.gsub('&', '&')
|
14
|
+
.gsub('<', '<')
|
15
|
+
.gsub('>', '>')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'slack_transformer/html/bold'
|
2
|
+
require 'slack_transformer/html/code'
|
3
|
+
require 'slack_transformer/html/italics'
|
4
|
+
require 'slack_transformer/html/lists'
|
5
|
+
require 'slack_transformer/html/preformatted'
|
6
|
+
require 'slack_transformer/html/strikethrough'
|
7
|
+
|
8
|
+
module SlackTransformer
|
9
|
+
class Html
|
10
|
+
attr_reader :input
|
11
|
+
|
12
|
+
TRANSFORMERS = [
|
13
|
+
SlackTransformer::Html::Bold,
|
14
|
+
SlackTransformer::Html::Italics,
|
15
|
+
SlackTransformer::Html::Strikethrough,
|
16
|
+
SlackTransformer::Html::Code,
|
17
|
+
SlackTransformer::Html::Preformatted,
|
18
|
+
SlackTransformer::Html::Lists
|
19
|
+
]
|
20
|
+
|
21
|
+
def initialize(input)
|
22
|
+
@input = input
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_slack
|
26
|
+
TRANSFORMERS.reduce(input) do |html, transformer|
|
27
|
+
transformer.new(html).to_slack
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module SlackTransformer
|
4
|
+
class Html
|
5
|
+
class Lists
|
6
|
+
attr_reader :input
|
7
|
+
|
8
|
+
def initialize(input)
|
9
|
+
@input = input
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_slack
|
13
|
+
fragment = Nokogiri::HTML.fragment(input)
|
14
|
+
|
15
|
+
fragment.children.each do |child|
|
16
|
+
case child.name
|
17
|
+
when 'ul'
|
18
|
+
list = child.children.map do |c|
|
19
|
+
"• #{c.children.to_html}"
|
20
|
+
end
|
21
|
+
|
22
|
+
child.replace(list.join("\n"))
|
23
|
+
when 'ol'
|
24
|
+
list = child.children.map.with_index do |c, i|
|
25
|
+
"#{i + 1}. #{c.children.to_html}"
|
26
|
+
end
|
27
|
+
|
28
|
+
child.replace(list.join("\n"))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
fragment.to_html
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'slack_transformer/slack/blockquote'
|
2
|
+
require 'slack_transformer/slack/bold'
|
3
|
+
require 'slack_transformer/slack/code'
|
4
|
+
require 'slack_transformer/slack/italics'
|
5
|
+
require 'slack_transformer/slack/preformatted'
|
6
|
+
require 'slack_transformer/slack/quote'
|
7
|
+
require 'slack_transformer/slack/strikethrough'
|
8
|
+
|
9
|
+
module SlackTransformer
|
10
|
+
class Slack
|
11
|
+
attr_reader :input
|
12
|
+
|
13
|
+
TRANSFORMERS = [
|
14
|
+
SlackTransformer::Slack::Bold,
|
15
|
+
SlackTransformer::Slack::Italics,
|
16
|
+
SlackTransformer::Slack::Strikethrough,
|
17
|
+
SlackTransformer::Slack::Code,
|
18
|
+
SlackTransformer::Slack::Preformatted,
|
19
|
+
SlackTransformer::Slack::Quote,
|
20
|
+
SlackTransformer::Slack::Blockquote
|
21
|
+
]
|
22
|
+
|
23
|
+
def initialize(input)
|
24
|
+
@input = input
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_html
|
28
|
+
html = TRANSFORMERS.reduce(input) do |html, transformer|
|
29
|
+
transformer.new(html).to_html
|
30
|
+
end
|
31
|
+
|
32
|
+
"<p>#{html.gsub("\n", '<br>')}</p>"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Blockquote
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
^
|
8
|
+
|
9
|
+
# start of line
|
10
|
+
|
11
|
+
([*_~]?)
|
12
|
+
|
13
|
+
# optionally preceded by *, _, or ~
|
14
|
+
|
15
|
+
>{3}(.+)
|
16
|
+
|
17
|
+
# one or more of anything preceded by >
|
18
|
+
|
19
|
+
\1
|
20
|
+
|
21
|
+
# followed by *, _, or ~ if preceded by it
|
22
|
+
|
23
|
+
$
|
24
|
+
|
25
|
+
# end of line
|
26
|
+
/mx
|
27
|
+
|
28
|
+
def initialize(input)
|
29
|
+
@input = input
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_html
|
33
|
+
input.gsub(PATTERN) do
|
34
|
+
outer = Regexp.last_match(1)
|
35
|
+
inner = Regexp.last_match(2).gsub("\n", '<br>')
|
36
|
+
|
37
|
+
"#{outer}<blockquote>#{inner}</blockquote>#{outer}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Bold
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
(?<=^|\W)
|
8
|
+
|
9
|
+
# preceded by start of line or non-word character
|
10
|
+
|
11
|
+
(?<![*~`])
|
12
|
+
|
13
|
+
# but not *, ~, or `, which are mrkdwn delimiters
|
14
|
+
# Note: _ is also a mrkdwn delimiter, but it's included in \W because
|
15
|
+
# it's a word character.
|
16
|
+
|
17
|
+
([_~]?)
|
18
|
+
|
19
|
+
# optionally preceded by _ or ~
|
20
|
+
|
21
|
+
\*((?:[^*]|(?<=[\w\s])\*+(?=\w))+)\*
|
22
|
+
|
23
|
+
# one or more of either not *, or one or more * preceded by word
|
24
|
+
# character or space and followed by word character, surrounded by *
|
25
|
+
|
26
|
+
\1
|
27
|
+
|
28
|
+
# followed by _ or ~ if preceded by it
|
29
|
+
|
30
|
+
(?![*`])
|
31
|
+
|
32
|
+
# not followed by * or `
|
33
|
+
|
34
|
+
(?=\W|$)
|
35
|
+
|
36
|
+
# followed by non-word character or end of line
|
37
|
+
/x
|
38
|
+
|
39
|
+
def initialize(input)
|
40
|
+
@input = input
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_html
|
44
|
+
input.gsub(PATTERN, '\1<b>\2</b>\1')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Code
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
(?<=^|\W|_)
|
8
|
+
|
9
|
+
# preceded by start of line, non-word character, or _
|
10
|
+
|
11
|
+
(?<!`)
|
12
|
+
|
13
|
+
# but not `
|
14
|
+
|
15
|
+
`([^`]+?)(`+)
|
16
|
+
|
17
|
+
# one or more of not ` preceded by ` followed by one or more `
|
18
|
+
/x
|
19
|
+
|
20
|
+
def initialize(input)
|
21
|
+
@input = input
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_html
|
25
|
+
input.gsub(PATTERN) do |match|
|
26
|
+
closing_backticks = Regexp.last_match(2)
|
27
|
+
closing_backticks_length = closing_backticks.length
|
28
|
+
closing_backticks_remainder = closing_backticks_length % 3
|
29
|
+
|
30
|
+
if closing_backticks_remainder == 0
|
31
|
+
match
|
32
|
+
else
|
33
|
+
inner_text = Regexp.last_match(1)
|
34
|
+
inner_trailing_backticks = '`' * (closing_backticks_length / 3 * 3)
|
35
|
+
outer_trailing_backticks = '`' * (closing_backticks_remainder - 1)
|
36
|
+
|
37
|
+
"<code>#{inner_text}#{inner_trailing_backticks}</code>#{outer_trailing_backticks}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Italics
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
(?<=^|\W)
|
8
|
+
|
9
|
+
# preceded by start of line or non-word character
|
10
|
+
|
11
|
+
(?<![*~`])
|
12
|
+
|
13
|
+
# but not *, ~, or `, which are mrkdwn delimiters
|
14
|
+
# Note: _ is also a mrkdwn delimiter, but it's included in \W because
|
15
|
+
# it's a word character.
|
16
|
+
|
17
|
+
([*~]?)
|
18
|
+
|
19
|
+
# optionally preceded by * or ~
|
20
|
+
|
21
|
+
_((?:[^_]|(?<=[a-zA-Z0-9\s])_+(?=[a-zA-Z0-9]))+)_
|
22
|
+
|
23
|
+
# one or more of either not _, or one or more _ preceded by letter,
|
24
|
+
# number, or space and followed by letter or number, surrounded by _
|
25
|
+
|
26
|
+
\1
|
27
|
+
|
28
|
+
# followed by * or ~ if preceded by it
|
29
|
+
|
30
|
+
(?!```)
|
31
|
+
|
32
|
+
# not followed by ```
|
33
|
+
|
34
|
+
(?=\W|$)
|
35
|
+
|
36
|
+
# followed by non-word character or end of line
|
37
|
+
/x
|
38
|
+
|
39
|
+
def initialize(input)
|
40
|
+
@input = input
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_html
|
44
|
+
input.gsub(PATTERN, '\1<i>\2</i>\1')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Preformatted
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
(?<=^|\W|_)
|
8
|
+
|
9
|
+
# preceded by start of line, non-word character, or _
|
10
|
+
|
11
|
+
(?<!~)
|
12
|
+
|
13
|
+
# but not ~
|
14
|
+
|
15
|
+
([*_~]?)
|
16
|
+
|
17
|
+
# optionally preceded by *, _, or ~
|
18
|
+
|
19
|
+
```(.+)```
|
20
|
+
|
21
|
+
# one or more of anything surrounded by ```
|
22
|
+
|
23
|
+
\1
|
24
|
+
|
25
|
+
# followed by *, _, or ~ if preceded by it
|
26
|
+
|
27
|
+
(?!~)
|
28
|
+
|
29
|
+
# not followed by ~
|
30
|
+
|
31
|
+
(?=\W|_|$)
|
32
|
+
|
33
|
+
# followed by non-word character, _, or end of line
|
34
|
+
/x
|
35
|
+
|
36
|
+
def initialize(input)
|
37
|
+
@input = input
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_html
|
41
|
+
input.gsub(PATTERN, '\1<pre>\2</pre>\1')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Quote
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
^
|
8
|
+
|
9
|
+
# start of line
|
10
|
+
|
11
|
+
([*_~]?)
|
12
|
+
|
13
|
+
# optionally preceded by *, _, or ~
|
14
|
+
|
15
|
+
>(.+?)
|
16
|
+
|
17
|
+
# one or more of anything preceded by >
|
18
|
+
|
19
|
+
\1
|
20
|
+
|
21
|
+
# followed by *, _, or ~ if preceded by it
|
22
|
+
|
23
|
+
(?:\n|$)
|
24
|
+
|
25
|
+
# followed by newline or end of line
|
26
|
+
/x
|
27
|
+
|
28
|
+
def initialize(input)
|
29
|
+
@input = input
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_html
|
33
|
+
input.gsub(PATTERN, '\1<blockquote>\2</blockquote>\1')
|
34
|
+
.gsub('</blockquote><blockquote>', '<br>')
|
35
|
+
.gsub(/(>(?:\n|$)){2,}/) { |match| match[0...-2] }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SlackTransformer
|
2
|
+
class Slack
|
3
|
+
class Strikethrough
|
4
|
+
attr_reader :input
|
5
|
+
|
6
|
+
PATTERN = /
|
7
|
+
(?<=^|\W)
|
8
|
+
|
9
|
+
# preceded by start of line or non-word character
|
10
|
+
|
11
|
+
(?<![*~`])
|
12
|
+
|
13
|
+
# but not *, ~, or `, which are mrkdwn delimiters
|
14
|
+
# Note: _ is also a mrkdwn delimiter, but it's included in \W because
|
15
|
+
# it's a word character.
|
16
|
+
|
17
|
+
([*_]?)
|
18
|
+
|
19
|
+
# optionally preceded by * or _
|
20
|
+
|
21
|
+
~((?:[^~]|(?<=[\w\s])~+(?=\w))+)~
|
22
|
+
|
23
|
+
# one or more of either not ~, or one or more ~ preceded by word
|
24
|
+
# character or space and followed by word character, surrounded by ~
|
25
|
+
|
26
|
+
\1
|
27
|
+
|
28
|
+
# followed by * or _ if preceded by it
|
29
|
+
|
30
|
+
(?![*`])
|
31
|
+
|
32
|
+
# not followed by * or `
|
33
|
+
|
34
|
+
(?=\W|$)
|
35
|
+
|
36
|
+
# followed by non-word character or end of line
|
37
|
+
/x
|
38
|
+
|
39
|
+
def initialize(input)
|
40
|
+
@input = input
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_html
|
44
|
+
input.gsub(PATTERN, '\1<s>\2</s>\1')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slack_transformer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Wang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.8.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.8.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.7.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.7.0
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- eric@geteverwise.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/slack_transformer.rb
|
49
|
+
- lib/slack_transformer/date.rb
|
50
|
+
- lib/slack_transformer/entities.rb
|
51
|
+
- lib/slack_transformer/html.rb
|
52
|
+
- lib/slack_transformer/html/bold.rb
|
53
|
+
- lib/slack_transformer/html/code.rb
|
54
|
+
- lib/slack_transformer/html/italics.rb
|
55
|
+
- lib/slack_transformer/html/lists.rb
|
56
|
+
- lib/slack_transformer/html/preformatted.rb
|
57
|
+
- lib/slack_transformer/html/strikethrough.rb
|
58
|
+
- lib/slack_transformer/slack.rb
|
59
|
+
- lib/slack_transformer/slack/blockquote.rb
|
60
|
+
- lib/slack_transformer/slack/bold.rb
|
61
|
+
- lib/slack_transformer/slack/code.rb
|
62
|
+
- lib/slack_transformer/slack/italics.rb
|
63
|
+
- lib/slack_transformer/slack/preformatted.rb
|
64
|
+
- lib/slack_transformer/slack/quote.rb
|
65
|
+
- lib/slack_transformer/slack/strikethrough.rb
|
66
|
+
homepage: https://github.com/everwise/slack_transformer
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.4.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Transform HTML into Slack-ready mrkdwn and back
|
90
|
+
test_files: []
|