objective_elements 0.1.1 → 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 +4 -4
- data/README.md +83 -57
- data/lib/objective_elements/single_tag.rb +33 -9
- data/lib/objective_elements/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e11c40fa73e065603e77081aef6c8df5e0a097a2ac47e0a5c2a69b04633aebbb
|
4
|
+
data.tar.gz: 7d9568d439b669be90cd8158d1078d339c0215720fee13c6a5e10561516881c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ead034c3e4fb8ba2c72b5417386163467c856c7bd43aa3367fad91c22b63f1332c358e6b806bf3b48742c7a11d9bdd65f35de9751375efb9e655d682bd3872b4
|
7
|
+
data.tar.gz: 9c6f3afc6646ea72608a30034ca6f87de8f2590ffac58b6b83c68a3c154cc6c00d06de8bcd82d68159a0078267860b1b7f17728f59c0b4eb01a40885774b2f12
|
data/README.md
CHANGED
@@ -1,29 +1,28 @@
|
|
1
1
|
# Objective Elements
|
2
2
|
|
3
|
-
This is a tiny gem that builds nicely formatted HTML using sane, readable Ruby. I use it for jekyll
|
4
|
-
plugins, but you can use it anywhere. It's ~100 lines, with
|
5
|
-
and rake.
|
3
|
+
This is a tiny gem that builds nicely formatted HTML using sane, readable Ruby. I use it for jekyll
|
4
|
+
plugins, but you can use it anywhere. It's ~100 lines, tested with rspec, and has no dependencies.
|
6
5
|
|
7
|
-
|
6
|
+
This gem doesn't actually know any HTML. It just knows how to format it.
|
8
7
|
|
9
8
|
## How it works:
|
10
9
|
|
11
10
|
* Instantiate a `SingleTag` or `DoubleTag`
|
12
11
|
|
13
|
-
*
|
12
|
+
* Add attributes & content in one of a few ways. Nest tags infinitely.
|
14
13
|
|
15
|
-
* Render it with `.to_s
|
14
|
+
* Render it with `.to_s`
|
16
15
|
|
17
16
|
## Motivation:
|
18
17
|
|
19
18
|
Have you ever tried to build HTML with string concatenation and interpolation? It starts out simply
|
20
|
-
enough, but once you account for all the what-ifs, the indentation, the closing tags, and the
|
21
|
-
|
19
|
+
enough, but once you account for all the what-ifs, the indentation, the closing tags, and the spaces
|
20
|
+
you only need sometimes, it turns into a horrible mess.
|
22
21
|
|
23
22
|
The problem, of course, is that building long, complex, varying blocks of text with string
|
24
23
|
concatenation and interpolation is fragile, unreadable, and painful. You know this, but you're not
|
25
24
|
going to write an entirely new class or pull in some big new dependency just for 10 lines of HTML.
|
26
|
-
Instead, you
|
25
|
+
Instead, you hammer through it and end up with code like this:
|
27
26
|
|
28
27
|
```ruby
|
29
28
|
picture_tag = "<picture>\n"\
|
@@ -57,19 +56,20 @@ p.to_s
|
|
57
56
|
# <p>
|
58
57
|
# </p>
|
59
58
|
|
60
|
-
# Add attributes
|
61
|
-
p.add_attributes class: 'stumpy grumpy', id
|
62
|
-
|
63
|
-
p.
|
59
|
+
# Add attributes as a hash, values can be strings or symbols:
|
60
|
+
p.add_attributes class: 'stumpy grumpy', 'id' => 'the-ugly-one'
|
61
|
+
# Add them as a string!
|
62
|
+
p.add_attributes 'class="slimy" data-awesomeness="11"'
|
63
|
+
p.add_content "Icky"
|
64
64
|
p.to_s
|
65
|
-
# <p class="stumpy grumpy slimy" id="the-ugly-one">
|
66
|
-
#
|
65
|
+
# <p class="stumpy grumpy slimy" id="the-ugly-one" data-awesomeness="11">
|
66
|
+
# Icky
|
67
67
|
# </p>
|
68
68
|
|
69
69
|
# Want a oneliner?
|
70
70
|
p.oneline = true
|
71
71
|
p.to_s
|
72
|
-
# <p class="stumpy mopey grumpy slimy" id="the-ugly-one">
|
72
|
+
# <p class="stumpy mopey grumpy slimy" id="the-ugly-one" data-awesomeness="11">Icky</p>
|
73
73
|
p.oneline = false
|
74
74
|
|
75
75
|
# Build it up step by step, or all at once:
|
@@ -78,16 +78,16 @@ p.add_content DoubleTag.new(
|
|
78
78
|
content: 'Link!',
|
79
79
|
attributes: {href: 'awesome-possum.com'},
|
80
80
|
oneline: true
|
81
|
-
)
|
81
|
+
)
|
82
82
|
# Add a parent tag!
|
83
83
|
div = p.add_parent DoubleTag.new 'div'
|
84
84
|
|
85
|
-
# Ruby implicitly calls .to_s on things when you try to perform string functions with them,
|
86
|
-
#
|
85
|
+
# Ruby implicitly calls .to_s on things when you try to perform string functions with them, so
|
86
|
+
# things like this work:
|
87
87
|
"#{div}"
|
88
88
|
# <div>
|
89
|
-
# <p class="stumpy mopey grumpy slimy" id="the-ugly-one">
|
90
|
-
#
|
89
|
+
# <p class="stumpy mopey grumpy slimy" id="the-ugly-one" data-awesomeness="11">
|
90
|
+
# Icky
|
91
91
|
# <a href="awesome-possum.com">Link!</a>
|
92
92
|
# </p>
|
93
93
|
# </div>
|
@@ -95,9 +95,18 @@ div = p.add_parent DoubleTag.new 'div'
|
|
95
95
|
```
|
96
96
|
## Installation
|
97
97
|
|
98
|
-
|
98
|
+
```ruby
|
99
|
+
# Gemfile
|
99
100
|
|
100
|
-
|
101
|
+
gem 'objective_elements', '~> 0.2.0'
|
102
|
+
```
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# Wherever you need to use it:
|
106
|
+
|
107
|
+
require 'objective_elements'
|
108
|
+
```
|
109
|
+
## Terminology
|
101
110
|
|
102
111
|
So we're on the same page, here's the terminology I'm using:
|
103
112
|
```
|
@@ -110,16 +119,25 @@ So we're on the same page, here's the terminology I'm using:
|
|
110
119
|
- c - content
|
111
120
|
- d - closing tag
|
112
121
|
|
113
|
-
There are 2 classes: `SingleTag` is the base class, and `DoubleTag` inherits from it. A `SingleTag`
|
114
|
-
self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is the other
|
122
|
+
There are 2 classes: `SingleTag` is the base class, and `DoubleTag` inherits from it. A `SingleTag`
|
123
|
+
is a self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is the other
|
124
|
+
kind.
|
125
|
+
|
126
|
+
## Usage
|
115
127
|
|
116
128
|
### SingleTag Properties:
|
117
129
|
|
118
|
-
|
119
|
-
|
120
|
-
-
|
121
|
-
|
122
|
-
|
130
|
+
#### element
|
131
|
+
- String
|
132
|
+
- Mandatory
|
133
|
+
- Which type of tag it is, such as 'hr' or 'img'
|
134
|
+
- Defined on initialization, cannot be changed afterwards. (Should it be? I'm on the fence about it.)
|
135
|
+
|
136
|
+
#### attributes
|
137
|
+
- Hash
|
138
|
+
- Optional
|
139
|
+
- Keys are symbols, values are arrays of strings. `{class: ['stumpy', 'slimy']}`
|
140
|
+
- add them with `.add_attributes`, which can accept a few different formats.
|
123
141
|
|
124
142
|
### SingleTag Methods (that you care about)
|
125
143
|
|
@@ -127,9 +145,12 @@ self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is
|
|
127
145
|
|
128
146
|
`.to_s` - The big one. Returns your HTML as a string, nondestructively.
|
129
147
|
|
130
|
-
`.reset_attributes(
|
148
|
+
`.reset_attributes(new)` - Deletes all attributes, calls add_attributes on supplied argument if
|
149
|
+
given.
|
131
150
|
|
132
|
-
`.add_attributes(
|
151
|
+
`.add_attributes(new)` - The only way we add new attributes. Can accept a hash (keys can be either
|
152
|
+
symbols or strings), or a string in the standard HTML syntax (`attribute="value" attribute2="value2
|
153
|
+
value3"`). Returns self.
|
133
154
|
|
134
155
|
`.add_parent(DoubleTag)` - returns supplied DoubleTag, with self added as a child.
|
135
156
|
|
@@ -138,35 +159,38 @@ self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is
|
|
138
159
|
### DoubleTag Properties:
|
139
160
|
|
140
161
|
#### `DoubleTag` Inherits all of `SingleTag`'s properties and methods, but adds content and a closing tag.
|
141
|
-
- content:
|
142
|
-
**Array**, optional, containing anything (but probably just strings and tags. Anything else
|
143
|
-
will be turned into a string with `.to_s`, which is an alias for `.inspect` most of the time).
|
144
162
|
|
145
|
-
|
146
|
-
get as many lines as they need (like you'd expect).
|
163
|
+
#### content
|
147
164
|
|
148
|
-
|
165
|
+
- Array
|
166
|
+
- Optional
|
167
|
+
- Contains anything (but probably just strings and tags. Anything else will be turned into a
|
168
|
+
string with `.to_s`, which is an alias for `.inspect` most of the time).
|
169
|
+
- Each element in the array corresponds to at least one line of HTML
|
170
|
+
- Multiline child tags will get as many lines as they need (like you'd expect).
|
171
|
+
- Child elements are not rendered until the parent is rendered, meaning you can access and
|
149
172
|
modify them after defining a parent.
|
173
|
+
- add with `.add_content`, or modify the content array directly.
|
150
174
|
|
151
|
-
|
152
|
-
|
153
|
-
|
175
|
+
#### oneline
|
176
|
+
- Boolean
|
177
|
+
- optional, defaults to false.
|
178
|
+
- When true, the entire element and its content will be rendered as a single line. Useful for
|
179
|
+
anchor tags and list items.
|
154
180
|
|
155
181
|
### DoubleTag Methods (that you care about)
|
156
182
|
|
157
|
-
`DoubleTag.new(element, attributes: {}, oneline: false, content: [])`
|
158
|
-
|
183
|
+
`DoubleTag.new(element, attributes: {}, oneline: false, content: [])` - You can initialize it with
|
184
|
+
content.
|
159
185
|
|
160
|
-
`add_content(anything)`
|
161
|
-
|
186
|
+
`add_content(anything)` - Smart enough to handle both arrays and not-arrays without getting dorked
|
187
|
+
up.
|
162
188
|
|
163
|
-
`attr_accessor: content`
|
164
|
-
|
165
|
-
`.add_content`
|
189
|
+
`attr_accessor: content` - You can modify the content array directly if you like. If you're just
|
190
|
+
adding items, you should use `.add_content`
|
166
191
|
|
167
|
-
`.to_a`
|
168
|
-
|
169
|
-
indentation applied, this is how you can get it.
|
192
|
+
`.to_a` - Mostly used internally, but if you want an array of strings, each element a line with
|
193
|
+
appropriate indentation applied, this is how you can get it.
|
170
194
|
|
171
195
|
## Configuration
|
172
196
|
|
@@ -180,6 +204,8 @@ self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is
|
|
180
204
|
Example:
|
181
205
|
|
182
206
|
```ruby
|
207
|
+
|
208
|
+
require 'ojbective_elements'
|
183
209
|
|
184
210
|
class MyDoubleTag < DoubleTag
|
185
211
|
def indent
|
@@ -197,11 +223,11 @@ MyDoubleTag.new('p', content: 'hello').to_s
|
|
197
223
|
|
198
224
|
## Limitations
|
199
225
|
|
200
|
-
* It
|
201
|
-
|
226
|
+
* It doesn't know a single HTML element on its own, so it does nothing to ensure your
|
227
|
+
HTML is valid. Garbage in, garbage out.
|
202
228
|
|
203
229
|
* A parent tag can't put siblings on the same line. You can either
|
204
|
-
|
230
|
+
do this (with `oneline: true` on the strong tag):
|
205
231
|
|
206
232
|
```html
|
207
233
|
|
@@ -228,14 +254,14 @@ MyDoubleTag.new('p', content: 'hello').to_s
|
|
228
254
|
Here is some <strong>strong</strong> text.
|
229
255
|
|
230
256
|
```
|
231
|
-
|
257
|
+
This doesn't affect how the browser will render it, but it might bug you if you're particular about
|
232
258
|
source code layout.
|
233
259
|
|
234
260
|
* If you set 'oneline: true' on a parent DoubleTag, but not all its children DoubleTags, the output
|
235
|
-
|
261
|
+
will not be pretty. I advise against it.
|
236
262
|
|
237
263
|
* It doesn't wrap long lines of text, and it doesn't indent text with newlines embedded. It's on the
|
238
|
-
|
264
|
+
TODO list.
|
239
265
|
|
240
266
|
## Contributing
|
241
267
|
|
@@ -23,17 +23,13 @@ class SingleTag
|
|
23
23
|
# This is the only way we add new attributes. Flexible about what you give
|
24
24
|
# it-- accepts both strings and symbols for the keys, and both strings and
|
25
25
|
# arrays for the values.
|
26
|
-
def add_attributes(new)
|
27
|
-
formatted_new = {}
|
28
|
-
new.each_pair do |k, v|
|
29
|
-
v = v.split ' ' if v.is_a? String
|
30
|
-
formatted_new[k.to_sym] = v
|
31
|
-
end
|
32
26
|
|
33
|
-
|
34
|
-
|
27
|
+
def add_attributes(new)
|
28
|
+
if new.is_a? String
|
29
|
+
add_string_attributes(new)
|
30
|
+
else
|
31
|
+
add_hash_attributes(new)
|
35
32
|
end
|
36
|
-
self
|
37
33
|
end
|
38
34
|
alias_method :add_attribute, :add_attributes
|
39
35
|
|
@@ -65,4 +61,32 @@ class SingleTag
|
|
65
61
|
def to_s
|
66
62
|
opening_tag + "\n"
|
67
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def add_string_attributes(new)
|
68
|
+
# looking for something like:
|
69
|
+
# 'class="something something-else" id="my-id"'
|
70
|
+
new_hash = {}
|
71
|
+
new.scan(/ ?([^="]+)="([^"]+)"/).each do |m|
|
72
|
+
# [['class','something something-else'],['id','my-id']]
|
73
|
+
new_hash[m.shift] = m.pop
|
74
|
+
end
|
75
|
+
|
76
|
+
add_hash_attributes(new_hash)
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_hash_attributes(new)
|
80
|
+
formatted_new = {}
|
81
|
+
new.each_pair do |k, v|
|
82
|
+
v = v.split ' ' if v.is_a? String
|
83
|
+
formatted_new[k.to_sym] = v
|
84
|
+
end
|
85
|
+
|
86
|
+
@attributes.merge! formatted_new do |_key, oldval, newval|
|
87
|
+
oldval.concat newval
|
88
|
+
end
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
68
92
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: objective_elements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Buchberger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|