rich_text_renderer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +27 -0
  5. data/.rubocop_todo.yml +35 -0
  6. data/.travis.yml +13 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +19 -0
  9. data/Gemfile +3 -0
  10. data/Guardfile +24 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +87 -0
  13. data/Rakefile +33 -0
  14. data/lib/rich_text_renderer.rb +2 -0
  15. data/lib/rich_text_renderer/base_node_renderer.rb +18 -0
  16. data/lib/rich_text_renderer/block_renderers.rb +18 -0
  17. data/lib/rich_text_renderer/block_renderers/base_block_renderer.rb +24 -0
  18. data/lib/rich_text_renderer/block_renderers/blockquote_renderer.rb +12 -0
  19. data/lib/rich_text_renderer/block_renderers/entry_block_renderer.rb +13 -0
  20. data/lib/rich_text_renderer/block_renderers/heading_five_renderer.rb +12 -0
  21. data/lib/rich_text_renderer/block_renderers/heading_four_renderer.rb +12 -0
  22. data/lib/rich_text_renderer/block_renderers/heading_one_renderer.rb +12 -0
  23. data/lib/rich_text_renderer/block_renderers/heading_six_renderer.rb +12 -0
  24. data/lib/rich_text_renderer/block_renderers/heading_three_renderer.rb +12 -0
  25. data/lib/rich_text_renderer/block_renderers/heading_two_renderer.rb +12 -0
  26. data/lib/rich_text_renderer/block_renderers/hr_renderer.rb +11 -0
  27. data/lib/rich_text_renderer/block_renderers/hyperlink_renderer.rb +11 -0
  28. data/lib/rich_text_renderer/block_renderers/list_item_renderer.rb +12 -0
  29. data/lib/rich_text_renderer/block_renderers/ordered_list_renderer.rb +12 -0
  30. data/lib/rich_text_renderer/block_renderers/paragraph_renderer.rb +12 -0
  31. data/lib/rich_text_renderer/block_renderers/unordered_list_renderer.rb +12 -0
  32. data/lib/rich_text_renderer/document_renderers.rb +1 -0
  33. data/lib/rich_text_renderer/document_renderers/document_renderer.rb +13 -0
  34. data/lib/rich_text_renderer/null_renderer.rb +19 -0
  35. data/lib/rich_text_renderer/renderer.rb +46 -0
  36. data/lib/rich_text_renderer/text_renderers.rb +5 -0
  37. data/lib/rich_text_renderer/text_renderers/base_inline_renderer.rb +17 -0
  38. data/lib/rich_text_renderer/text_renderers/bold_renderer.rb +12 -0
  39. data/lib/rich_text_renderer/text_renderers/code_renderer.rb +12 -0
  40. data/lib/rich_text_renderer/text_renderers/italic_renderer.rb +12 -0
  41. data/lib/rich_text_renderer/text_renderers/text_renderer.rb +19 -0
  42. data/lib/rich_text_renderer/text_renderers/underline_renderer.rb +12 -0
  43. data/lib/rich_text_renderer/version.rb +4 -0
  44. data/rich_text_renderer.gemspec +30 -0
  45. data/spec/lib/rich_text_renderer/block_renderers/base_block_renderer_spec.rb +26 -0
  46. data/spec/lib/rich_text_renderer/block_renderers/blockquote_renderer_spec.rb +25 -0
  47. data/spec/lib/rich_text_renderer/block_renderers/entry_block_renderer_spec.rb +15 -0
  48. data/spec/lib/rich_text_renderer/block_renderers/heading_five_renderer_spec.rb +24 -0
  49. data/spec/lib/rich_text_renderer/block_renderers/heading_four_renderer_spec.rb +24 -0
  50. data/spec/lib/rich_text_renderer/block_renderers/heading_one_renderer_spec.rb +24 -0
  51. data/spec/lib/rich_text_renderer/block_renderers/heading_six_renderer_spec.rb +24 -0
  52. data/spec/lib/rich_text_renderer/block_renderers/heading_three_renderer_spec.rb +24 -0
  53. data/spec/lib/rich_text_renderer/block_renderers/heading_two_renderer_spec.rb +24 -0
  54. data/spec/lib/rich_text_renderer/block_renderers/hr_renderer_spec.rb +13 -0
  55. data/spec/lib/rich_text_renderer/block_renderers/hyperlink_renderer_spec.rb +24 -0
  56. data/spec/lib/rich_text_renderer/block_renderers/list_item_renderer_spec.rb +24 -0
  57. data/spec/lib/rich_text_renderer/block_renderers/ordered_list_renderer_spec.rb +56 -0
  58. data/spec/lib/rich_text_renderer/block_renderers/paragraph_renderer_spec.rb +30 -0
  59. data/spec/lib/rich_text_renderer/block_renderers/unordered_list_renderer_spec.rb +56 -0
  60. data/spec/lib/rich_text_renderer/document_renderers/document_renderer_spec.rb +42 -0
  61. data/spec/lib/rich_text_renderer/null_renderer_spec.rb +19 -0
  62. data/spec/lib/rich_text_renderer/renderer_spec.rb +308 -0
  63. data/spec/lib/rich_text_renderer/text_renderers/base_inline_renderer_spec.rb +11 -0
  64. data/spec/lib/rich_text_renderer/text_renderers/bold_renderer_spec.rb +11 -0
  65. data/spec/lib/rich_text_renderer/text_renderers/code_renderer_spec.rb +11 -0
  66. data/spec/lib/rich_text_renderer/text_renderers/italic_renderer_spec.rb +11 -0
  67. data/spec/lib/rich_text_renderer/text_renderers/text_renderer_spec.rb +53 -0
  68. data/spec/lib/rich_text_renderer/text_renderers/underline_renderer_spec.rb +11 -0
  69. data/spec/spec_helper.rb +82 -0
  70. metadata +387 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a005b745298c66461e9f96c7066f47b0ae964e2102932242a09f0dfc3387e500
4
+ data.tar.gz: e1533944ead3ffa58ed274598721d99922dee574e3ddaaa54b4103cfd2f60901
5
+ SHA512:
6
+ metadata.gz: cc2063f0e0aadfab6aca31401f4c5912273c75aeb06d2a421f3e4b33ed143a49b7451af9ba3f515f683e507e93d6c50ba577590285252aa2551d8fb15b11618f
7
+ data.tar.gz: 8d3380163cb785d1ac0ac6141f599edebd629c32c5cfb274536b50cbbda988cfc2146f7dfd96bc6da3a8a6dc5861e1817b8057e5ac8d4042ba671ee78851a575
@@ -0,0 +1,7 @@
1
+ pkg
2
+ doc/
3
+ .yardoc/
4
+ coverage
5
+ Gemfile.lock
6
+ .idea
7
+ *.DS_Store
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
@@ -0,0 +1,27 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Encoding:
4
+ Enabled: false
5
+
6
+ Metrics/ClassLength:
7
+ CountComments: false
8
+
9
+ Metrics/MethodLength:
10
+ CountComments: false
11
+
12
+ AllCops:
13
+ Exclude:
14
+ - structured_text_renderer.gemspec
15
+ - spec/**/*
16
+ - Guardfile
17
+ - Gemfile
18
+ - Rakefile
19
+
20
+ Metrics/ClassLength:
21
+ Max: 250
22
+
23
+ Style/MutableConstant:
24
+ Enabled: false
25
+
26
+ Style/SignalException:
27
+ EnforcedStyle: 'semantic'
@@ -0,0 +1,35 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2016-02-02 13:30:13 -0300 using RuboCop version 0.36.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 6
10
+ Metrics/AbcSize:
11
+ Max: 38
12
+
13
+ # Offense count: 5
14
+ Metrics/CyclomaticComplexity:
15
+ Max: 8
16
+
17
+ # Offense count: 1
18
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
19
+ # URISchemes: http, https
20
+ Metrics/LineLength:
21
+ Max: 142
22
+
23
+ # Offense count: 12
24
+ # Configuration parameters: CountComments.
25
+ Metrics/MethodLength:
26
+ Max: 27
27
+
28
+ # Offense count: 2
29
+ # Configuration parameters: CountComments.
30
+ Metrics/ModuleLength:
31
+ Max: 499
32
+
33
+ # Offense count: 4
34
+ Metrics/PerceivedComplexity:
35
+ Max: 8
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ - 2.3.1
5
+ - 2.2.1
6
+ notifications:
7
+ slack:
8
+ secure: Zr3mKCiTb0vaTD4MPtTG8BbyYyErFuoxioM25QyrqePKVkDFeZC1MtGmg5klQQrJiWTKZPa/zB8NAHYkoUxg9I+z15JK0hYfz9KRubEpCrXCaqTC9Vzq88kJ3LN8YsTyBF66izaBH2KLsOfaJRxwplFzZqgpg4GG2DUBPtrGtes=
9
+ before_install: gem install bundler -v 1.10.6
10
+ script: bundle exec rake rspec_rubocop
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: jruby
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ -
3
+ CHANGELOG.md
4
+ LICENSE.txt
@@ -0,0 +1,19 @@
1
+ # CHANGELOG
2
+
3
+ ## Unreleased
4
+
5
+ ## v0.1.0 (`rich_text_renderer`)
6
+
7
+ As `RichText` moves from `alpha` to `beta`, we're treating this as a feature release.
8
+
9
+ ### Changed
10
+ * Renamed `StructuredText` to `RichText`.
11
+
12
+ ## v0.0.2 (`structured_text_renderer`)
13
+
14
+ ### Fixed
15
+ * Fixed rendering logic for block type nodes
16
+
17
+ ## v0.0.1
18
+
19
+ * Initial Release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,24 @@
1
+ group :green_red_refactor, halt_on_fail: true do
2
+ guard :rspec, cmd: "bundle exec rspec" do
3
+ require "guard/rspec/dsl"
4
+ dsl = Guard::RSpec::Dsl.new(self)
5
+
6
+ # Feel free to open issues for suggestions and improvements
7
+
8
+ # RSpec files
9
+ rspec = dsl.rspec
10
+ watch(rspec.spec_helper) { rspec.spec_dir }
11
+ watch(rspec.spec_support) { rspec.spec_dir }
12
+ watch(rspec.spec_files)
13
+
14
+ # Ruby files
15
+ ruby = dsl.ruby
16
+ dsl.watch_spec_files_for(ruby.lib_files)
17
+ end
18
+
19
+ guard :yard, cmd: "yard doc" do
20
+ end
21
+
22
+ guard :rubocop, cmd: "rubocop" do
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Contentful GmbH - David Litvak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ # Contentful Rich Text Renderer
2
+
3
+ [Contentful](https://www.contentful.com) provides a content infrastructure for digital teams to power content in websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship digital products faster.
4
+
5
+ This library provides rendering capabilities for the `RichText` field type. It is recommended to be used alongside the [Contentful Delivery SDK](https://www.github.com/contentful/contentful.rb).
6
+ By default this library will serialize `RichText` fields into it's corresponding HTML representation. All behaviour can be overridden to serialize to different formats.
7
+
8
+ ## Installation
9
+
10
+ Install Contentful Rich Text Renderer from RubyGems:
11
+
12
+ ```bash
13
+ gem install rich_text_renderer
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ Create a renderer:
19
+
20
+ ```ruby
21
+ require 'rich_text_renderer'
22
+
23
+ renderer = RichTextRenderer::Renderer.new
24
+ ```
25
+
26
+ Render your document:
27
+
28
+ ```ruby
29
+ renderer.render(document)
30
+ ```
31
+
32
+ ## Using different renderers
33
+
34
+ There are many cases in which HTML serialization is not what you want.
35
+ Therefore, all renderers are overridable when creating a `RichTextRenderer`.
36
+
37
+ Also, if you're planning to embed entries within your rich text, overriding the `'embedded-entry-block'` mapping is a must,
38
+ as by default it only does `<div>#{entry.to_s}</div>`.
39
+
40
+ You can override the configuration like follows:
41
+
42
+ ```ruby
43
+ renderer = RichTextRenderer::Renderer.new(
44
+ 'embedded-entry-block' => MyEntryBlockRenderer
45
+ )
46
+ ```
47
+
48
+ Where `MyEntryBlockRenderer` requires to have a `#render(node)` method and needs to return a string.
49
+
50
+ An example entry renderer, assuming our entry has 2 fields called `name` and `description` could be:
51
+
52
+ ```ruby
53
+ class MyEntryBlockRenderer < RichTextRenderer::BaseNodeRenderer
54
+ def render(node)
55
+ entry = node['data']
56
+
57
+ "<div class='my-entry'><h3>#{entry.name}</h3><p><small>#{entry.description}</p></small></div>"
58
+ end
59
+ end
60
+ ```
61
+
62
+ ## Dealing with unknown node types
63
+
64
+ By default, this gem will treat all unknown node types as errors and will raise an exception letting the user know which node mapping is missing.
65
+ If you wish to remove this behaviour then replace the `nil` key of the mapping with a NullRenderer that returns an empty string, or something similar.
66
+
67
+ An example would be like follows:
68
+
69
+ ```ruby
70
+ class SilentNullRenderer < RichTextRenderer::BaseNodeRenderer
71
+ def render(node)
72
+ ""
73
+ end
74
+ end
75
+
76
+ renderer = RichTextRenderer::Renderer.new(
77
+ nil => SilentNullRenderer
78
+ )
79
+ ```
80
+
81
+ ## License
82
+
83
+ Copyright (c) 2018 Contentful GmbH. See [LICENSE](./LICENSE) for further details.
84
+
85
+ ## Contributing
86
+
87
+ Feel free to improve this tool by submitting a Pull Request.
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'bundler'
5
+ rescue LoadError => e
6
+ warn e.message
7
+ warn 'Run `gem install bundler` to install Bundler.'
8
+ exit -1
9
+ end
10
+
11
+ begin
12
+ Bundler.setup(:development)
13
+ rescue Bundler::BundlerError => e
14
+ warn e.message
15
+ warn 'Run `bundle install` to install missing gems.'
16
+ exit e.status_code
17
+ end
18
+
19
+ require 'rake'
20
+
21
+ require 'rubygems/tasks'
22
+ Gem::Tasks.new
23
+
24
+ require 'rspec/core/rake_task'
25
+ RSpec::Core::RakeTask.new
26
+
27
+ require 'rubocop/rake_task'
28
+ RuboCop::RakeTask.new
29
+
30
+ task rspec_rubocop: %w(spec rubocop)
31
+
32
+ task test: :spec
33
+ task default: :spec
@@ -0,0 +1,2 @@
1
+ require_relative './rich_text_renderer/renderer'
2
+ require_relative './rich_text_renderer/version'
@@ -0,0 +1,18 @@
1
+ module RichTextRenderer
2
+ # Base class for all NodeRenderers
3
+ class BaseNodeRenderer
4
+ attr_reader :mappings
5
+
6
+ def initialize(mappings = {})
7
+ @mappings = mappings
8
+ end
9
+
10
+ protected
11
+
12
+ def find_renderer(node)
13
+ renderer = mappings[node['nodeType']]
14
+ return mappings[nil].new(mappings) if renderer.nil? && mappings.key?(nil)
15
+ renderer.new(mappings) unless renderer.nil?
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative './block_renderers/hr_renderer'
2
+
3
+ require_relative './block_renderers/paragraph_renderer'
4
+ require_relative './block_renderers/hyperlink_renderer'
5
+ require_relative './block_renderers/blockquote_renderer'
6
+
7
+ require_relative './block_renderers/entry_block_renderer'
8
+
9
+ require_relative './block_renderers/heading_one_renderer'
10
+ require_relative './block_renderers/heading_two_renderer'
11
+ require_relative './block_renderers/heading_six_renderer'
12
+ require_relative './block_renderers/heading_five_renderer'
13
+ require_relative './block_renderers/heading_four_renderer'
14
+ require_relative './block_renderers/heading_three_renderer'
15
+
16
+ require_relative './block_renderers/list_item_renderer'
17
+ require_relative './block_renderers/ordered_list_renderer'
18
+ require_relative './block_renderers/unordered_list_renderer'
@@ -0,0 +1,24 @@
1
+ require_relative '../base_node_renderer'
2
+
3
+ module RichTextRenderer
4
+ # Base renderer for block type nodes
5
+ class BaseBlockRenderer < BaseNodeRenderer
6
+ # Renders block type nodes.
7
+ def render(node)
8
+ "<#{render_tag}>#{render_content(node)}</#{render_tag}>"
9
+ end
10
+
11
+ protected
12
+
13
+ def render_content(node)
14
+ node['content'].each_with_object([]) do |content_node, result|
15
+ renderer = find_renderer(content_node)
16
+ result << renderer.render(content_node)
17
+ end.join
18
+ end
19
+
20
+ def render_tag
21
+ 'div'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './base_block_renderer'
2
+
3
+ module RichTextRenderer
4
+ # blockquote node renderer.
5
+ class BlockQuoteRenderer < BaseBlockRenderer
6
+ protected
7
+
8
+ def render_tag
9
+ 'blockqoute'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require_relative '../base_node_renderer'
2
+
3
+ module RichTextRenderer
4
+ # Default embedded entry renderer.
5
+ # Dumps entry to string.
6
+ # This renderer should be overridden for your particular applications.
7
+ class EntryBlockRenderer < BaseNodeRenderer
8
+ # Renders embedded entry node.
9
+ def render(node)
10
+ "<div>#{node['data']}</div>"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './base_block_renderer'
2
+
3
+ module RichTextRenderer
4
+ # H5 node renderer.
5
+ class HeadingFiveRenderer < BaseBlockRenderer
6
+ protected
7
+
8
+ def render_tag
9
+ 'h5'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './base_block_renderer'
2
+
3
+ module RichTextRenderer
4
+ # H4 node renderer.
5
+ class HeadingFourRenderer < BaseBlockRenderer
6
+ protected
7
+
8
+ def render_tag
9
+ 'h4'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './base_block_renderer'
2
+
3
+ module RichTextRenderer
4
+ # H1 node renderer.
5
+ class HeadingOneRenderer < BaseBlockRenderer
6
+ protected
7
+
8
+ def render_tag
9
+ 'h1'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './base_block_renderer'
2
+
3
+ module RichTextRenderer
4
+ # H6 node renderer.
5
+ class HeadingSixRenderer < BaseBlockRenderer
6
+ protected
7
+
8
+ def render_tag
9
+ 'h6'
10
+ end
11
+ end
12
+ end