belletrist 1.0.3 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d59cf0de5fc3b77ee612b1bec7fc8a41db26bf7475e1f4943967871f41f024d
4
- data.tar.gz: 62755a4c1c86779d64f29857cfce47fecb3740562ce53105cb35b6666cfaabd5
3
+ metadata.gz: 7a59242bc76875cc57af10fc601d9f873eaeb3b5423f84a7f7d52b28360434db
4
+ data.tar.gz: 4c4ddb3a7ba0e25b0b354ce4fc753a5523b9e5b02b8621b72f6a04e23e00103f
5
5
  SHA512:
6
- metadata.gz: a7a9d2b6c69834b2054f364271abff3362ccf37fbdcc789c482c6d2243225cf041cbc388b4bf9f7185501be7a12848152fdb15840dc8254faa1239c1833cc0a3
7
- data.tar.gz: 2918a2a44daa4495d1955378e6d8962d312d635fb99ba600a7a81480525b1a9340b08f9ac59768c2a89df310477525562ed49d2c5f6de5a0a361473b5d3d618e
6
+ metadata.gz: 933f94556b186d146d75ec205be968ab2928bf8be727a1d162f2e1de8585cb027ee6b626ee12b499644e33015d7a11152ac7948c1ee50007a93f90e44d73bc62
7
+ data.tar.gz: d642df58fde3590cfdbfc6985cbfb320c34eafff083a5d40483668e7c402af684a5b5b24d876de48d711665ef18c3ae4a75c273313f980fa61e1b235f2d6965d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
  This file contains general, high level explanations of the differences between versions. Please check the commmit
3
3
  history for further details.
4
4
 
5
+ ## 1.1.0
6
+ * Added JSON DSL. Supports the same `with` mechanism as the HTML DSL, and generally functions similarly.
7
+ * Rewrote `HTML::Element` to inherit directly from `Belletrist::BaseCollector`.
8
+ * This change allows subclassing `HTML::Element` for components to be much more ergonomic. See: README.
9
+
5
10
  ## 1.0.3
6
11
  * Actually added the LICENSE file to the gem.
7
12
 
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Belletrist
2
- Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML is supported, but
3
- that will grow as my needs do, or if other people want or contribute any other DSLs, which would be pretty cool I think.
2
+ Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML and JSON are
3
+ supported but that will grow as my needs do, or if other people want or contribute any other DSLs.
4
4
 
5
- Important to note is that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule of
6
- "what goes in, must come out". Belletrist DSLs must output well-formed documents so long as the developer provides
7
- Belletrist valid input, if that contract is broken the result is undefined.
5
+ It is important to note that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule
6
+ of "what goes in, must come out", and as such Belletrist DSLs must output well-formed documents so long as the developer
7
+ provides Belletrist valid input. If that contract is broken the result is undefined.
8
8
 
9
9
  ## Requirements of a Belletrist DSL
10
10
  * All input must be sanitized, and sanitization is not optional.
@@ -14,11 +14,15 @@ Belletrist valid input, if that contract is broken the result is undefined.
14
14
  Below are some examples of how you can use the different DSLs provided by Belletrist.
15
15
 
16
16
  ### HTML
17
+ Generation of a simple HTML document:
17
18
  ```ruby
18
19
  require 'belletrist'
19
20
 
20
21
  da_rulez = ['Be hip!', 'Be cool!', 'Don\'t be square!']
21
22
 
23
+ # HTML5 is the default DOCTYPE.
24
+ # HTML5 DOCTYPE: Belletrist::HTML::Document.new(Belletrist::HTML::V5)
25
+ # HTML4 DOCTYPE: Belletrist::HTML::Document.new(Belletrist::HTML::V4)
22
26
  document = Belletrist::HTML::Document.new
23
27
  document.head do
24
28
  title 'Some Kind of Web Page'
@@ -34,4 +38,64 @@ end
34
38
 
35
39
  # String conversation is serialization of the input.
36
40
  print document.to_s
41
+ ```
42
+ Subclassing `Belletrist::HTML:Element` to create components:
43
+ ```ruby
44
+ require 'belletrist'
45
+
46
+ class SubElement < Belletrist::HTML::Element
47
+ def initialize
48
+ super('div')
49
+ end
50
+
51
+ def component
52
+ p 'I am rendered from a custom component!'
53
+ end
54
+ end
55
+
56
+ document = Belletrist::HTML::Document.new
57
+ document.body do
58
+ h1 'Look at my cool new element!'
59
+ with SubElement.new
60
+ end
61
+ ```
62
+
63
+ ### JSON
64
+ Using the DSL directly:
65
+ ```ruby
66
+ require 'belletrist'
67
+
68
+ dict = {a_string: 'Hello, world!', a_number: 1}
69
+ list = [1, 1, 2, 3, 5, 8]
70
+
71
+ obj = Belletrist::JSON::Object.new
72
+ obj.title 'An example JSON object'
73
+ obj.empty nil
74
+
75
+ obj.sub do
76
+ object_key dict
77
+ array_key list
78
+ end
79
+
80
+ obj.double_fib.map list do |item|
81
+ push item * 2
82
+ end
83
+ ```
84
+ Sending a Hash to a new JSON object:
85
+ ```ruby
86
+ require 'belletrist'
87
+
88
+ fib = [1, 1, 2, 3, 5, 8]
89
+
90
+ dict = {
91
+ title: 'An example JSON object',
92
+ empty: nil,
93
+ sub: {
94
+ object_key: {a_string: 'Hello, world!', a_number: 1},
95
+ array_key: fib
96
+ },
97
+ double_map: fib.map { |item| item * item }
98
+ }
99
+
100
+ obj = Belletrist::JSON::Object.new(dict)
37
101
  ```
data/belletrist.gemspec CHANGED
@@ -6,13 +6,12 @@ Gem::Specification.new do |s|
6
6
  s.licenses = ['MIT']
7
7
  s.summary = 'A collection of Ruby DSLs for data file generation.'
8
8
  s.description = <<-EOF
9
- Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML is supported, but
10
- that will grow as my needs do, or if other people want or contribute any other DSLs, which would be pretty cool I think.
11
-
12
- Important to note is that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule of
13
- "what goes in, must come out". Belletrist DSLs must output well-formed documents so long as the developer provides
14
- Belletrist valid input, if that contract is broken the result is undefined.
15
- EOF
9
+ Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML and JSON are
10
+ supported but that will grow as my needs do, or if other people want or contribute any other DSLs. It is important to
11
+ note that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule of "what goes in,
12
+ must come out", and as such Belletrist DSLs must output well-formed documents so long as the developer provides
13
+ Belletrist valid input. If that contract is broken the result is undefined.
14
+ EOF
16
15
  s.authors = ['Juniper']
17
16
  s.email = 'me@junisoft.org'
18
17
  s.files = Dir['lib/**/*.rb'] + %w[README.md CHANGELOG.md belletrist.gemspec LICENSE]
@@ -26,7 +26,7 @@ module Belletrist
26
26
 
27
27
  def with(ele, &block)
28
28
  @elements.push ele
29
- ele.children.instance_eval(&block) if block
29
+ ele.instance_eval(&block) if block
30
30
  ele
31
31
  end
32
32
 
@@ -39,5 +39,9 @@ module Belletrist
39
39
  def responds_to?(method)
40
40
  true
41
41
  end
42
+
43
+ def inspect
44
+ to_s
45
+ end
42
46
  end
43
47
  end
@@ -3,19 +3,7 @@
3
3
  require_relative './abstract'
4
4
 
5
5
  module Belletrist::HTML
6
- class Base
7
- attr_reader :children
8
-
9
- def initialize
10
- @children = Collector.new
11
- end
12
-
13
- def inspect
14
- self.to_s
15
- end
16
- end
17
-
18
- class Element < Base
6
+ class Element < Belletrist::BaseCollector
19
7
  ESCAPE_HTML = {
20
8
  "&" => "&amp;",
21
9
  "<" => "&lt;",
@@ -29,7 +17,7 @@ module Belletrist::HTML
29
17
  attr_accessor :text
30
18
  attr_reader :name
31
19
 
32
- def initialize(name, args)
20
+ def initialize(name, args=[])
33
21
  super()
34
22
  @name = name.to_s
35
23
  @attr = []
@@ -43,10 +31,14 @@ module Belletrist::HTML
43
31
  end
44
32
  end
45
33
 
46
- component(@children)
34
+ component
35
+ end
36
+
37
+ def component
47
38
  end
48
39
 
49
- def component(c)
40
+ def new_element(name, args)
41
+ Element.new(name, args)
50
42
  end
51
43
 
52
44
  private def import_attribute(hash)
@@ -68,24 +60,21 @@ module Belletrist::HTML
68
60
  text.gsub(ESCAPE_HTML_PATTERN, ESCAPE_HTML)
69
61
  end
70
62
 
71
- def map(arr, &block)
72
- arr.each do |item|
73
- @children.instance_exec item, &block
74
- end
75
- end
76
-
77
63
  def to_s
78
64
  spacer = ''
79
65
  spacer = ' ' if @attr.length > 0
80
- "<#{s_key(@name)}#{spacer}#{@attr.join(' ')}>#{s_txt(@text)}#{@children}</#{s_key(@name)}>"
66
+ "<#{s_key(@name)}#{spacer}#{@attr.join(' ')}>#{s_txt(@text)}#{@elements.map { |e| e.to_s }.join('')}</#{s_key(@name)}>"
81
67
  end
82
68
  end
83
69
 
84
- class Document < Base
85
- def initialize(spec=V5)
70
+ class Document
71
+ def initialize(spec=V5, lang=nil)
86
72
  super()
87
- @head = Collector.new
88
- @body = Collector.new
73
+ body_args = []
74
+ body_args.push lang if lang
75
+
76
+ @head = Element.new 'head'
77
+ @body = Element.new 'body', body_args
89
78
  @spec = spec
90
79
  end
91
80
 
@@ -100,13 +89,7 @@ module Belletrist::HTML
100
89
  end
101
90
 
102
91
  def to_s
103
- "#{@spec}<html><head>#{@head}</head><body>#{@body}</body></html>"
104
- end
105
- end
106
-
107
- class Collector < Belletrist::BaseCollector
108
- def new_element(name, args)
109
- Element.new(name, args)
92
+ "#{@spec}<html>#{@head}#{@body}</html>"
110
93
  end
111
94
  end
112
95
 
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './abstract'
4
+
5
+ module Belletrist::JSON
6
+ def self.to_value(v)
7
+ if v.nil?
8
+ 'null'
9
+ elsif v.is_a?(String)
10
+ "\"#{v.gsub(/"/, '\"')}\""
11
+ else
12
+ v.to_s
13
+ end
14
+ end
15
+
16
+ class Object < Belletrist::BaseCollector
17
+ class Entry
18
+ attr_reader :key, :value
19
+
20
+ def initialize(key, value)
21
+ super()
22
+
23
+ @key = key.to_s
24
+ @value = value
25
+ end
26
+
27
+ def map(values, &block)
28
+ if @value.is_a?(Object) and @value.length == 0
29
+ @value = List.new
30
+ end
31
+
32
+ if @value.is_a?(List)
33
+ @value.map values, &block
34
+ end
35
+ end
36
+
37
+ private def method_missing(symbol, *args, &block)
38
+ @value.send(symbol, *args, &block)
39
+ end
40
+ end
41
+
42
+ def initialize(dict={})
43
+ super()
44
+ dict.each do |entry|
45
+ key, val = entry
46
+ unless key.is_a?(Symbol)
47
+ key = key.to_sym
48
+ end
49
+
50
+ self.send(key, val)
51
+ end if dict
52
+ end
53
+
54
+ private def new_element(ele, args)
55
+ args = {} if args.length == 0
56
+ args = args.pop if args.length == 1
57
+
58
+ if args.is_a?(Hash)
59
+ args = Object.new(args)
60
+ elsif args.is_a?(Array)
61
+ args = List.new(args)
62
+ end
63
+
64
+ Entry.new(ele, args)
65
+ end
66
+
67
+ def length
68
+ @elements.length
69
+ end
70
+
71
+ def to_s
72
+ value = '{'
73
+ @elements.each_index do |i|
74
+ item = @elements[i]
75
+ value += "\"#{item.key}\":#{JSON.to_value(item.value)}"
76
+ value += ',' unless i + 1 == @elements.length
77
+ end
78
+ value + '}'
79
+ end
80
+ end
81
+
82
+ class List
83
+ attr_reader :elements
84
+
85
+ def initialize(arr=[])
86
+ super()
87
+ @elements = Array.new
88
+
89
+ arr.each do |item|
90
+ self.push item
91
+ end if arr
92
+ end
93
+
94
+ def push(value)
95
+ @elements.push(correct_type(value))
96
+ end
97
+
98
+ def unshift(value)
99
+ @elements.unshift(correct_type(value))
100
+ end
101
+
102
+ def map(values, &block)
103
+ values.each do |item|
104
+ self.instance_exec item, &block
105
+ end
106
+ end
107
+
108
+ private def correct_type(value)
109
+ if value.is_a?(Hash)
110
+ Object.new(value)
111
+ elsif value.is_a?(Array)
112
+ List.new(value)
113
+ else
114
+ value
115
+ end
116
+ end
117
+
118
+ def to_s
119
+ value = '['
120
+ @elements.each_index do |i|
121
+ item = @elements[i]
122
+ value += JSON.to_value(item)
123
+ value += ',' unless i + 1 == @elements.length
124
+ end
125
+ value + ']'
126
+ end
127
+
128
+ def inspect
129
+ to_s
130
+ end
131
+ end
132
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Belletrist
4
- VERSION = '1.0.3'
4
+ VERSION = '1.1.0'
5
5
  end
data/lib/belletrist.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'belletrist/version'
4
4
  require_relative 'belletrist/html'
5
+ require_relative 'belletrist/json'
5
6
 
6
7
  module Belletrist
7
8
  end
metadata CHANGED
@@ -1,22 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: belletrist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juniper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-17 00:00:00.000000000 Z
11
+ date: 2023-12-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
- Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML is supported, but
15
- that will grow as my needs do, or if other people want or contribute any other DSLs, which would be pretty cool I think.
16
-
17
- Important to note is that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule of
18
- "what goes in, must come out". Belletrist DSLs must output well-formed documents so long as the developer provides
19
- Belletrist valid input, if that contract is broken the result is undefined.
14
+ Belletrist is a collection of Ruby DSLs for generation of different data file types. Currently, HTML and JSON are
15
+ supported but that will grow as my needs do, or if other people want or contribute any other DSLs. It is important to
16
+ note that Belletrist has a focus on performance, not correctness. Belletrist ascribes to the rule of "what goes in,
17
+ must come out", and as such Belletrist DSLs must output well-formed documents so long as the developer provides
18
+ Belletrist valid input. If that contract is broken the result is undefined.
20
19
  email: me@junisoft.org
21
20
  executables: []
22
21
  extensions: []
@@ -29,6 +28,7 @@ files:
29
28
  - lib/belletrist.rb
30
29
  - lib/belletrist/abstract.rb
31
30
  - lib/belletrist/html.rb
31
+ - lib/belletrist/json.rb
32
32
  - lib/belletrist/version.rb
33
33
  homepage: https://codeberg.org/juniper/Belletrist
34
34
  licenses: