yart 0.1.0 → 0.2.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: 6dd8a4e37aedd9a60366cf53c6d3a270d098fb4739d2a4044b70c9515fe3f323
4
- data.tar.gz: ad1b5c369574d17de2025fb1945bbb6a611d2ea88f239dfd08877af78a3e87d1
3
+ metadata.gz: 03fbc3910c0db0766cd4ccdd88102c0e777c34d0b7485e9a93c6b67a1c5d9d4c
4
+ data.tar.gz: fcfa919687199006176319f750ba06b6953565a7500455b17eb16afaeae5387b
5
5
  SHA512:
6
- metadata.gz: b5eb0adbd6e5d46267db1c655248122c7e8028700ba315f16200a995d77ba4a815213a6a7b1374def5211fff61c82c3d930940cac5c907e94d4fa169cf4ed2b0
7
- data.tar.gz: accd0937be8d188c1d7f5b46bd36739be711901d5eacdb667e7e891da4bc70230e00a313d314d3d46f64b5378f4670c5bef782aa2f3681c4601aedff606ab021
6
+ metadata.gz: d75dd2df60e6c8754c09b302ebfb385cfbc1802f3c106d9bc8766639fd8dbbc9334e01d854eadca289be0821b70f36683bb992649efdec66797bf6e337b2d359
7
+ data.tar.gz: 55e9cdba62d6fb48bcd60b78577b6e598fb1f91e2670e68464c420aec99286698b0a5cbf2883fbd32c94d345980df4a62568fbb19d7f125069a918eb9d70c7df
data/Gemfile CHANGED
@@ -5,8 +5,8 @@ source "https://rubygems.org"
5
5
  ruby "~> 2.7"
6
6
 
7
7
  group :development do
8
+ gem "byebug", "~> 11.1"
8
9
  gem "minitest", "~> 5.0"
9
10
  gem "rake", "~> 13.0"
10
11
  gem "rubocop", "~> 1.7"
11
- gem "byebug", "~> 11.1"
12
12
  end
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  *Yet Another Ruby Templater* turns plain Ruby into HTML making it fun to write webpages.
4
4
 
5
5
  - YART provides an intuitive DSL that feels natural to use and removes the boiler plate from writing HTML
6
- - YART has zero runtime dependencies and around 100 lines of code
6
+ - YART has zero runtime dependencies and around 120 lines of code
7
7
  - YART is fully unit tested
8
8
 
9
9
  ## Example Usage
@@ -112,7 +112,11 @@ Main points to note:
112
112
  - Several attibute *values* can be rendered by passing an `Array` e.g. `p class: [:para, :italic]`. The values will be rendered space separated.
113
113
  - Attribute *values* containing illegal characters (like quotes etc.) will be escaped in the rendered HTML.
114
114
  - The attribute `close: true` is special and tells the parser to auto-close the element (because it's empty).
115
- - Use the convenience methods `doctype`, `script` and `stylesheet` as needed.
115
+ - Use the convenience methods `doctype`, `javascript`, `stylesheet` and `br` as needed.
116
+
117
+ ## Markdown
118
+
119
+ If you're creating a site with a lot of static textual content, check out the [static_site_builder](https://github.com/michaeltelford/static_site_builder) gem. It can render HTML sites built using Markdown and it fully supports YART; meaning you can write your text in Markdown and your forms etc in YART, never needing to touch HTML.
116
120
 
117
121
  ## Development
118
122
 
data/bin/console CHANGED
@@ -40,7 +40,7 @@ def sample
40
40
  div data_test_id: "String attribute values will be parsed as is" do
41
41
  h2(data_x: :sub_heading) { "Symbol attribute keys/values will be kebab-cased" }
42
42
  text { "Set the div's innerText, before and/or after its child elements" }
43
- p(class: [:content, :italic_text], id: :paragraph) do
43
+ p(class: %i[content italic_text], id: :paragraph) do
44
44
  "You can pass an array of attribute values and they will be space separated"
45
45
  end
46
46
  end
data/lib/yart/parser.rb CHANGED
@@ -1,125 +1,135 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module YART::Parser
4
- CUSTOM_ATTRIBUTES = [:close]
5
-
6
- # Parses a block of Ruby, rendering and returning a HTML String.
7
- def parse(&block)
8
- raise "Must pass a block to parse" unless block_given?
9
-
10
- @@yart_buffer = []
11
- instance_eval(&block)
12
- @@yart_buffer.join
13
- end
14
-
15
- # Allows elements to be called and rendered via a DSL.
16
- def method_missing(m, *args, &block)
17
- attributes = args.fetch(0, {})
18
-
19
- render(m, attributes, &block)
20
- end
21
-
22
- # Renders an element with the raw name (case insensitive).
23
- def element(name, **attributes, &block)
24
- render(name, attributes, &block)
25
- end
26
-
27
- # Renders a <!DOCTYPE html> element, for convenience.
28
- def doctype
29
- element("!DOCTYPE", html: true, close: true)
30
- end
31
-
32
- # Renders a JS <script src="..."> element, for convenience.
33
- def script(src = nil, &block)
34
- raise "Must pass a String param or a block returning a String" unless src || block_given?
35
-
36
- src ||= block.call
37
- element("script", src: src, close: true)
38
- end
39
-
40
- # Renders a CSS <link href="..."> element, for convenience.
41
- def stylesheet(href = nil, &block)
42
- raise "Must pass a String param or a block returning a String" unless href || block_given?
43
-
44
- href ||= block.call
45
- element("link", href: href, rel: :stylesheet, type: "text/css", close: true)
46
- end
47
-
48
- # Overrides Ruby's `p` method to render the element instead of printing.
49
- def p(**attributes, &block)
50
- render("p", attributes, &block)
51
- end
52
-
53
- # Sets the `innerText` of the element being rendered.
54
- def text(str = nil, &block)
55
- raise "Must pass a String param or a block returning a String" unless str || block_given?
56
-
57
- str ||= block.call
58
- buffer(str)
59
- end
60
-
61
- private
62
-
63
- def buffer(str)
64
- @@yart_buffer << str if str.is_a?(String)
65
- end
66
-
67
- def render(element, attributes, &block)
68
- raise "Must pass attributes as a Hash" unless attributes.is_a?(Hash)
69
-
70
- buffer(build_opening_tag(element, attributes))
71
- buffer(instance_eval(&block)) if block_given?
72
- buffer(build_closing_tag(element, attributes))
73
- end
74
-
75
- def build_opening_tag(element, attributes)
76
- attributes_str = sanitise_attributes(attributes)
77
- .reject { |k, v| CUSTOM_ATTRIBUTES.include?(k) }
78
- .map { |k, v| v == true ? k.to_s : "#{k}='#{v}'" }
79
- .join(" ")
80
- separator = attributes_str.empty? ? "" : " "
81
-
82
- "<#{element}#{separator}#{attributes_str}>"
83
- end
84
-
85
- def build_closing_tag(element, attributes)
86
- attributes[:close] ? "" : "</#{element}>"
87
- end
88
-
89
- def sanitise_attributes(attributes)
90
- attributes.map do |k, v|
91
- k = kebab_case(k)
92
- v = v.respond_to?(:map) ?
93
- v.map { |v2| convert_attribute_value(v2) }.join(" ") :
94
- convert_attribute_value(v)
95
-
96
- [k, v]
97
- end.to_h
98
- end
99
-
100
- def convert_attribute_value(value)
101
- value = kebab_case(value)
102
- value = replace_illegal_chars(value)
103
-
104
- value
105
- end
106
-
107
- def kebab_case(s)
108
- return s unless s.is_a?(Symbol)
109
-
110
- s
111
- .to_s
112
- .gsub("_", "-")
113
- .to_sym
114
- end
115
-
116
- def replace_illegal_chars(s)
117
- return s unless s.is_a?(String)
118
-
119
- s
120
- .gsub('"', "&quot;")
121
- .gsub("'", "&#39;")
122
- .gsub("<", "&lt;")
123
- .gsub(">", "&gt;")
3
+ module YART
4
+ module Parser
5
+ CUSTOM_ATTRIBUTES = [:close].freeze
6
+
7
+ # Parses a block of Ruby, rendering and returning a HTML String.
8
+ def parse(&block)
9
+ raise "Must pass a block to parse" unless block_given?
10
+
11
+ @@yart_buffer = []
12
+ instance_eval(&block)
13
+ @@yart_buffer.join
14
+ end
15
+
16
+ # Allows elements to be called and rendered via a DSL.
17
+ def method_missing(m, *args, &block)
18
+ attributes = args.fetch(0, {})
19
+
20
+ element(m, **attributes, &block)
21
+ end
22
+
23
+ # Renders an element with the raw name (case insensitive).
24
+ def element(name, **attributes, &block)
25
+ render(name, attributes, &block)
26
+ end
27
+
28
+ # Sets the `innerText` of the element being rendered.
29
+ def text(str = nil, &block)
30
+ raise "Must pass a String param or a block returning a String" unless str || block_given?
31
+
32
+ str ||= block.call
33
+ buffer(str)
34
+ end
35
+
36
+ # Renders a <!DOCTYPE html> element, for convenience.
37
+ def doctype
38
+ element("!DOCTYPE", html: true, close: true)
39
+ end
40
+
41
+ # Renders a JS <script src="..."> element, for convenience.
42
+ def javascript(src = nil, &block)
43
+ raise "Must pass a String param or a block returning a String" unless src || block_given?
44
+
45
+ src ||= block.call
46
+ element("script", src: src, close: true)
47
+ end
48
+
49
+ # Renders a CSS <link href="..."> element, for convenience.
50
+ def stylesheet(href = nil, &block)
51
+ raise "Must pass a String param or a block returning a String" unless href || block_given?
52
+
53
+ href ||= block.call
54
+ element("link", href: href, rel: :stylesheet, type: "text/css", close: true)
55
+ end
56
+
57
+ def br(**attributes, &block)
58
+ attributes[:close] = true unless attributes[:close] == false
59
+ element("br", **attributes, &block)
60
+ end
61
+
62
+ # Overrides Ruby's `p` method to render the element instead of printing.
63
+ def p(**attributes, &block)
64
+ element("p", **attributes, &block)
65
+ end
66
+
67
+ private
68
+
69
+ def buffer(str)
70
+ @@yart_buffer << str if str.is_a?(String)
71
+ end
72
+
73
+ def render(element, attributes, &block)
74
+ raise "Must pass attributes as a Hash" unless attributes.is_a?(Hash)
75
+ if block_given? && attributes.fetch(:close, false)
76
+ raise "Block and 'close: true' are mutually exclusive"
77
+ end
78
+
79
+ buffer(build_opening_tag(element, attributes))
80
+ buffer(instance_eval(&block)) if block_given?
81
+ buffer(build_closing_tag(element, attributes))
82
+ end
83
+
84
+ def build_opening_tag(element, attributes)
85
+ attributes_str = sanitise_attributes(attributes)
86
+ .reject { |k, _v| CUSTOM_ATTRIBUTES.include?(k) }
87
+ .map { |k, v| v == true ? k.to_s : "#{k}='#{v}'" }
88
+ .join(" ")
89
+ separator = attributes_str.empty? ? "" : " "
90
+
91
+ "<#{element}#{separator}#{attributes_str}>"
92
+ end
93
+
94
+ def build_closing_tag(element, attributes)
95
+ attributes[:close] ? "" : "</#{element}>"
96
+ end
97
+
98
+ def sanitise_attributes(attributes)
99
+ attributes.map do |k, v|
100
+ k = kebab_case(k)
101
+ v = if v.respond_to?(:map)
102
+ v.map { |v2| convert_attribute_value(v2) }.join(" ")
103
+ else
104
+ convert_attribute_value(v)
105
+ end
106
+
107
+ [k, v]
108
+ end.to_h
109
+ end
110
+
111
+ def convert_attribute_value(value)
112
+ value = kebab_case(value)
113
+ replace_illegal_chars(value)
114
+ end
115
+
116
+ def kebab_case(s)
117
+ return s unless s.is_a?(Symbol)
118
+
119
+ s
120
+ .to_s
121
+ .gsub("_", "-")
122
+ .to_sym
123
+ end
124
+
125
+ def replace_illegal_chars(s)
126
+ return s unless s.is_a?(String)
127
+
128
+ s
129
+ .gsub('"', "&quot;")
130
+ .gsub("'", "&#39;")
131
+ .gsub("<", "&lt;")
132
+ .gsub(">", "&gt;")
133
+ end
124
134
  end
125
135
  end
data/lib/yart/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module YART
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/load.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  # Development script which loads (all changes to) the code when called.
4
4
 
5
- load 'lib/yart/version.rb'
6
- load 'lib/yart/parser.rb'
7
- load 'lib/yart.rb'
5
+ load "lib/yart/version.rb"
6
+ load "lib/yart/parser.rb"
7
+ load "lib/yart.rb"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Telford
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-03 00:00:00.000000000 Z
11
+ date: 2021-08-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Yet Another Ruby Templater (YART) turns plain Ruby into HTML making it fun to write webpages.