rich_text_renderer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|