dato_dast 0.0.1

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.projections.json +4 -0
  4. data/.rspec +3 -0
  5. data/CHANGELOG.md +6 -0
  6. data/CODE_OF_CONDUCT.md +128 -0
  7. data/Gemfile +7 -0
  8. data/Gemfile.lock +58 -0
  9. data/README.md +1082 -0
  10. data/Rakefile +8 -0
  11. data/TODO.md +0 -0
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/dato_dast.gemspec +29 -0
  15. data/lib/dato_dast/configuration.rb +121 -0
  16. data/lib/dato_dast/errors/block_field_missing.rb +15 -0
  17. data/lib/dato_dast/errors/block_node_missing_render_function.rb +15 -0
  18. data/lib/dato_dast/errors/invalid_block_structure_type.rb +6 -0
  19. data/lib/dato_dast/errors/invalid_blocks_configuration.rb +18 -0
  20. data/lib/dato_dast/errors/invalid_marks_configuration.rb +15 -0
  21. data/lib/dato_dast/errors/invalid_nodes.rb +15 -0
  22. data/lib/dato_dast/errors/invalid_types_configuration.rb +15 -0
  23. data/lib/dato_dast/errors/missing_render_value_function.rb +15 -0
  24. data/lib/dato_dast/errors.rb +8 -0
  25. data/lib/dato_dast/extensions/middleman.rb +35 -0
  26. data/lib/dato_dast/html_tag.rb +74 -0
  27. data/lib/dato_dast/marks.rb +12 -0
  28. data/lib/dato_dast/nodes/attributed_quote.rb +20 -0
  29. data/lib/dato_dast/nodes/base.rb +113 -0
  30. data/lib/dato_dast/nodes/block.rb +124 -0
  31. data/lib/dato_dast/nodes/blockquote.rb +6 -0
  32. data/lib/dato_dast/nodes/code.rb +35 -0
  33. data/lib/dato_dast/nodes/generic.rb +21 -0
  34. data/lib/dato_dast/nodes/heading.rb +14 -0
  35. data/lib/dato_dast/nodes/inline_item.rb +14 -0
  36. data/lib/dato_dast/nodes/item_link.rb +29 -0
  37. data/lib/dato_dast/nodes/link.rb +57 -0
  38. data/lib/dato_dast/nodes/list.rb +9 -0
  39. data/lib/dato_dast/nodes/list_item.rb +6 -0
  40. data/lib/dato_dast/nodes/paragraph.rb +6 -0
  41. data/lib/dato_dast/nodes/root.rb +6 -0
  42. data/lib/dato_dast/nodes/span.rb +21 -0
  43. data/lib/dato_dast/nodes/thematic_break.rb +9 -0
  44. data/lib/dato_dast/nodes.rb +29 -0
  45. data/lib/dato_dast/version.rb +5 -0
  46. data/lib/dato_dast.rb +39 -0
  47. metadata +119 -0
@@ -0,0 +1,124 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Block < Base
4
+ def block_id
5
+ @node["item"]
6
+ end
7
+
8
+ def block
9
+ return @block if @block
10
+
11
+ @block ||= @blocks.find { |block| block[:id] == block_id }
12
+ end
13
+
14
+ def item_type
15
+ block[:item_type]
16
+ end
17
+
18
+ def node
19
+ node_config["node"]
20
+ end
21
+
22
+ def node_config
23
+ config.blocks[item_type]
24
+ end
25
+
26
+ def children
27
+ Array.wrap(structure).map do |child|
28
+ case child["type"]
29
+ when "field"
30
+ build_field(child)
31
+ when "value"
32
+ build_value(child)
33
+ when "block"
34
+ build_block(block[child["field"].to_sym])
35
+ when "blocks"
36
+ build_blocks(child)
37
+ else
38
+ raise Errors::InvalidBlockStructureType
39
+ end.merge(extract_tags(child)).compact
40
+ end.flatten
41
+ end
42
+
43
+ def render_value
44
+ if node_config["render_value"]
45
+ node_config["render_value"].call(block)
46
+ else
47
+ render_children
48
+ end
49
+ end
50
+
51
+ def render
52
+ return super unless node
53
+
54
+ begin
55
+ node.new(block).render
56
+ rescue NoMethodError => _e
57
+ raise Errors::BlockNodeMissingRenderFunction.new(["block->#{item_type}"])
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def structure
64
+ node_config["structure"]
65
+ end
66
+
67
+ def extract_tags(child)
68
+ {
69
+ "tag" => child["tag"],
70
+ "css_class" => child["css_class"],
71
+ "meta" => child["meta"],
72
+ "wrappers" => child["wrappers"],
73
+ }.compact
74
+ end
75
+
76
+ def build_field(child)
77
+ raise Errors::BlockFieldMissing.new(item_type) unless child["field"]
78
+
79
+ field = child["field"].to_sym
80
+ value = block[field]
81
+
82
+ {
83
+ "type" => "span",
84
+ "value" => value,
85
+ "marks" => Array.wrap(child["marks"]),
86
+ }
87
+ end
88
+
89
+ def build_value(child)
90
+ raise Errors::MissingRenderValueFunction.new(item_type) unless child["render_value"]
91
+
92
+ value = child["render_value"].call(block)
93
+
94
+ {
95
+ "type" => "span",
96
+ "value" => value,
97
+ "marks" => Array.wrap(child["marks"]),
98
+ }
99
+ end
100
+
101
+ def build_block(child)
102
+ @blocks << child
103
+
104
+ {
105
+ "type" => "block",
106
+ "item" => child[:id],
107
+ }
108
+ end
109
+
110
+ def build_blocks(child)
111
+ field = child["field"].to_sym
112
+
113
+ parent = {
114
+ "type" => "generic",
115
+ "children" => Array.wrap(block[field]).map { |child_block| build_block(child_block) }
116
+ }
117
+ end
118
+
119
+ def proc_object
120
+ block
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,6 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Blockquote < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,35 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Code < Base
4
+ def language
5
+ @node["language"]
6
+ end
7
+
8
+ def code
9
+ @node["code"]
10
+ end
11
+
12
+ def render
13
+ if highlighter?
14
+ highlight
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def render_value
21
+ code.gsub(/\n/, "<br/>")
22
+ end
23
+
24
+ private
25
+
26
+ def highlighter?
27
+ config.highlight && defined?(::Middleman::Syntax::SyntaxExtension)
28
+ end
29
+
30
+ def highlight
31
+ Middleman::Syntax::Highlighter.highlight(code, language, {}).html_safe
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Generic < Base
4
+ def tag
5
+ @node["tag"]
6
+ end
7
+
8
+ def css_class
9
+ @node["css_class"]
10
+ end
11
+
12
+ def wrappers
13
+ Array.wrap(@node["wrappers"])
14
+ end
15
+
16
+ def meta
17
+ @node["meta"]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Heading < Base
4
+ def level
5
+ @node["level"]
6
+ end
7
+
8
+ # def tag
9
+ # base_tag = super
10
+ # base_tag.gsub(/#/, level.to_s)
11
+ # end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # An inlineItem, similarly to itemLink, links the document to another record but does not specify any inner content (children).
2
+ #
3
+ # It can be used in situations where it is up to the frontend to decide how to present the record (ie. a widget, or an <a> tag pointing to the URL of the record with a text that is the title of the linked record).
4
+ #
5
+ # It does not allow children nodes.
6
+ #
7
+ # type "inlineItem" Required
8
+ # item string Required
9
+ # The DatoCMS record ID
10
+ #
11
+ # {
12
+ # "type": "inlineItem",
13
+ # "item": "74619345"
14
+ # }
@@ -0,0 +1,29 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class ItemLink < Link
4
+ def item_id
5
+ @node["item"]
6
+ end
7
+
8
+ def item
9
+ @links.find { |link| link[:id] == item_id }
10
+ end
11
+
12
+ def url
13
+ item[url_key]
14
+ end
15
+
16
+ def item_type
17
+ item[:item_type]
18
+ end
19
+
20
+ private
21
+
22
+ def url_key
23
+ # TODO if the url key does not exist
24
+
25
+ config.item_links[item_type]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,57 @@
1
+ require "uri"
2
+
3
+ module DatoDast
4
+ module Nodes
5
+ class Link < Base
6
+ NEW_WINDOW_META = [
7
+ { "id" => "rel", "value" => "nofollow" },
8
+ { "id" => "target", "value" => "_blank" },
9
+ ].freeze
10
+
11
+ def url
12
+ node_url = @node["url"]
13
+
14
+ if node_url =~ URI::MailTo::EMAIL_REGEXP
15
+ "mailto:#{node_url}"
16
+ else
17
+ node_url
18
+ end
19
+ end
20
+
21
+ def meta
22
+ fields = @node["meta"].dup || []
23
+ fields.prepend({ "id" => "href", "value" => path })
24
+
25
+ new_window? ? (fields + NEW_WINDOW_META).uniq : fields
26
+ end
27
+
28
+ def path
29
+ local_url || uri.to_s
30
+ end
31
+
32
+ private
33
+
34
+ def uri
35
+ @uri ||= URI(url)
36
+ end
37
+
38
+ def smart_links?
39
+ config.smart_links
40
+ end
41
+
42
+ def new_window?
43
+ smart_links? && !local_url
44
+ end
45
+
46
+ def local_url
47
+ return @local_url if defined?(@local_url)
48
+
49
+ @local_url = if uri.host.nil? && !uri.is_a?(URI::MailTo)
50
+ "/#{uri.to_s}"
51
+ elsif smart_links? && uri.host == config.host
52
+ uri.path
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,9 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class List < Base
4
+ def style
5
+ @node["style"]
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class ListItem < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Paragraph < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Root < Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class Span < Base
4
+ def marks
5
+ @node["marks"] || []
6
+ end
7
+
8
+ def value
9
+ @node["value"].gsub(/\n/, "<br/>")
10
+ end
11
+
12
+ def wrappers
13
+ Array.wrap(super) + marks.map { |mark| config.marks[mark] }
14
+ end
15
+
16
+ def render_value
17
+ value
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module DatoDast
2
+ module Nodes
3
+ class ThematicBreak < Base
4
+ def render
5
+ "<#{tag}/>\n"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ require "dato_dast/nodes/base"
2
+ require "dato_dast/nodes/span"
3
+ require "dato_dast/nodes/generic"
4
+ require "dato_dast/nodes/block"
5
+ require "dato_dast/nodes/attributed_quote"
6
+ require "dato_dast/nodes/blockquote"
7
+ require "dato_dast/nodes/code"
8
+ require "dato_dast/nodes/heading"
9
+ require "dato_dast/nodes/inline_item"
10
+ require "dato_dast/nodes/link"
11
+ require "dato_dast/nodes/item_link"
12
+ require "dato_dast/nodes/list"
13
+ require "dato_dast/nodes/list_item"
14
+ require "dato_dast/nodes/paragraph"
15
+ require "dato_dast/nodes/root"
16
+ require "dato_dast/nodes/thematic_break"
17
+ require "dato_dast/nodes/block"
18
+
19
+
20
+ module DatoDast
21
+ module Nodes
22
+ def self.wrap(value, links = [], blocks = [], config = nil)
23
+ type = value["type"]
24
+ configuration = config || DatoDast.configuration
25
+ node_class = value["node"] || configuration.types[type]["node"]
26
+ node_class.new(value, links, blocks, config)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DatoDast
4
+ VERSION = "0.0.1"
5
+ end
data/lib/dato_dast.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array"
4
+ require "active_support/core_ext/string"
5
+ require "active_support/core_ext/object"
6
+ require "active_support/concern"
7
+ require_relative "dato_dast/version"
8
+ require_relative "dato_dast/html_tag"
9
+ require_relative "dato_dast/errors"
10
+ require_relative "dato_dast/marks"
11
+ require_relative "dato_dast/nodes"
12
+ require_relative "dato_dast/configuration"
13
+
14
+ module DatoDast
15
+ def self.configuration
16
+ @configuration ||= DatoDast::Configuration.new
17
+ end
18
+
19
+ def self.configure
20
+ yield configuration
21
+ end
22
+
23
+ def self.reset_configuration
24
+ @configuration = DatoDast::Configuration.new
25
+ end
26
+
27
+ def self.structured_text(item, config = nil)
28
+ object = item.to_hash
29
+ document = object[:value]["document"]
30
+ links = object[:links]
31
+ blocks = object[:blocks]
32
+
33
+ Nodes.wrap(document, links, blocks, config).render
34
+ end
35
+ end
36
+
37
+ if defined?(Middleman)
38
+ require "dato_dast/extensions/middleman"
39
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dato_dast
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - John DeWyze
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry-byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: This gem provides a way to convert DatoCMS structured text to Html, as
42
+ well as an extension for Middleman.
43
+ email:
44
+ - john@dewyze.dev
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".projections.json"
51
+ - ".rspec"
52
+ - CHANGELOG.md
53
+ - CODE_OF_CONDUCT.md
54
+ - Gemfile
55
+ - Gemfile.lock
56
+ - README.md
57
+ - Rakefile
58
+ - TODO.md
59
+ - bin/console
60
+ - bin/setup
61
+ - dato_dast.gemspec
62
+ - lib/dato_dast.rb
63
+ - lib/dato_dast/configuration.rb
64
+ - lib/dato_dast/errors.rb
65
+ - lib/dato_dast/errors/block_field_missing.rb
66
+ - lib/dato_dast/errors/block_node_missing_render_function.rb
67
+ - lib/dato_dast/errors/invalid_block_structure_type.rb
68
+ - lib/dato_dast/errors/invalid_blocks_configuration.rb
69
+ - lib/dato_dast/errors/invalid_marks_configuration.rb
70
+ - lib/dato_dast/errors/invalid_nodes.rb
71
+ - lib/dato_dast/errors/invalid_types_configuration.rb
72
+ - lib/dato_dast/errors/missing_render_value_function.rb
73
+ - lib/dato_dast/extensions/middleman.rb
74
+ - lib/dato_dast/html_tag.rb
75
+ - lib/dato_dast/marks.rb
76
+ - lib/dato_dast/nodes.rb
77
+ - lib/dato_dast/nodes/attributed_quote.rb
78
+ - lib/dato_dast/nodes/base.rb
79
+ - lib/dato_dast/nodes/block.rb
80
+ - lib/dato_dast/nodes/blockquote.rb
81
+ - lib/dato_dast/nodes/code.rb
82
+ - lib/dato_dast/nodes/generic.rb
83
+ - lib/dato_dast/nodes/heading.rb
84
+ - lib/dato_dast/nodes/inline_item.rb
85
+ - lib/dato_dast/nodes/item_link.rb
86
+ - lib/dato_dast/nodes/link.rb
87
+ - lib/dato_dast/nodes/list.rb
88
+ - lib/dato_dast/nodes/list_item.rb
89
+ - lib/dato_dast/nodes/paragraph.rb
90
+ - lib/dato_dast/nodes/root.rb
91
+ - lib/dato_dast/nodes/span.rb
92
+ - lib/dato_dast/nodes/thematic_break.rb
93
+ - lib/dato_dast/version.rb
94
+ homepage: https://github.com/dewyze/dato_dast
95
+ licenses: []
96
+ metadata:
97
+ homepage_uri: https://github.com/dewyze/dato_dast
98
+ source_code_uri: https://github.com/dewyze/dato_dast
99
+ changelog_uri: https://github.com/dewyze/dato_dast/blob/main/CHANGELOG.md.
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.4.0
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.2.15
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Gem for converting DatoCMS Structured Text to Html
119
+ test_files: []