From 7f66506ab34f21189a7445a5216d3102dca913da Mon Sep 17 00:00:00 2001 From: Mimi Lee Date: Tue, 21 May 2024 10:43:18 -0700 Subject: [PATCH 1/9] Add support for hyperlinks and nested lists --- lib/slack_transformer/html.rb | 5 ++- lib/slack_transformer/html/hyperlinks.rb | 32 +++++++++++++++ lib/slack_transformer/html/lists.rb | 39 ++++++++++++++----- .../slack_transformer/html/hyperlinks_spec.rb | 21 ++++++++++ spec/slack_transformer/html/lists_spec.rb | 16 ++++++++ 5 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 lib/slack_transformer/html/hyperlinks.rb create mode 100644 spec/slack_transformer/html/hyperlinks_spec.rb diff --git a/lib/slack_transformer/html.rb b/lib/slack_transformer/html.rb index 3952abd..8527845 100644 --- a/lib/slack_transformer/html.rb +++ b/lib/slack_transformer/html.rb @@ -1,5 +1,6 @@ require 'slack_transformer/html/bold' require 'slack_transformer/html/code' +require 'slack_transformer/html/hyperlinks' require 'slack_transformer/html/italics' require 'slack_transformer/html/lists' require 'slack_transformer/html/preformatted' @@ -10,12 +11,14 @@ class Html attr_reader :input TRANSFORMERS = [ + # Need to use the transformers using Nokogiri first before using gsub. + SlackTransformer::Html::Lists, SlackTransformer::Html::Bold, SlackTransformer::Html::Italics, SlackTransformer::Html::Strikethrough, SlackTransformer::Html::Code, SlackTransformer::Html::Preformatted, - SlackTransformer::Html::Lists + SlackTransformer::Html::Hyperlinks ] def initialize(input) diff --git a/lib/slack_transformer/html/hyperlinks.rb b/lib/slack_transformer/html/hyperlinks.rb new file mode 100644 index 0000000..68ecbbb --- /dev/null +++ b/lib/slack_transformer/html/hyperlinks.rb @@ -0,0 +1,32 @@ +require 'nokogiri' + +module SlackTransformer + class Html + class Hyperlinks + attr_reader :input + + def initialize(input) + @input = input + end + + def to_slack + fragment = Nokogiri::HTML.fragment(input) + + links_to_replace = {} + fragment.children.each do |child| + if child.name == 'a' + hyperlink_text = child.text.empty? ? child.attr('href') : child.text + hyperlink = "<#{child.attr('href')}|#{hyperlink_text}>" + links_to_replace[child.to_s] = hyperlink + end + end + + links_to_replace.each do |html, hyperlink| + input.gsub!(html, hyperlink) + end + + input + end + end + end +end diff --git a/lib/slack_transformer/html/lists.rb b/lib/slack_transformer/html/lists.rb index c4a8753..738cec3 100644 --- a/lib/slack_transformer/html/lists.rb +++ b/lib/slack_transformer/html/lists.rb @@ -15,22 +15,41 @@ def to_slack fragment.children.each do |child| case child.name when 'ul' - list = child.children.map do |c| - "• #{c.children.to_html}" - end - - child.replace(list.join("\n")) + child.replace(indent_nested_list(child))) when 'ol' - list = child.children.map.with_index do |c, i| - "#{i + 1}. #{c.children.to_html}" - end - - child.replace(list.join("\n")) + child.replace(indent_nested_number_list(child)) end end fragment.to_html end + + def indent_nested_list(child, num_indent = 0) + child.children.map do |c| + + case c.name + when 'li' + indent_nested_list(c, num_indent) + when 'ul' + indent_nested_list(c, num_indent += 1) + else + "#{"\t" * num_indent}• #{c.to_html}" + end + end.join("\n") + end + + def indent_nested_number_list(child, num_indent = 0, index = 0) + child.children.map do |c| + case c.name + when 'li' + indent_nested_number_list(c, num_indent, index += 1) + when 'ol' + indent_nested_number_list(c, num_indent += 1, 0) + else + "#{"\t" * num_indent}#{index}. #{c.to_html}" + end + end.join("\n") + end end end end diff --git a/spec/slack_transformer/html/hyperlinks_spec.rb b/spec/slack_transformer/html/hyperlinks_spec.rb new file mode 100644 index 0000000..c8b797a --- /dev/null +++ b/spec/slack_transformer/html/hyperlinks_spec.rb @@ -0,0 +1,21 @@ +require 'slack_transformer/html/hyperlinks' + +RSpec.describe SlackTransformer::Html::Hyperlinks do + let(:transformation) { described_class.new(input) } + + describe '#to_slack' do + context 'when hyperlink text is present' do + let(:input) { 'test link' } + it 'replaces HTML a Tag with slack hyperlink' do + expect(transformation.to_slack).to eq('') + end + end + + context 'when hyperlink text is not present' do + let(:input) { '' } + it 'uses the href as the hyperlink text' do + expect(transformation.to_slack).to eq('') + end + end + end +end diff --git a/spec/slack_transformer/html/lists_spec.rb b/spec/slack_transformer/html/lists_spec.rb index b949af5..b581eee 100644 --- a/spec/slack_transformer/html/lists_spec.rb +++ b/spec/slack_transformer/html/lists_spec.rb @@ -12,6 +12,14 @@ end end + context 'when a nested list is unordered' do + let(:input) { '
  • foo
    • bar
      • baz
' } + + it 'replaces the list' do + expect(transformation.to_slack).to eq("• foo\n\t• bar\n\t\t• baz") + end + end + context 'when a list is ordered' do let(:input) { '
  1. foo
  2. bar
  3. baz
' } @@ -19,5 +27,13 @@ expect(transformation.to_slack).to eq("1. foo\n2. bar\n3. baz") end end + + context 'when a nested list is ordered' do + let(:input) { '
  1. foo
    1. bar
      1. baz
' } + + it 'replaces the list' do + expect(transformation.to_slack).to eq("1. foo\n\t1. bar\n\t\t1. baz") + end + end end end From 25159443acd59a0ead395f56558d904301695964 Mon Sep 17 00:00:00 2001 From: Mimi Lee Date: Tue, 21 May 2024 10:48:27 -0700 Subject: [PATCH 2/9] Remove extra paranthesis --- lib/slack_transformer/html/lists.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack_transformer/html/lists.rb b/lib/slack_transformer/html/lists.rb index 738cec3..e81f337 100644 --- a/lib/slack_transformer/html/lists.rb +++ b/lib/slack_transformer/html/lists.rb @@ -15,7 +15,7 @@ def to_slack fragment.children.each do |child| case child.name when 'ul' - child.replace(indent_nested_list(child))) + child.replace(indent_nested_list(child)) when 'ol' child.replace(indent_nested_number_list(child)) end From 2661bf2164cba1942948ac3602bbd5e299a14535 Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Tue, 28 May 2024 12:06:27 -0400 Subject: [PATCH 3/9] added newline --- lib/slack_transformer/html/newline.rb | 29 ++++++++++++ spec/slack_transformer/html/newline_spec.rb | 50 +++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 lib/slack_transformer/html/newline.rb create mode 100644 spec/slack_transformer/html/newline_spec.rb diff --git a/lib/slack_transformer/html/newline.rb b/lib/slack_transformer/html/newline.rb new file mode 100644 index 0000000..ce7486f --- /dev/null +++ b/lib/slack_transformer/html/newline.rb @@ -0,0 +1,29 @@ +require 'nokogiri' + +module SlackTransformer + class Html + class Newline + attr_reader :input + + def initialize(input) + @input = input + end + + def to_slack + # input.gsub(/<\/?p>/, '\n') + fragment = Nokogiri::HTML.fragment(input) + + fragment.children.each do |child| + case child.name + when 'p' + child.replace("\n #{child.children.to_html} \n") + when 'br' + child.replace("\n") + end + end + + fragment.to_html + end + end + end +end diff --git a/spec/slack_transformer/html/newline_spec.rb b/spec/slack_transformer/html/newline_spec.rb new file mode 100644 index 0000000..7d2a998 --- /dev/null +++ b/spec/slack_transformer/html/newline_spec.rb @@ -0,0 +1,50 @@ +require 'slack_transformer/html/newline' + + +RSpec.describe SlackTransformer::Html::Newline do + let(:transformation) { described_class.new(input) } + + describe '#to_slack' do + context 'when a tag

exist' do + let(:input) { '

new paragraph

' } + + it 'wrapping the content with \n' do + expect(transformation.to_slack).to eq("\n new paragraph \n") + end + end + + context 'when only opening tag

exist' do + let(:input) { '

new paragraph' } + + it 'wrapping the content with \n' do + expect(transformation.to_slack).to eq("\n new paragraph \n") + end + end + + context 'when
tag exist' do + let(:input) { '
newline' } + + it 'just add a newline in the beginning' do + expect(transformation.to_slack).to eq("\n newline") + end + end + + context 'when
tag exist' do + let(:input) { '
newline' } + + it 'just add a newine in teh beginning' do + expect(transformation.to_slack).to eq("\n newline") + end + end + + context 'when

tag exist' do + let(:input) { '
newline
' } + + it 'just add a newine in teh beginning' do + expect(transformation.to_slack).to eq("\n newline") + end + end + + end + end + \ No newline at end of file From 88ca3036aa71e66c6786fe3bcdb3eb2b7f13bbf8 Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Tue, 28 May 2024 13:54:46 -0400 Subject: [PATCH 4/9] cleanup and adjustemnt --- lib/slack_transformer/html.rb | 4 +++- lib/slack_transformer/html/newline.rb | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/slack_transformer/html.rb b/lib/slack_transformer/html.rb index 8527845..7fd8c9a 100644 --- a/lib/slack_transformer/html.rb +++ b/lib/slack_transformer/html.rb @@ -1,6 +1,7 @@ require 'slack_transformer/html/bold' require 'slack_transformer/html/code' require 'slack_transformer/html/hyperlinks' +require 'slack_transformer/html/newline' require 'slack_transformer/html/italics' require 'slack_transformer/html/lists' require 'slack_transformer/html/preformatted' @@ -18,7 +19,8 @@ class Html SlackTransformer::Html::Strikethrough, SlackTransformer::Html::Code, SlackTransformer::Html::Preformatted, - SlackTransformer::Html::Hyperlinks + SlackTransformer::Html::Hyperlinks, + SlackTransformer::Html::Newline ] def initialize(input) diff --git a/lib/slack_transformer/html/newline.rb b/lib/slack_transformer/html/newline.rb index ce7486f..df679cd 100644 --- a/lib/slack_transformer/html/newline.rb +++ b/lib/slack_transformer/html/newline.rb @@ -9,8 +9,7 @@ def initialize(input) @input = input end - def to_slack - # input.gsub(/<\/?p>/, '\n') + def to_slack fragment = Nokogiri::HTML.fragment(input) fragment.children.each do |child| From c600241a55e3c41cdfdc6d81c8231003ac26231f Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Wed, 29 May 2024 11:08:01 -0400 Subject: [PATCH 5/9] separated paragraph from newline and fixed the logic for paragraph --- lib/slack_transformer/html.rb | 4 +- lib/slack_transformer/html/newline.rb | 9 +-- lib/slack_transformer/html/paragraph.rb | 38 +++++++++ spec/slack_transformer/html/newline_spec.rb | 17 +--- spec/slack_transformer/html/paragraph_spec.rb | 80 +++++++++++++++++++ 5 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 lib/slack_transformer/html/paragraph.rb create mode 100644 spec/slack_transformer/html/paragraph_spec.rb diff --git a/lib/slack_transformer/html.rb b/lib/slack_transformer/html.rb index 7fd8c9a..d1837b6 100644 --- a/lib/slack_transformer/html.rb +++ b/lib/slack_transformer/html.rb @@ -2,6 +2,7 @@ require 'slack_transformer/html/code' require 'slack_transformer/html/hyperlinks' require 'slack_transformer/html/newline' +require 'slack_transformer/html/paragraph' require 'slack_transformer/html/italics' require 'slack_transformer/html/lists' require 'slack_transformer/html/preformatted' @@ -20,7 +21,8 @@ class Html SlackTransformer::Html::Code, SlackTransformer::Html::Preformatted, SlackTransformer::Html::Hyperlinks, - SlackTransformer::Html::Newline + SlackTransformer::Html::Newline, + SlackTransformer::Html::Paragraph ] def initialize(input) diff --git a/lib/slack_transformer/html/newline.rb b/lib/slack_transformer/html/newline.rb index df679cd..faa314e 100644 --- a/lib/slack_transformer/html/newline.rb +++ b/lib/slack_transformer/html/newline.rb @@ -9,16 +9,11 @@ def initialize(input) @input = input end - def to_slack + def to_slack fragment = Nokogiri::HTML.fragment(input) fragment.children.each do |child| - case child.name - when 'p' - child.replace("\n #{child.children.to_html} \n") - when 'br' - child.replace("\n") - end + child.replace("\n") if child.name == 'br' end fragment.to_html diff --git a/lib/slack_transformer/html/paragraph.rb b/lib/slack_transformer/html/paragraph.rb new file mode 100644 index 0000000..c9f18c7 --- /dev/null +++ b/lib/slack_transformer/html/paragraph.rb @@ -0,0 +1,38 @@ +require 'nokogiri' + +module SlackTransformer + class Html + class Paragraph + attr_reader :input + + def initialize(input) + @input = input + end + + def to_slack + fragment = Nokogiri::HTML.fragment(input) + previous = nil + + fragment.children.each do |child| + if child.name == 'p' + + if previous.nil? + child.replace("#{child.children.to_html}") + else + child.replace("\n#{child.children.to_html}") + end + + previous = child.children.empty? ? nil : 'p' + + else + current = child.name + child.replace("\n#{child.to_html}") if previous == 'p' + previous = current + end + end + + fragment.to_html + end + end + end +end diff --git a/spec/slack_transformer/html/newline_spec.rb b/spec/slack_transformer/html/newline_spec.rb index 7d2a998..885b249 100644 --- a/spec/slack_transformer/html/newline_spec.rb +++ b/spec/slack_transformer/html/newline_spec.rb @@ -5,22 +5,7 @@ let(:transformation) { described_class.new(input) } describe '#to_slack' do - context 'when a tag

exist' do - let(:input) { '

new paragraph

' } - - it 'wrapping the content with \n' do - expect(transformation.to_slack).to eq("\n new paragraph \n") - end - end - - context 'when only opening tag

exist' do - let(:input) { '

new paragraph' } - - it 'wrapping the content with \n' do - expect(transformation.to_slack).to eq("\n new paragraph \n") - end - end - + context 'when
tag exist' do let(:input) { '
newline' } diff --git a/spec/slack_transformer/html/paragraph_spec.rb b/spec/slack_transformer/html/paragraph_spec.rb new file mode 100644 index 0000000..575a866 --- /dev/null +++ b/spec/slack_transformer/html/paragraph_spec.rb @@ -0,0 +1,80 @@ +require 'slack_transformer/html/paragraph' + + +RSpec.describe SlackTransformer::Html::Paragraph do + let(:transformation) { described_class.new(input) } + describe '#to_slack' do + + context '

Hello World

' do + let(:input) { '

Hello World

' } + + it 'return Hello World' do + expect(transformation.to_slack).to eq('Hello World') + end + end + + context '

Hello

World

' do + let(:input) { '

Hello

World

' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld") + end + end + + context 'Hello

World

Again' do + let(:input) { 'Hello

World

Again' } + + it 'return World and Again on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld\nAgain") + end + end + + context 'Hello

World

' do + let(:input) { 'Hello

World

' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld") + end + end + + context '

Hello

World' do + let(:input) { '

Hello

World' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld") + end + end + + context 'Hello

World' do + let(:input) { 'Hello

World' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld") + end + end + + context 'Hello

World

' do + let(:input) { 'Hello

World

' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld\n") + end + end + + + + context '

Hello

World' do + let(:input) { '

Hello

World' } + + it 'return World on a newline' do + expect(transformation.to_slack).to eq("Hello\nWorld") + end + end + + + + + + end + end + \ No newline at end of file From 0ebf012d48c8dbc1316cb64981f438f764217cc4 Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Wed, 29 May 2024 11:18:23 -0400 Subject: [PATCH 6/9] adjustment in newline test --- spec/slack_transformer/html/newline_spec.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/slack_transformer/html/newline_spec.rb b/spec/slack_transformer/html/newline_spec.rb index 885b249..b8aa77a 100644 --- a/spec/slack_transformer/html/newline_spec.rb +++ b/spec/slack_transformer/html/newline_spec.rb @@ -7,26 +7,26 @@ describe '#to_slack' do context 'when
tag exist' do - let(:input) { '
newline' } + let(:input) { '
newline' } - it 'just add a newline in the beginning' do - expect(transformation.to_slack).to eq("\n newline") + it 'just add a newline at the beginning' do + expect(transformation.to_slack).to eq("\nnewline") end end context 'when
tag exist' do - let(:input) { '
newline' } + let(:input) { '
newline' } - it 'just add a newine in teh beginning' do - expect(transformation.to_slack).to eq("\n newline") + it 'just add a newline at the beginning' do + expect(transformation.to_slack).to eq("\nnewline") end end context 'when

tag exist' do - let(:input) { '
newline
' } + let(:input) { '
newline
' } - it 'just add a newine in teh beginning' do - expect(transformation.to_slack).to eq("\n newline") + it 'just add a newline at the beginning' do + expect(transformation.to_slack).to eq("\nnewline") end end From 0365d1f7004081346e4487894de709941e538df9 Mon Sep 17 00:00:00 2001 From: Fatemeh <114527410+fatemeh-affinity@users.noreply.github.com> Date: Wed, 29 May 2024 13:53:11 -0400 Subject: [PATCH 7/9] Update lib/slack_transformer/html/paragraph.rb Co-authored-by: mimslee32 <35465554+mimslee32@users.noreply.github.com> --- lib/slack_transformer/html/paragraph.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/slack_transformer/html/paragraph.rb b/lib/slack_transformer/html/paragraph.rb index c9f18c7..9baadf9 100644 --- a/lib/slack_transformer/html/paragraph.rb +++ b/lib/slack_transformer/html/paragraph.rb @@ -16,11 +16,8 @@ def to_slack fragment.children.each do |child| if child.name == 'p' - if previous.nil? - child.replace("#{child.children.to_html}") - else - child.replace("\n#{child.children.to_html}") - end + newline = previous.nil? ? "" : "\n" + child.replace("#{newline}#{child.children.to_html}") previous = child.children.empty? ? nil : 'p' From 9125bc0eb2a01ed363c85b78cec2a762823beacf Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Wed, 29 May 2024 15:05:12 -0400 Subject: [PATCH 8/9] moved the newly added transformers to the head of the transformer list in html file --- lib/slack_transformer/html.rb | 6 +++--- lib/slack_transformer/html/newline.rb | 2 +- lib/slack_transformer/html/paragraph.rb | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/slack_transformer/html.rb b/lib/slack_transformer/html.rb index d1837b6..5bb2833 100644 --- a/lib/slack_transformer/html.rb +++ b/lib/slack_transformer/html.rb @@ -14,15 +14,15 @@ class Html TRANSFORMERS = [ # Need to use the transformers using Nokogiri first before using gsub. + SlackTransformer::Html::Newline, + SlackTransformer::Html::Paragraph, SlackTransformer::Html::Lists, SlackTransformer::Html::Bold, SlackTransformer::Html::Italics, SlackTransformer::Html::Strikethrough, SlackTransformer::Html::Code, SlackTransformer::Html::Preformatted, - SlackTransformer::Html::Hyperlinks, - SlackTransformer::Html::Newline, - SlackTransformer::Html::Paragraph + SlackTransformer::Html::Hyperlinks ] def initialize(input) diff --git a/lib/slack_transformer/html/newline.rb b/lib/slack_transformer/html/newline.rb index faa314e..65f2b3b 100644 --- a/lib/slack_transformer/html/newline.rb +++ b/lib/slack_transformer/html/newline.rb @@ -13,7 +13,7 @@ def to_slack fragment = Nokogiri::HTML.fragment(input) fragment.children.each do |child| - child.replace("\n") if child.name == 'br' + child.replace("\n") if child.name == 'br' end fragment.to_html diff --git a/lib/slack_transformer/html/paragraph.rb b/lib/slack_transformer/html/paragraph.rb index c9f18c7..16f68a9 100644 --- a/lib/slack_transformer/html/paragraph.rb +++ b/lib/slack_transformer/html/paragraph.rb @@ -12,21 +12,18 @@ def initialize(input) def to_slack fragment = Nokogiri::HTML.fragment(input) previous = nil - fragment.children.each do |child| if child.name == 'p' - if previous.nil? child.replace("#{child.children.to_html}") else child.replace("\n#{child.children.to_html}") end - + # We don't want to add a newline after the last paragraph tag if it's empty. previous = child.children.empty? ? nil : 'p' - else current = child.name - child.replace("\n#{child.to_html}") if previous == 'p' + child.replace("\n#{child.to_html}") if previous == 'p' previous = current end end From 6349b90c967f5c7556dcee5b974d60aadcee0040 Mon Sep 17 00:00:00 2001 From: Fatemeh Date: Wed, 29 May 2024 15:09:55 -0400 Subject: [PATCH 9/9] removed extra empty lines --- spec/slack_transformer/html/paragraph_spec.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/spec/slack_transformer/html/paragraph_spec.rb b/spec/slack_transformer/html/paragraph_spec.rb index 575a866..a4af628 100644 --- a/spec/slack_transformer/html/paragraph_spec.rb +++ b/spec/slack_transformer/html/paragraph_spec.rb @@ -2,9 +2,9 @@ RSpec.describe SlackTransformer::Html::Paragraph do - let(:transformation) { described_class.new(input) } + let(:transformation) { described_class.new(input) } + describe '#to_slack' do - context '

Hello World

' do let(:input) { '

Hello World

' } @@ -61,8 +61,6 @@ end end - - context '

Hello

World' do let(:input) { '

Hello

World' } @@ -70,11 +68,6 @@ expect(transformation.to_slack).to eq("Hello\nWorld") end end - - - - - end end \ No newline at end of file