yart 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.