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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +69 -5
- data/belletrist.gemspec +6 -7
- data/lib/belletrist/abstract.rb +5 -1
- data/lib/belletrist/html.rb +17 -34
- data/lib/belletrist/json.rb +132 -0
- data/lib/belletrist/version.rb +1 -1
- data/lib/belletrist.rb +1 -0
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a59242bc76875cc57af10fc601d9f873eaeb3b5423f84a7f7d52b28360434db
|
|
4
|
+
data.tar.gz: 4c4ddb3a7ba0e25b0b354ce4fc753a5523b9e5b02b8621b72f6a04e23e00103f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
3
|
-
that will grow as my needs do, or if other people want or contribute any other DSLs
|
|
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
|
-
|
|
6
|
-
"what goes in, must come out"
|
|
7
|
-
Belletrist valid input
|
|
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
|
|
10
|
-
that will grow as my needs do, or if other people want or contribute any other DSLs
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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]
|
data/lib/belletrist/abstract.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Belletrist
|
|
|
26
26
|
|
|
27
27
|
def with(ele, &block)
|
|
28
28
|
@elements.push ele
|
|
29
|
-
ele.
|
|
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
|
data/lib/belletrist/html.rb
CHANGED
|
@@ -3,19 +3,7 @@
|
|
|
3
3
|
require_relative './abstract'
|
|
4
4
|
|
|
5
5
|
module Belletrist::HTML
|
|
6
|
-
class
|
|
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
|
"&" => "&",
|
|
21
9
|
"<" => "<",
|
|
@@ -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
|
|
34
|
+
component
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def component
|
|
47
38
|
end
|
|
48
39
|
|
|
49
|
-
def
|
|
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)}#{@
|
|
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
|
|
85
|
-
def initialize(spec=V5)
|
|
70
|
+
class Document
|
|
71
|
+
def initialize(spec=V5, lang=nil)
|
|
86
72
|
super()
|
|
87
|
-
|
|
88
|
-
|
|
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
|
|
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
|
data/lib/belletrist/version.rb
CHANGED
data/lib/belletrist.rb
CHANGED
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
|
|
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-
|
|
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
|
|
15
|
-
that will grow as my needs do, or if other people want or contribute any other DSLs
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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:
|