rich_text_renderer 0.1.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/.gitignore +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +27 -0
- data/.rubocop_todo.yml +35 -0
- data/.travis.yml +13 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +3 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +87 -0
- data/Rakefile +33 -0
- data/lib/rich_text_renderer.rb +2 -0
- data/lib/rich_text_renderer/base_node_renderer.rb +18 -0
- data/lib/rich_text_renderer/block_renderers.rb +18 -0
- data/lib/rich_text_renderer/block_renderers/base_block_renderer.rb +24 -0
- data/lib/rich_text_renderer/block_renderers/blockquote_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/entry_block_renderer.rb +13 -0
- data/lib/rich_text_renderer/block_renderers/heading_five_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/heading_four_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/heading_one_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/heading_six_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/heading_three_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/heading_two_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/hr_renderer.rb +11 -0
- data/lib/rich_text_renderer/block_renderers/hyperlink_renderer.rb +11 -0
- data/lib/rich_text_renderer/block_renderers/list_item_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/ordered_list_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/paragraph_renderer.rb +12 -0
- data/lib/rich_text_renderer/block_renderers/unordered_list_renderer.rb +12 -0
- data/lib/rich_text_renderer/document_renderers.rb +1 -0
- data/lib/rich_text_renderer/document_renderers/document_renderer.rb +13 -0
- data/lib/rich_text_renderer/null_renderer.rb +19 -0
- data/lib/rich_text_renderer/renderer.rb +46 -0
- data/lib/rich_text_renderer/text_renderers.rb +5 -0
- data/lib/rich_text_renderer/text_renderers/base_inline_renderer.rb +17 -0
- data/lib/rich_text_renderer/text_renderers/bold_renderer.rb +12 -0
- data/lib/rich_text_renderer/text_renderers/code_renderer.rb +12 -0
- data/lib/rich_text_renderer/text_renderers/italic_renderer.rb +12 -0
- data/lib/rich_text_renderer/text_renderers/text_renderer.rb +19 -0
- data/lib/rich_text_renderer/text_renderers/underline_renderer.rb +12 -0
- data/lib/rich_text_renderer/version.rb +4 -0
- data/rich_text_renderer.gemspec +30 -0
- data/spec/lib/rich_text_renderer/block_renderers/base_block_renderer_spec.rb +26 -0
- data/spec/lib/rich_text_renderer/block_renderers/blockquote_renderer_spec.rb +25 -0
- data/spec/lib/rich_text_renderer/block_renderers/entry_block_renderer_spec.rb +15 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_five_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_four_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_one_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_six_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_three_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/heading_two_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/hr_renderer_spec.rb +13 -0
- data/spec/lib/rich_text_renderer/block_renderers/hyperlink_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/list_item_renderer_spec.rb +24 -0
- data/spec/lib/rich_text_renderer/block_renderers/ordered_list_renderer_spec.rb +56 -0
- data/spec/lib/rich_text_renderer/block_renderers/paragraph_renderer_spec.rb +30 -0
- data/spec/lib/rich_text_renderer/block_renderers/unordered_list_renderer_spec.rb +56 -0
- data/spec/lib/rich_text_renderer/document_renderers/document_renderer_spec.rb +42 -0
- data/spec/lib/rich_text_renderer/null_renderer_spec.rb +19 -0
- data/spec/lib/rich_text_renderer/renderer_spec.rb +308 -0
- data/spec/lib/rich_text_renderer/text_renderers/base_inline_renderer_spec.rb +11 -0
- data/spec/lib/rich_text_renderer/text_renderers/bold_renderer_spec.rb +11 -0
- data/spec/lib/rich_text_renderer/text_renderers/code_renderer_spec.rb +11 -0
- data/spec/lib/rich_text_renderer/text_renderers/italic_renderer_spec.rb +11 -0
- data/spec/lib/rich_text_renderer/text_renderers/text_renderer_spec.rb +53 -0
- data/spec/lib/rich_text_renderer/text_renderers/underline_renderer_spec.rb +11 -0
- data/spec/spec_helper.rb +82 -0
- metadata +387 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative './base_block_renderer'
|
2
|
+
|
3
|
+
module RichTextRenderer
|
4
|
+
# a node renderer.
|
5
|
+
class HyperlinkRenderer < BaseBlockRenderer
|
6
|
+
# Renders hyperlink
|
7
|
+
def render(node)
|
8
|
+
"<a href=\"#{node['data']['uri']}\">#{render_content(node)}</a>"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative './document_renderers/document_renderer'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../base_node_renderer'
|
2
|
+
|
3
|
+
module RichTextRenderer
|
4
|
+
# Document renderer.
|
5
|
+
class DocumentRenderer < BaseNodeRenderer
|
6
|
+
# Renders all nodes in the document.
|
7
|
+
def render(document)
|
8
|
+
document['content'].each_with_object([]) do |node, result|
|
9
|
+
result << find_renderer(node).render(node)
|
10
|
+
end.join("\n")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative './base_node_renderer'
|
2
|
+
|
3
|
+
module RichTextRenderer
|
4
|
+
# Catch-all renderer for missing node types
|
5
|
+
class NullRenderer < BaseNodeRenderer
|
6
|
+
# Will raise an exception indicating the missing node type.
|
7
|
+
def render(node)
|
8
|
+
fail "No renderer defined for '#{node_type(node)}' nodes"
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def node_type(node)
|
14
|
+
return node['nodeType'] if node.key?('nodeType')
|
15
|
+
return node['type'] if node.key?('type')
|
16
|
+
node
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative './text_renderers'
|
2
|
+
require_relative './block_renderers'
|
3
|
+
require_relative './document_renderers'
|
4
|
+
require_relative './base_node_renderer'
|
5
|
+
require_relative './null_renderer'
|
6
|
+
|
7
|
+
# RichTextRenderer Namespace
|
8
|
+
module RichTextRenderer
|
9
|
+
# Renderer for RichText field from Contentful
|
10
|
+
class Renderer < BaseNodeRenderer
|
11
|
+
# Default Renderers
|
12
|
+
DEFAULT_MAPPINGS = {
|
13
|
+
nil => NullRenderer,
|
14
|
+
'document' => DocumentRenderer,
|
15
|
+
'heading-1' => HeadingOneRenderer,
|
16
|
+
'heading-2' => HeadingTwoRenderer,
|
17
|
+
'heading-3' => HeadingThreeRenderer,
|
18
|
+
'heading-4' => HeadingFourRenderer,
|
19
|
+
'heading-5' => HeadingFiveRenderer,
|
20
|
+
'heading-6' => HeadingSixRenderer,
|
21
|
+
'blockquote' => BlockQuoteRenderer,
|
22
|
+
'hyperlink' => HyperlinkRenderer,
|
23
|
+
'paragraph' => ParagraphRenderer,
|
24
|
+
'list-item' => ListItemRenderer,
|
25
|
+
'ordered-list' => OrderedListRenderer,
|
26
|
+
'unordered-list' => UnorderedListRenderer,
|
27
|
+
'embedded-entry-block' => EntryBlockRenderer,
|
28
|
+
'hr' => HrRenderer,
|
29
|
+
'text' => TextRenderer,
|
30
|
+
'bold' => BoldRenderer,
|
31
|
+
'code' => CodeRenderer,
|
32
|
+
'italic' => ItalicRenderer,
|
33
|
+
'underline' => UnderlineRenderer
|
34
|
+
}
|
35
|
+
|
36
|
+
def initialize(mappings = {})
|
37
|
+
@mappings = DEFAULT_MAPPINGS.merge(mappings)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a rendered RichText document
|
41
|
+
def render(document)
|
42
|
+
renderer = find_renderer(document)
|
43
|
+
renderer.render(document) unless renderer.nil?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../base_node_renderer'
|
2
|
+
|
3
|
+
module RichTextRenderer
|
4
|
+
# Base renderer for inline nodes.
|
5
|
+
class BaseInlineRenderer < BaseNodeRenderer
|
6
|
+
# Renders inline nodes.
|
7
|
+
def render(node)
|
8
|
+
"<#{render_tag}>#{node['value']}</#{render_tag}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def render_tag
|
14
|
+
'span'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../base_node_renderer'
|
2
|
+
|
3
|
+
module RichTextRenderer
|
4
|
+
# Renderer for Text nodes.
|
5
|
+
class TextRenderer < BaseNodeRenderer
|
6
|
+
# Renders text nodes with all markings.
|
7
|
+
def render(node)
|
8
|
+
node = Marshal.load(Marshal.dump(node)) # Clone the node
|
9
|
+
|
10
|
+
node.fetch('marks', []).each do |mark|
|
11
|
+
renderer = mappings[mark['type']]
|
12
|
+
return mappings[nil].new(mappings).render(mark) if renderer.nil? && mappings.key?(nil)
|
13
|
+
node['value'] = renderer.new(mappings).render(node) unless renderer.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
node['value']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../lib/rich_text_renderer/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'rich_text_renderer'
|
5
|
+
gem.version = RichTextRenderer::VERSION
|
6
|
+
gem.summary = 'Rich Text Renderer for the Contentful RichText field type'
|
7
|
+
gem.description = 'Rich Text Renderer for the Contentful RichText field type'
|
8
|
+
gem.license = 'MIT'
|
9
|
+
gem.authors = ['Contentful GmbH (David Litvak Bruno)']
|
10
|
+
gem.email = 'rubygems@contentful.com'
|
11
|
+
gem.homepage = 'https://github.com/contentful/rich-text-renderer.rb'
|
12
|
+
|
13
|
+
gem.files = Dir['{**/}{.*,*}'].select { |path| File.file?(path) && !path.start_with?('pkg') }
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^spec/})
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
gem.add_development_dependency 'bundler', '~> 1.5'
|
19
|
+
gem.add_development_dependency 'rake', '< 11.0'
|
20
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'guard'
|
23
|
+
gem.add_development_dependency 'guard-rspec'
|
24
|
+
gem.add_development_dependency 'guard-rubocop'
|
25
|
+
gem.add_development_dependency 'guard-yard'
|
26
|
+
gem.add_development_dependency 'yard'
|
27
|
+
gem.add_development_dependency 'rubocop', '~> 0.49.1'
|
28
|
+
gem.add_development_dependency 'rspec', '~> 3'
|
29
|
+
gem.add_development_dependency 'simplecov'
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
mock_node = {"content" => [{"value" => "foo", "nodeType" => "text"}]}
|
4
|
+
|
5
|
+
mock_node_with_marks = {"content" => [{"value" => "foo", "nodeType" => "text", "marks" => [{"type" => "bold"}]}]}
|
6
|
+
|
7
|
+
describe RichTextRenderer::BaseBlockRenderer do
|
8
|
+
subject do
|
9
|
+
described_class.new(
|
10
|
+
'text' => RichTextRenderer::TextRenderer,
|
11
|
+
'bold' => RichTextRenderer::BoldRenderer,
|
12
|
+
'italic' => RichTextRenderer::ItalicRenderer,
|
13
|
+
'underline' => RichTextRenderer::UnderlineRenderer
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#render' do
|
18
|
+
it 'by defaults renders a div' do
|
19
|
+
expect(subject.render(mock_node)).to eq "<div>foo</div>"
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'will propagate marks to text renderers' do
|
23
|
+
expect(subject.render(mock_node_with_marks)).to eq "<div><b>foo</b></div>"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
mock_node = {"content" => [{"nodeType" => "paragraph", "content" => [{"value" => "foo", "nodeType" => "text"}]}]}
|
4
|
+
|
5
|
+
mock_node_with_marks = {"content" => [{"nodeType" => "paragraph", "content" => [{"value" => "foo", "nodeType" => "text", "marks" => [{"type" => "bold"}]}]}]}
|
6
|
+
|
7
|
+
describe RichTextRenderer::BlockQuoteRenderer do
|
8
|
+
subject do
|
9
|
+
described_class.new(
|
10
|
+
'paragraph' => RichTextRenderer::ParagraphRenderer,
|
11
|
+
'text' => RichTextRenderer::TextRenderer,
|
12
|
+
'bold' => RichTextRenderer::BoldRenderer
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#render' do
|
17
|
+
it 'renders a blockqoute' do
|
18
|
+
expect(subject.render(mock_node)).to eq "<blockqoute><p>foo</p></blockqoute>"
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'will propagate marks to text renderers' do
|
22
|
+
expect(subject.render(mock_node_with_marks)).to eq "<blockqoute><p><b>foo</b></p></blockqoute>"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
mock_data_node = {
|
4
|
+
"data" => {"target" => {"sys" => {"id" => "foo", "type" => "Link", "linkType" => "Entry"}}}
|
5
|
+
}
|
6
|
+
|
7
|
+
describe RichTextRenderer::EntryBlockRenderer do
|
8
|
+
subject { described_class.new }
|
9
|
+
|
10
|
+
describe '#render' do
|
11
|
+
it 'will stringify node data' do
|
12
|
+
expect(subject.render(mock_data_node)).to eq '<div>{"target"=>{"sys"=>{"id"=>"foo", "type"=>"Link", "linkType"=>"Entry"}}}</div>'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
mock_node = {"content" => [{"value" => "foo", "nodeType" => "text"}]}
|
4
|
+
|
5
|
+
mock_node_with_marks = {"content" => [{"value" => "foo", "nodeType" => "text", "marks" => [{"type" => "bold"}]}]}
|
6
|
+
|
7
|
+
describe RichTextRenderer::HeadingFiveRenderer do
|
8
|
+
subject do
|
9
|
+
described_class.new(
|
10
|
+
'text' => RichTextRenderer::TextRenderer,
|
11
|
+
'bold' => RichTextRenderer::BoldRenderer
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#render' do
|
16
|
+
it 'renders a h5' do
|
17
|
+
expect(subject.render(mock_node)).to eq "<h5>foo</h5>"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'will propagate marks to text renderers' do
|
21
|
+
expect(subject.render(mock_node_with_marks)).to eq "<h5><b>foo</b></h5>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
mock_node = {"content" => [{"value" => "foo", "nodeType" => "text"}]}
|
4
|
+
|
5
|
+
mock_node_with_marks = {"content" => [{"value" => "foo", "nodeType" => "text", "marks" => [{"type" => "bold"}]}]}
|
6
|
+
|
7
|
+
describe RichTextRenderer::HeadingFourRenderer do
|
8
|
+
subject do
|
9
|
+
described_class.new(
|
10
|
+
'text' => RichTextRenderer::TextRenderer,
|
11
|
+
'bold' => RichTextRenderer::BoldRenderer
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#render' do
|
16
|
+
it 'renders a h4' do
|
17
|
+
expect(subject.render(mock_node)).to eq "<h4>foo</h4>"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'will propagate marks to text renderers' do
|
21
|
+
expect(subject.render(mock_node_with_marks)).to eq "<h4><b>foo</b></h4>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|