objective_elements 0.1.1 → 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: 38f809fad81753971aea9a020e001e734799fd78853c819885513971ed428b62
4
- data.tar.gz: 7d619307a7d4fc03e9e76fb2eeccd820b7fdde4edd44085bebde10923e69bf8f
3
+ metadata.gz: e11c40fa73e065603e77081aef6c8df5e0a097a2ac47e0a5c2a69b04633aebbb
4
+ data.tar.gz: 7d9568d439b669be90cd8158d1078d339c0215720fee13c6a5e10561516881c9
5
5
  SHA512:
6
- metadata.gz: a1a4a36ada92b3c8a69ba223c1d60f99cd82c9d35ae23be6035c253d7f4efb3cd961acc85482d4dcd241fb277ba86cb694ea0028a585bf7352aaf4788fa39f38
7
- data.tar.gz: 92fe704f0977dc18660b1bfe79a7bd95f43c0b3332b10f5f49b975a17d314403d6899194e274eeed30804c673d977a5507911c36a6eae81d446c4aa1c0f2ca48
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 no runtime dependencies beyond bundler
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
- Note: This gem doesn't actually know any HTML. It just knows how it should be formatted.
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
- * Attributes are a Hash, Content is an array. Define them on initialization, or later on.
12
+ * Add attributes & content in one of a few ways. Nest tags infinitely.
14
13
 
15
- * Render it with `.to_s`. Get normal HTML without the pain.
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
- spaces you only need sometimes, it turns into a horrible mess.
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 just hammer through it and end up with code like this:
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 and content however you like:
61
- p.add_attributes class: 'stumpy grumpy', id: 'the-ugly-one'
62
- p.add_attributes class: 'slimy'
63
- p.add_content 'Bippity Boppity Boo!'
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
- # Bippity Boppity Boo!
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">Bippity Boppity Boo!</p>
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, meaning
86
- # cool things like this work:
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
- # Bippity Boppity Boo!
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
- - coming eventually. It'll be a gem and a require. For now, you can load it from this repo in your gemfile.
98
+ ```ruby
99
+ # Gemfile
99
100
 
100
- ## Usage
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` is a
114
- self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is the other kind.
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
- - element:
119
- **String**, mandatory. What kind of tag it is; such as 'img' or 'hr'
120
- - attributes:
121
- **Hash** `{symbol: array or string}`, optional. Example: `{class: 'myclass plaid'}` or `{class:
122
- ['myclass', 'plaid']}`
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(hash)` - Deletes all attributes, replaces with supplied argument if given.
148
+ `.reset_attributes(new)` - Deletes all attributes, calls add_attributes on supplied argument if
149
+ given.
131
150
 
132
- `.add_attributes(hash)` - Appends attributes instead of overwriting them.
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
- Each element in the array corresponds to at least one line of HTML; multiline child tags will
146
- get as many lines as they need (like you'd expect).
163
+ #### content
147
164
 
148
- Child elements are not rendered until the parent is rendered, meaning you can access and
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
- - oneline:
152
- **Boolean**, optional, defaults to false. When true, the entire element and its content will be
153
- rendered as a single line. Useful for anchor tags and list items.
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
- - You can initialize it with content.
183
+ `DoubleTag.new(element, attributes: {}, oneline: false, content: [])` - You can initialize it with
184
+ content.
159
185
 
160
- `add_content(anything)`
161
- - Smart enough to handle both arrays and not-arrays without getting dorked up.
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
- - You can modify the content array directly if you like. If you're just adding items, you should use
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
- - Mostly used internally, but if you want an array of strings, each element a line with appropriate
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 actually doesn't know a single HTML element on its own, so it does nothing to ensure that
201
- your HTML is valid. Garbage in, garbage out.
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
- do this (with `oneline: true` on the strong tag):
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
- It doesn't affect how the browser will render it, but it might bug you if you're particular about
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
- will not be pretty. I advise against it.
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
- TODO list.
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
- @attributes.merge! formatted_new do |_key, oldval, newval|
34
- oldval.concat newval
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
@@ -1,3 +1,3 @@
1
1
  module ObjectiveElements
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
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: 0.1.1
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-01 00:00:00.000000000 Z
11
+ date: 2018-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler