objective_elements 1.0.0 → 1.1.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: c40decb6ef274c91eb3c04c8b88e3fe8cfebf9be34173044faa8541bee7e1a8c
4
- data.tar.gz: c89f6d58e729c5a3a60095244fcdbcdb30b1f109214b0faf91b9b3c4fd27cf83
3
+ metadata.gz: cd77403a8910ff13f0b09d7d6d1a1e258b272f728d210f795d87e4df666309d3
4
+ data.tar.gz: b937e84cc9071b9f103cc8fa8980b2a3f68ce976c22e6baf79d2cd23c8b16bb6
5
5
  SHA512:
6
- metadata.gz: 7ba86d122bbacc96b7fa989cb122a63582cb9e6619a5e42777ed7eb69bf80b2837feca836c0f430c870a60c34e0f22906b10e808e1debd1c6ebe7f6b9ab6da56
7
- data.tar.gz: 236c0aa5c7768d653ad702b63b66ffc2261416ac0cad3ba9bc404684f7428d41584468f9951b5967125f14b33000c26b5e79f7910dea6081e43f4879d03e65c7
6
+ metadata.gz: e14e8f6c77cd762a26180d477ce028df2db91bf03309283dcdeb84c63cd0eb540af60f7c041b6c9d24d2a1647ccff47e5fab2037990f44bc4737a92168cd417c
7
+ data.tar.gz: 07712c2317042d016e37dee5b95e1d411c2788ab2b61399ff3adf790c9282ae73d66dbcaf7a87da1ed8116fd554c836257707f93a158b871f6c8d28a3a044405
data/README.md CHANGED
@@ -1,23 +1,15 @@
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, tested with rspec, and has no dependencies.
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.
5
5
 
6
6
  It doesn't actually know any HTML, just how to format it.
7
7
 
8
8
  This is meant to be less involved and more flexible than nokogiri's XML/HTML generator. There's no
9
- DSL to learn, and no cleverness to wrap your mind around. Its specialty is taking fragmented,
9
+ DSL to learn and no cleverness to wrap your mind around. Its specialty is taking fragmented,
10
10
  disjointed information and condensing it into a string of properly formatted HTML. It's as agnostic
11
11
  as possible on the input, while being extremely consistent with its output.
12
12
 
13
- ## How it works:
14
-
15
- * Instantiate a `SingleTag` or `DoubleTag`
16
-
17
- * Add attributes & content. Nest tags infinitely.
18
-
19
- * Render it with `.to_s`
20
-
21
13
  ## Motivation:
22
14
 
23
15
  Have you ever tried to build HTML with string concatenation and interpolation? It starts out simply
@@ -51,62 +43,49 @@ or this:
51
43
  end
52
44
  ```
53
45
 
54
- Which is why I sat down and wrote this gem. It's super simple, you probably could have written it
55
- too, but hey! Now you don't have to. Here's a demo:
56
-
57
46
  ## Demo
58
47
 
59
48
  ```ruby
60
- # gemfile:
61
- gem 'objective_elements', '~>1.0.0'
62
-
63
- # Anywhyere else:
64
- require 'objective_elements'
65
-
66
49
  p = DoubleTag.new 'p'
67
50
  p.to_s
68
51
  # <p>
69
52
  # </p>
70
53
 
71
- # Add attributes as a hash. keys can be strings or symbols, values can be arrays or strings:
72
54
  p.attributes << { class: 'stumpy grumpy', 'id' => 'the-ugly-one' }
73
55
 
74
- # Add attributes as a string!
56
+ p.id
57
+ # the-ugly-one
58
+
75
59
  p.attributes << 'class="slimy" data-awesomeness="11"'
76
60
 
77
- # Get attributes by calling a method!
78
- p.data-awesomeness
61
+
62
+ # Ruby method names can't have dashes.
63
+ p.attributes['data-awesomeness']
79
64
  # '11'
80
65
 
81
- # Set them, too! (Note: This doesn't work for class or method)
82
66
  p.id = 'killer'
83
67
 
84
- # Add content. It can be anything, or an array of anythings.
85
- p.add_content "Icky"
68
+ p << "Icky"
86
69
 
87
70
  p.to_s
88
71
  # <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">
89
72
  # Icky
90
73
  # </p>
91
74
 
92
- # Want a oneliner?
93
75
  p.oneline = true
94
76
  p.to_s
95
77
  # <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">Icky</p>
96
78
  p.oneline = false
97
79
 
98
- # Build a tag all at once:
99
80
  p.add_content DoubleTag.new(
100
81
  'a',
101
82
  content: 'Link!',
102
- attributes: {href: 'awesome-possum.com'},
83
+ attributes: { href: 'awesome-possum.com' },
103
84
  oneline: true
104
85
  )
105
86
 
106
- # Add a parent tag:
107
87
  div = p.add_parent DoubleTag.new 'div'
108
88
 
109
- # Implicit string conversion means cool stuff like this works:
110
89
  "#{div}"
111
90
  # <div>
112
91
  # <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">
@@ -117,26 +96,31 @@ div = p.add_parent DoubleTag.new 'div'
117
96
 
118
97
  ```
119
98
 
120
- For complete example usage, see [jekyll_icon_list](https://github.com/rbuchberger/jekyll_icon_list), or
121
- this [pull request](https://github.com/robwierzbowski/jekyll-picture-tag/pull/87/commits/d6b2deca0f19f173251a2984037e5e5f8d7c21d1)
122
- to [jekyll-picture-tag](https://github.com/robwierzbowski/jekyll-picture-tag).
99
+ ## Changes
100
+
101
+ ### 1.1.0
102
+ Add `ShelfTag`, which is useful when you want to create siblings without a parent element.
103
+
104
+ ### 1.0.0
105
+ Attributes syntax has changed pretty significantly. Find `.add_attributes` & replace `.attributes << `
106
+ will get you most of the way there, but you should read over the usage section again.
123
107
 
124
108
  ## Installation
125
109
 
126
110
  ```ruby
127
111
  # Gemfile
128
112
 
129
- gem 'objective_elements', '~> 0.2.0'
113
+ gem 'objective_elements', '~> 1.0.0'
130
114
  ```
131
115
 
132
116
  ```ruby
133
- # Wherever you need to use it:
117
+ # Anywhere else:
134
118
 
135
119
  require 'objective_elements'
136
120
  ```
121
+
137
122
  ## Terminology
138
123
 
139
- So we're on the same page, here's the terminology I'm using:
140
124
  ```
141
125
  <p class="stumpy">Hello</p>
142
126
  |a| b | c | d |
@@ -150,75 +134,114 @@ So we're on the same page, here's the terminology I'm using:
150
134
 
151
135
  ## Usage
152
136
 
137
+ For Attribute & SingleTag examples, we'll use this image tag:
138
+ ```ruby
139
+
140
+ img = SingleTag.new 'img', attributes: 'src="angry-baby.jpg"'
141
+
142
+ ```
143
+
153
144
  There are 2 classes you care about: `SingleTag` is the base class, and `DoubleTag` inherits from it.
154
145
  A `SingleTag` is a self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is
155
146
  the other kind.
156
147
 
157
148
  ### Attributes
158
149
  Attributes are their own class, and can be accessed by the `.attributes` method on both single and
159
- double tags. Important methods:
150
+ double tags. Important methods:
160
151
 
161
- ` << (attribute)` - Add new attributes, can accept a hash or a string. Hash keys will be converted
152
+ ` << (attribute)`
153
+ - Example: `p.attributes << 'alt="he does not look happy"'`
154
+ - Example: `p.attributes << { alt: "he does not look happy" }`
155
+ - Add new attributes, can accept a hash or a string. Hash keys will be converted
162
156
  to symbols if they are not already, and values will be split on spaces into an array if they are not
163
157
  already. Attributes can also be given as a string in the standard HTML syntax (`class="myclass"
164
158
  id="my-id"`). **Every other method which adds attributes in some way, calls this method**. This
165
159
  means that any time you are adding attributes, you can use any format which this method understands.
166
160
 
167
- `.delete(attribute)` - Delete one or more attributes. Accepts a string, symbol, or an array of
161
+ `.delete(attribute)`
162
+ - Example: `img.attributes.delete 'src'`
163
+ - Example: `img.attributes.delete :src`
164
+ - Example: `img.attributes.delete [:src, 'alt']`
165
+ - Delete one or more attributes. Accepts a string, symbol, or an array of
168
166
  strings and/or symbols.
169
167
 
170
- `.replace(attribute)` - Replaces one or more attributes and values.
168
+ `.replace(attribute)`
169
+ - Example: `img.attributes.replace 'src="happy-baby.jpg"'`
170
+ - Replaces one or more attributes and values individually.
171
+
172
+ `.content[:attribute_name] = `
173
+ - Example: `img.attributes.content[:src] = 'dirty-baby.jpg'` < This just broke everything.
174
+ - Don't do it. Use `.replace`, `.(attribute name) = `, or `<<`
175
+
176
+ `.content[:attribute_name]`
177
+ - Example: `img.attributes[:src] # returns 'angry-baby.jpg`
178
+ - Retrieve the content for a given attribute, as an array of strings. Must be a symbol. You'll
179
+ - mostly need this when you don't know which attribute you need ahead of
180
+ time, or to access class and method attributes because you can't use the methods below:
181
+
182
+ **There is a shorthand for the next two methods. Keep reading.**
171
183
 
172
- `.content[:attribute_name]` - Retrieve the content for a given attribute, as an array of strings.
173
- Must be a symbol. You'll mostly need this when you don't know which attribute you need ahead of ti
174
- me, or to access class and method attributes because you can't use the methods below:
184
+ `.(attribute_name)`
185
+ - Example: `img.attributes.src # 'angry-baby.jpg'`
186
+ - Convenience method/syntactic sugar: Returns the value of a given attribute name, as a
187
+ - space-separated string. This relies on method_missing, which means that any overlap with
188
+ already existing methods won't work.
189
+ - **You can't access `class` or `method` html attributes this way, because
190
+ basic objects in ruby already have those methods.**
191
+ - **Ruby methods can't have dashes in them.** This means `p.data-awesomeness` won't work.
175
192
 
176
- `.content[:attribute_name] = ` - Don't do it. Use `<<` or `.replace`.
193
+ `.(attribute_name) = value`
194
+ - Example: `img.attributes.src = 'happy-baby.jpg'`
195
+ - Same as above. Similar to `.replace(attribute)`. Interestingly, `method = ` and `class = ` both
196
+ work (`.class` is defined on the basic object class, but `.class=` is not.). Still, you
197
+ probably shouldn't use them.
177
198
 
178
- `.(attribute_name)` - Convenience method/syntactic sugar: Returns the value of a given attribute
179
- name, as a space-separated string. This relies on method_missing, which means that any overlap with
180
- already existing methods won't work. **You can't access `class` or `method` html attributes this
181
- way, because basic objects in ruby already have those methods.**
199
+ **Missing methods are forwarded from elements to their attributes, so you can do this:**
182
200
 
183
- `.(attribute_name) = value` - Same as above. Equivalent to `.replace(attribute)`. Interestingly,
184
- `method = ` and `class = ` both work (`.class` is defined on the basic object class, but `.class=`
185
- is not.). That said, you probably shouldn't use them because it will be confusing to understand
186
- later.
201
+ - Example: `img.src # returns 'angry-baby.jpg'`
202
+ - Example: `img.src = 'grumpy-baby.jpg'`
187
203
 
188
204
  ### SingleTag Properties:
189
205
 
190
206
  #### element
191
207
  - String
192
208
  - Mandatory
193
- - Which type of tag it is, such as 'hr' or 'img'
209
+ - Which type of tag, such as 'hr' or 'img'
210
+
194
211
  #### attributes
195
212
  - Instance of the class described above.
196
213
 
197
-
198
214
  ### SingleTag Methods (that you care about)
199
215
 
200
216
  `SingleTag.new(element, attributes: nil)`
201
217
 
202
- `.to_s` - The big one. Returns your HTML as a string, nondestructively.
218
+ `.to_s`
219
+ - Example: `img.to_s`
220
+ - The big one. Returns your HTML as a string, nondestructively.
203
221
 
204
- `.add_parent(DoubleTag)` - returns supplied DoubleTag, with self added as a child.
222
+ `.add_parent(DoubleTag)`
223
+ - Example: `img.add_parent DoubleTag.new 'picture'`
224
+ - returns supplied DoubleTag, with self added as a child.
205
225
 
206
- `.attributes` - attr_reader for HTML attributes. This is how you can access any attribute method
226
+ `.attributes`
227
+ - Example: `img.attributes`
228
+ - attr_reader for HTML attributes. This is how you can access any attribute method
207
229
  described above.
208
230
 
209
- `.reset_attributes` - Removes all attributes
231
+ `.reset_attributes`
232
+ - Example: `img.reset_attributes`
233
+ - Removes all attributes.
210
234
 
211
- `.attributes=(attributes)` - Sets attributes to the supplied argument
235
+ `.attributes=(new)`
236
+ - Example: `img.attributes = 'src="grumpy-baby.jpg" id="muddy"'`
237
+ - Equivalent to `reset_attributes` and `.attributes << new`
212
238
 
213
239
  `attr_reader :attributes`
214
240
  `attr_accessor :element`
215
241
 
216
- `.(attribute_name)` / `.(attribute_name) = ` - Forwarded to attributes object. Allows you to set or
217
- retrieve the value of attributes other than `class` and `method`, without having to type
218
- `.attributes` in front of it.
219
-
220
242
  ### DoubleTag Properties:
221
243
 
244
+
222
245
  #### `DoubleTag` Inherits all of `SingleTag`'s properties and methods, and adds content and a
223
246
  closing tag.
224
247
 
@@ -242,23 +265,43 @@ closing tag.
242
265
 
243
266
  ### DoubleTag Methods (that you care about)
244
267
 
245
- `DoubleTag.new(element, attributes: {}, oneline: false, content: [])` - You can initialize it with
246
- content.
268
+ For DoubleTag Examples, we're working with a div tag:
247
269
 
248
- `add_content(anything)` - Smart enough to handle both arrays and not-arrays without getting dorked
249
- up. When given an array, its elements will be appended to the content array. When given a single
250
- item, that item will be inserted at the end of the array. (Remember each element in the content
251
- array gets at least one line!)
270
+ ```
271
+ div = DoubleTag.new 'div'
272
+ ```
273
+
274
+ `DoubleTag.new(element, attributes: {}, oneline: false, content: [])`
275
+ - You can initialize it with content.
276
+
277
+ `add_content(anything)`
278
+ - Example: `div.add_content 'example text!'`
279
+ - Example: `div.add_content ['splits', 'across', 'lines']`
280
+ - Example: `div.add_content img # image tag from earlier`
281
+ - Smart enough to handle both arrays and not-arrays without getting dorked up. When given an array,
282
+ its elements will be appended to the content array. When given a single item, that item will be
283
+ inserted at the end of the array. (Remember each element in the content array gets at least one
284
+ line!)
252
285
 
253
286
  `attr_accessor: content` - You can modify the content array directly if you like. If you're just
254
287
  adding items, you should use `.add_content`
255
288
 
289
+ `oneline` - Example: `div.oneline = true`
290
+
256
291
  `.to_a` - Mostly used internally, but if you want an array of strings, each element a line with
257
292
  appropriate indentation applied, this is how you can get it.
258
293
 
294
+ ### ShelfTags:
295
+
296
+ Shelf tags are like invisible double tags. Think of them like a bookshelf.
297
+ They're useful when you want to build siblings without a corresponding parent
298
+ tag.
299
+
300
+ Convert it into an actual tag with `.add_parent(DoubleTag)`
301
+
259
302
  ## Configuration
260
303
 
261
- Indentation is defined by the `indent` method on the DoubleTag class, which is two markdown-escaped
304
+ Indentation is defined by the `indent` method on the DoubleTag class, which is two escaped
262
305
  spaces by default ("\ \ "). If you'd like to change it:
263
306
 
264
307
  1. Make a new class, inherit from DoubleTag.
@@ -2,4 +2,5 @@ module ObjectiveElements
2
2
  require_relative 'objective_elements/single_tag'
3
3
  require_relative 'objective_elements/double_tag'
4
4
  require_relative 'objective_elements/html_attributes'
5
+ require_relative 'objective_elements/shelf_tag'
5
6
  end
@@ -40,6 +40,7 @@ class DoubleTag < SingleTag
40
40
  private
41
41
 
42
42
  def build_content_line(element)
43
+ # Since DoubleTag inherits from SingleTag, it will slurp up those too.
43
44
  element.is_a?(SingleTag) ? element.to_a : element.to_s.dup
44
45
  end
45
46
 
@@ -6,6 +6,10 @@ class HTMLAttributes
6
6
  self << new
7
7
  end
8
8
 
9
+ def [](key)
10
+ @content[key.to_sym]
11
+ end
12
+
9
13
  def to_s
10
14
  return_string = ''
11
15
  @content.each_pair do |k, v|
@@ -0,0 +1,17 @@
1
+ # This is a nonexistent HTML tag, which holds content like a double tag but has
2
+ # no opening or closing tag. This allows us to group siblings without adding an
3
+ # extra parent to the markup.
4
+ class ShelfTag < DoubleTag
5
+ def initialize(content: nil, oneline: false)
6
+ self.oneline = oneline
7
+ self.content = content
8
+ end
9
+
10
+ def to_a
11
+ content.map { |c| build_content_line c }.flatten
12
+ end
13
+
14
+ def add_parent(parent)
15
+ parent.add_content content
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module ObjectiveElements
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  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: 1.0.0
4
+ version: 1.1.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-23 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,6 +84,7 @@ files:
84
84
  - lib/objective_elements.rb
85
85
  - lib/objective_elements/double_tag.rb
86
86
  - lib/objective_elements/html_attributes.rb
87
+ - lib/objective_elements/shelf_tag.rb
87
88
  - lib/objective_elements/single_tag.rb
88
89
  - lib/objective_elements/version.rb
89
90
  - objective_elements.gemspec
@@ -106,8 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
107
  - !ruby/object:Gem::Version
107
108
  version: '0'
108
109
  requirements: []
109
- rubyforge_project:
110
- rubygems_version: 2.7.3
110
+ rubygems_version: 3.0.2
111
111
  signing_key:
112
112
  specification_version: 4
113
113
  summary: Build HTML without interpolating strings.