uga_uga 0.1.0 → 1.0.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
  SHA1:
3
- metadata.gz: 4e475b295a76d004debe5c9f8b5f1ce5bb44b0af
4
- data.tar.gz: eccdc212ac1896218ad9491fee0b8754694c5703
3
+ metadata.gz: aa553dc1ddf1359cba861ec14ad679a176b3f106
4
+ data.tar.gz: 79285eccf41f266a17c753a30bdb0ba793ec4a32
5
5
  SHA512:
6
- metadata.gz: 00f18ca1b2ada9fefcdae9a6a860ea46fd1cd14678ffaa1142c4ed0a07f114571a138d2ee54c9e2bbe48180c80c7caa917803c74add98c18585be4e2fdad35d7
7
- data.tar.gz: 348bd55a6fcce453c15e138fdfb0b97895c8b6fc3ef6da858787430675664d4ba2085c0566fbc6e5984ad7061d8f43ee625e74bdbff3cdff061936bd7ddb0532
6
+ metadata.gz: c225b4ac370606899e767fee6f0fb8f428221590cdded199eebf54f3f15aad1c08e098f7ef89e3144472c888a01c35cc465f5de12ea48759384e1e9a16ec57a1
7
+ data.tar.gz: ed779bb2f65c9d0b6ebb5fec31e460f3efb21a5235497aee2aa4e009f010a9ff5068ce51836d300d2afa90fce606be3ef192ef527abe05f3bbb37f72de5e9a13
data/README.md CHANGED
@@ -2,7 +2,10 @@
2
2
  # Uga\_Uga
3
3
 
4
4
  Don't use this.
5
- Use [Treetop](https://github.com/nathansobo/treetop) or [OMeta](https://github.com/alexwarth/ometa-js).
5
+ Use [Parslet](http://kschiess.github.io/parslet/) or [OMeta](https://github.com/alexwarth/ometa-js).
6
+
7
+ Here is a video on creating your own external DSL:
8
+ [Writing DSL's with Parslet by Jason Garber](https://www.youtube.com/watch?v=ET_POMJNWNs)
6
9
 
7
10
  ## Installation
8
11
 
@@ -22,30 +25,25 @@ Use [Treetop](https://github.com/nathansobo/treetop) or [OMeta](https://github.c
22
25
 
23
26
  results = []
24
27
 
25
- Uga_Uga.uga code do |name, blok|
26
-
27
- case name
28
+ Uga_Uga.new code do
28
29
 
29
- when "bobby"
30
- results << "bobby was called"
31
- blok
30
+ case
32
31
 
33
- when "howie"
34
- results << "howie was called"
35
- blok
32
+ when rex?("(white*)(word) { ")
33
+ line = shift
34
+ results << "#{captures.last} was called"
35
+ {:raw=>grab_until(bracket(line, '}'))}
36
36
 
37
- when "mandel"
38
- results << "mandel was called"
39
- blok
40
-
41
- when ":funny", '"comedian"'
37
+ when rex?(" (word) { (...) } ")
38
+ results << "#{captures.first} called with #{captures.last}"
42
39
 
43
40
  else
44
- fail ArgumentError, "Command not found: #{name.inspect}"
45
- end
41
+ fail ArgumentError, "Command not found: #{l!.inspect}"
42
+
43
+ end # === case name
46
44
 
47
- end
45
+ end # === .new
48
46
 
49
- puts results.inspect
47
+ results
50
48
 
51
49
  ```
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 1.0.0
@@ -2,10 +2,14 @@
2
2
  # -*- bash -*-
3
3
  #
4
4
  #
5
- set -u -e -o pipefail
6
5
 
7
6
  action="$1"
8
7
  shift
8
+ set -u -e -o pipefail
9
+
10
+ if [[ -z "$action" ]]; then
11
+ action="watch"
12
+ fi
9
13
 
10
14
  case "$action" in
11
15
 
@@ -13,6 +17,7 @@ case "$action" in
13
17
  echo " ====================================================="
14
18
  echo ""
15
19
  echo " $ uga_uga watch"
20
+ echo " $ uga_uga watch [test args]"
16
21
  echo ""
17
22
  echo " $ uga_uga test"
18
23
  echo " $ uga_uga test name"
@@ -35,7 +40,7 @@ case "$action" in
35
40
 
36
41
  if [[ ( ! "$op" =~ "NOWRITE" ) && ( "$op" =~ "CLOSE" || "$op" =~ "WRITE" ) && ! -z "$file" ]]
37
42
  then
38
- echo ""
43
+
39
44
  if [[ "$file" == *.js* ]]; then
40
45
  echo ""
41
46
  echo "=== Runninig jshint on $path: $CHANGE"
@@ -48,10 +53,17 @@ case "$action" in
48
53
  exec $path "watch" "$@"
49
54
  fi
50
55
 
51
- if [[ "$file" == *.rb* || "$path" == *spec* ]]; then
52
- echo "=== Running tests: $@"
53
- bin/uga_uga test "$@" || true
56
+ if [[ "$path" == */explore.rb* ]]; then
57
+ cmd="bundle exec ruby "$path""
58
+ echo "=== $cmd"
59
+ $cmd || true
60
+ else
61
+ if [[ "$file" == *.rb* || "$file" == *.md* || "$path" == *spec* ]]; then
62
+ echo "=== Running tests: $@"
63
+ bin/uga_uga test "$@" || true
64
+ fi
54
65
  fi
66
+
55
67
  fi # === if file op
56
68
 
57
69
  done
@@ -1,47 +1,22 @@
1
1
 
2
2
  class Uga_Uga
3
3
 
4
- class << self
5
-
6
- def uga origin
7
- tokens = blockenize(tokenize(origin))
4
+ NEW_LINE_REGEXP = /\n/
5
+ NOTHING = ''.freeze
6
+ REX = /(\ {1,})|\(([^\)]+)\)|(.)/
7
+ REX_CACHE = {}
8
+ ZERO_OR_MORE_SPACES = /\ */
9
+ ONE_OR_MORE_SPACES = /\ +/
8
10
 
9
- case
10
- when block_given?
11
- run(tokens) do |cmd, block|
12
- yield cmd, block
13
- end
14
- else
15
- tokens
11
+ module String_Refines
12
+ refine String do
13
+ def blank?
14
+ strip.empty?
16
15
  end
17
16
  end
17
+ end
18
18
 
19
- def tokenize origin
20
- origin.split(/(\n)|((?<!\{)\{(?!\{))|((?<!\})\}(?!\}))/)
21
- end
22
-
23
- def blockenize raw
24
- tokens = raw.dup
25
- final = []
26
- stack = []
27
- current = final
28
- last = nil
29
- while t = tokens.shift
30
- case t
31
- when '{'
32
- stack << current
33
- current << (b = [])
34
- current = b
35
- when '}'
36
- current = stack.pop
37
- when ''
38
- # ignore
39
- else
40
- current << t
41
- end
42
- end # === while
43
- final
44
- end
19
+ class << self
45
20
 
46
21
  #
47
22
  # This method is used mainly used in
@@ -66,33 +41,260 @@ class Uga_Uga
66
41
  end
67
42
  end
68
43
 
69
- def run raw
70
- arr = raw.dup
71
- while t = arr.shift
44
+ def reg_exp str, *custom
45
+ i = -1
46
+ base = str.scan(REX).map { |arr|
72
47
  case
48
+ when arr[0]
49
+ ONE_OR_MORE_SPACES
50
+
51
+ when arr[1]
52
+ key = arr[1].strip
53
+
54
+ case key
55
+ when '...'
56
+ /\ *([^\)]+?)\ */
57
+
58
+ when '_'
59
+ i += 1
60
+ fail ArgumentError, "NO value set for #{i.inspect} -> #{str.inspect}" unless custom[i]
61
+ '(' + custom[i].to_s + ')'
62
+
63
+ when 'word'
64
+ /\ *([^\ \)]+)\ */
65
+
66
+ when 'white*'
67
+ /([\ ]*)/
68
+
69
+ when 'white'
70
+ /([\ ]+)/
71
+
72
+ when 'num'
73
+ /\ *([0-9\.\_\-]+)\ */
74
+
75
+ when /\A![^\!]+/
76
+ /\ *([^#{Regexp.escape key.sub('!', '')}]+)\ */
77
+
78
+ else
79
+ fail ArgumentError, "Unknown value for Regexp: #{arr[1].inspect} in #{str.inspect}"
80
+ end # === case key
73
81
 
74
- when t.is_a?(String) && arr.first.is_a?(Array)
75
- blok = arr.shift
76
- results = yield t.strip, blok
77
- if results == blok
78
- run results do |arg1, arg2|
79
- yield arg1, arg2
80
- end
82
+ when arr[2]
83
+ Regexp.escape arr[2]
84
+
85
+ else
86
+ fail ArgumentError, "#{str.inspect} -> #{REG_EXP.inspect}"
87
+ end # === case
88
+ }
89
+
90
+ if base.first == ONE_OR_MORE_SPACES
91
+ base.shift
92
+ base.unshift ZERO_OR_MORE_SPACES
93
+ end
94
+
95
+ if base.last == ONE_OR_MORE_SPACES
96
+ base.pop
97
+ base.push ZERO_OR_MORE_SPACES
98
+ end
99
+
100
+ /\A#{base.join}\Z/
101
+ end
102
+
103
+ end # === class self ===
104
+
105
+ attr_reader :stack, :line_num, :parent, :captures
106
+ def initialize str_or_arr = nil, *args
107
+ @origin = str_or_arr
108
+ @instruct = block_given? ? Proc.new : nil
109
+ @stack = []
110
+
111
+ @captures = nil
112
+ @parent = nil
113
+ file_or_number = nil
114
+
115
+ args.each { |o|
116
+ case o
117
+ when Uga_Uga
118
+ @parent = o
119
+ file_or_number ||= o.line_num
120
+
121
+ when Numeric
122
+ file_or_number = o
123
+
124
+ when String
125
+ file_or_number = o
126
+
127
+ else
128
+ fail ArgumentError, "Unknown argument: #{o.inspect}"
129
+ end
130
+ }
131
+
132
+ return unless @origin
133
+
134
+ if str_or_arr.is_a?(String)
135
+ str = str_or_arr
136
+ @lines = str_or_arr.split(NEW_LINE_REGEXP)
137
+ else
138
+ str = nil
139
+ @lines = str_or_arr
140
+ end
141
+
142
+ @origin = str_or_arr
143
+ @old = []
144
+ @line_num = if file_or_number.is_a? Numeric
145
+ file_or_number
146
+ else
147
+ contents = File.read(file_or_number || __FILE__ )
148
+ index = contents.index(str || @lines.join("\n"))
149
+ if index
150
+ contents[0,index + 1].split("\n").size
151
+ else
152
+ 1
153
+ end
154
+ end
155
+ run
156
+ end # === def uga
157
+
158
+ def rex? str, *args
159
+ key = [str,args].to_s
160
+ reg_exp = ( REX_CACHE[key] ||= Uga_Uga.reg_exp(str, *args) )
161
+ match = l!.match reg_exp
162
+ @captures = match ?
163
+ match.captures :
164
+ nil
165
+ !!match
166
+ end
167
+
168
+ def l!
169
+ @lines.first
170
+ end
171
+
172
+ private # ===============================================
173
+
174
+ def bracket l, close
175
+ index = l.index(/[^\ ]/)
176
+ "#{" " * index}#{close}"
177
+ end
178
+
179
+ def skip
180
+ throw :skip
181
+ end
182
+
183
+ def white?
184
+ l!.strip.empty?
185
+ end
186
+
187
+ def first *args
188
+ l!.split.first.split(*args).first.strip
189
+ end
190
+
191
+ def split *args
192
+ l!.split *args
193
+ end
194
+
195
+ def save_as cmd, data = nil
196
+ @stack.last[:type] = cmd
197
+ if data
198
+ @stack.<<( @stack.pop.merge(data) )
199
+ end
200
+ @stack.last
201
+ end
202
+
203
+ def shift
204
+ @old << @lines.shift
205
+ @line_num = @line_num + 1
206
+ @old.last
207
+ end
208
+
209
+ def head? str_or_rxp
210
+ rxp = if str_or_rxp.is_a?(String)
211
+ e = Regexp.escape str_or_rxp
212
+ /\A\ *#{e}/
213
+ else
214
+ str_or_rxp
81
215
  end
216
+ l![rxp]
217
+ end
82
218
 
83
- when t.is_a?(String) && (arr.first != arr.is_a?(Array))
84
- str = t.strip
85
- if !str.empty?
86
- yield str, nil
219
+ def tail? str_or_rxp
220
+ rxp = if str_or_rxp.is_a?(String)
221
+ e = Regexp.escape str_or_rxp
222
+ /#{e}\ *\z/
223
+ else
224
+ str_or_rxp
87
225
  end
226
+ l![rxp]
227
+ end
88
228
 
89
- else
90
- fail ArgumentError, "Syntax: #{t.inspect} in #{raw.join.inspect}"
229
+ def grab_all
230
+ blok = []
231
+ while !@lines.empty?
232
+ blok << shift
233
+ end
234
+
235
+ blok
236
+ end
91
237
 
238
+ def grab_all_or_until period
239
+ grab_until period, :close_optional
240
+ end
241
+
242
+ def grab_until period, *opts
243
+ new_cmd = nil
244
+ blok = []
245
+ found = false
246
+ line_num = @line_num
247
+
248
+ is_line = period.is_a?(Regexp) ? period : /\A#{Regexp.escape period}\ *\Z/
249
+
250
+ while !found && (l = shift)
251
+ if !(found =l[is_line])
252
+ blok << l
253
+ end
254
+ end
255
+
256
+ if !found && !opts.include?(:close_optional)
257
+ fail ArgumentError, "Missing from around line number: #{line_num}: #{period.inspect}\n#{blok.join "\n"}"
258
+ end
259
+
260
+ blok
261
+ end
262
+
263
+ public def run *args
264
+ return(Uga_Uga.new(*args, &@instruct)) unless args.empty?
265
+ return @stack unless @stack.empty?
266
+
267
+ while !@lines.empty?
268
+ size = @lines.size
269
+ num = line_num
270
+ catch(:skip) do
271
+ result = instance_eval(&@instruct)
272
+ if result.is_a?(Hash)
273
+ @stack << result
274
+ @stack.last[:line_num] = num
92
275
  end
93
276
  end
94
- end # === def run
277
+ shift if size == @lines.size
278
+ end
279
+
280
+ @stack.each { |h|
281
+ next if !h[:raw] || h[:done?]
282
+
283
+ if h[:type] == String
284
+ h[:output] = h[:raw].join("\n")
285
+ h.delete :raw
286
+ next
287
+ end
288
+
289
+ if h[:type] == Array
290
+ h[:output] = h[:raw]
291
+ h.delete :raw
292
+ next
293
+ end
294
+
295
+ h[:output] = Uga_Uga.new(h.delete(:raw), h[:line_num], self, &@instruct).stack
296
+ }
297
+ end # === def run
95
298
 
96
- end # === class self ===
97
299
 
98
300
  end # === class Uga_Uga ===
@@ -1,14 +1,32 @@
1
1
 
2
+
2
3
  describe :uga.inspect do
3
4
 
4
5
  it "runs" do
5
- o = Uga_Uga.uga(<<-EOF)
6
+ code = <<-EOF
6
7
  p {
7
8
  "my paragraph"
8
9
  }
9
10
  EOF
10
11
 
11
- Uga_Uga.clean(o).should == [
12
+ o = Uga_Uga.new(code) do
13
+ case
14
+ when rex?(" (word) { ")
15
+ final = {
16
+ :type =>captures.first,
17
+ :raw =>grab_until(bracket shift, '}')
18
+ }
19
+ when stack.empty?
20
+ final = {
21
+ :type=>String,
22
+ :output=>grab_all.join("\n")
23
+ }
24
+ else
25
+ fail ArgumentError, "Unknown common: #{l!}"
26
+ end
27
+ end
28
+
29
+ clean(o).should == [
12
30
  'p', ['"my paragraph"']
13
31
  ]
14
32
  end
@@ -19,20 +37,26 @@ describe :uga.inspect do
19
37
  code = (contents[/```ruby([^`]+)```/] && $1).gsub('puts ','')
20
38
 
21
39
  result = eval(code, nil, file, contents.split("\n").index('```ruby') + 1)
22
- result.should.match /bobby/
40
+
41
+ result.should == [
42
+ "bobby was called",
43
+ "howie called with :funny",
44
+ 'mandel called with "comedian"'
45
+ ]
23
46
  end # === it
24
47
 
25
48
  it "parses lines without blocks" do
26
49
  code = <<-EOF
27
- a :href => addr
28
- a :href addr
50
+ a :href => addr /a
51
+ a :href addr /a
29
52
  p { }
30
53
  EOF
31
54
 
32
- Uga_Uga.clean(Uga_Uga.uga code).
33
- should == [ "a :href => addr",
34
- "a :href addr",
35
- "p", []
55
+ clean(uga code).
56
+ should == [
57
+ :html, "a :href => addr /a",
58
+ :html, "a :href addr /a",
59
+ :css, []
36
60
  ]
37
61
  end
38
62
 
@@ -45,42 +69,16 @@ describe :uga.inspect do
45
69
  }
46
70
  EOF
47
71
 
48
- Uga_Uga.clean(Uga_Uga.uga code).
72
+ clean(uga code).
49
73
  should == [
50
- "p", [
51
- "span", [
52
- "inner", ['"my"']
74
+ :css, [
75
+ :css, [
76
+ :css, ['"my"']
53
77
  ]
54
78
  ]
55
79
  ]
56
80
  end
57
81
 
58
- it "yields the inner block" do
59
- result = []
60
- code = <<-EOF
61
- p {
62
- span {
63
- 1 {
64
- 2 {
65
- 3 { "my text" }
66
- }
67
- }
68
- }
69
- }
70
- EOF
71
-
72
- Uga_Uga.uga(code) do |cmd, code|
73
- if cmd['"']
74
- result << cmd
75
- else
76
- result << cmd.to_sym
77
- end
78
- code
79
- end
80
-
81
- result.should == [:p, :span, :'1', :'2', :'3', '"my text"']
82
- end # === it
83
-
84
82
  it "passes all text before a block start: cmd, cmd {" do
85
83
  result = []
86
84
  code = %^
@@ -89,49 +87,15 @@ describe :uga.inspect do
89
87
  }
90
88
  }
91
89
  ^
92
- Uga_Uga.uga(code) do |cmd, code|
93
- result << cmd
94
- code
95
- end
96
- result.should == ["cmd, cmd", "inner, inner"]
97
- end # === it
98
-
99
- it "yields lines without a block" do
100
- code = "
101
- br /
102
- br /
103
- p { }
104
- "
105
- result = []
106
- Uga_Uga.uga(code) do |cmd, code|
107
- result << cmd
108
- code
109
- end
110
-
111
- result.should == ['br /', 'br /', 'p']
112
- end # === it
113
-
114
- it "passes block w/original whitespace" do
115
- blok = "
116
- a
117
- a a
118
- a
119
- "
120
- code = "
121
- p {#{blok}}
122
- "
123
- result = nil
124
- Uga_Uga.uga(code) { |cmd, code| result = code.join }
125
- result.should == blok
90
+ uga(code).stack.first[:selectors]
91
+ .should == "cmd, cmd"
126
92
  end # === it
127
93
 
128
94
  it "does not parse mustaches as blocks: {{ }}" do
129
95
  code = "
130
- p {{ code }}
96
+ p { {{code}} }
131
97
  "
132
- result = nil
133
- Uga_Uga.uga(code) { |cmd, code| result = cmd }
134
- result.should == code.strip
98
+ clean(uga(code)).should == [:css, ['{{code}}']]
135
99
  end # === it
136
100
 
137
101
  end # === describe :uga
@@ -3,3 +3,106 @@ require 'Bacon_Colored'
3
3
  require 'uga_uga'
4
4
  require 'pry'
5
5
  require 'awesome_print'
6
+
7
+ module Bacon
8
+ class Context
9
+
10
+ def clean o
11
+ return o.strip if o.is_a?(String)
12
+ return o unless o.is_a?(Array) || o.is_a?(Uga_Uga)
13
+
14
+ return clean(o.stack) if o.respond_to?(:stack)
15
+
16
+ o.inject([]) do |memo, hash|
17
+ memo << hash[:type] unless hash[:type] == String
18
+ memo << clean(hash[:output])
19
+ memo
20
+ end
21
+ end
22
+
23
+ def uga *args
24
+ SAMPLE.run *args
25
+ end
26
+
27
+ end # === class Context
28
+
29
+ end # === module Bacon
30
+
31
+
32
+ SAMPLE = Uga_Uga.new do
33
+
34
+ skip if white?
35
+
36
+ case
37
+ when rex?("(white*)(...) { ") # === multi-line css
38
+ close = captures.first
39
+ shift
40
+ final = {
41
+ :type => :css,
42
+ :selectors => captures.last,
43
+ :raw => grab_until(/\A#{close}\}\ *\Z/)
44
+ }
45
+
46
+ when rex?(" (!{) {(...)} ") # === css one-liner
47
+ selectors , content = captures
48
+ shift
49
+ final = {
50
+ :type => :css,
51
+ :selectors => selectors,
52
+ :raw => [content],
53
+ :one_liner => true
54
+ }
55
+
56
+ when rex?(" String (word) ") # === Multi-line String
57
+ close = captures.first
58
+ shift
59
+ final = {
60
+ :type => String,
61
+ :output => grab_until(/\A\ *#{Regexp.escape close}\ *\Z/).join("\n")
62
+ }
63
+
64
+ when rex?(" color (word) ")
65
+ # l![/\A\ *color\ *([a-zA-Z0-9\-\_\#]+)\ *\Z/]
66
+ val = captures.first
67
+ final = {
68
+ :type => :css_property,
69
+ :name => :color,
70
+ :output=> val
71
+ }
72
+
73
+ when rex?(" id (word) ")
74
+ # l![/\A\ *id\ *([a-zA-Z0-9\-\_\#]+)\ *\Z/]
75
+ val = captures.first
76
+ final = {
77
+ :type => :id!,
78
+ :output=> val
79
+ }
80
+
81
+ else
82
+ tag = first('.')
83
+ if tail?("/#{tag}")
84
+ {:type=>:html, :tag=>tag.to_sym, :one_liner=>true, :output => shift}
85
+ else
86
+ tag = tag.to_sym
87
+ case tag
88
+ when :p, :a
89
+ line = shift
90
+ bracket = bracket(line, "/#{tag}")
91
+ final = {:type=>:html, :tag=>tag, :selector => line, :raw=>grab_until(bracket)}
92
+ final
93
+ else
94
+ if stack.empty?
95
+ {:type=>String, :raw=>grab_all}
96
+ elsif rex?(" (_) ", /\-{4,}/) # Start of multi-line string --------------------
97
+ eos = l!.rstrip
98
+ shift
99
+ {:type=>String, :raw=>grab_all_or_until(/\A#{eos}\ *|Z/)}
100
+ else
101
+ fail ArgumentError, "Unknown command: #{line_num}: #{l!.inspect}"
102
+ end
103
+ end
104
+ end
105
+
106
+ end # === case
107
+
108
+ end # === .new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uga_uga
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - da99
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-18 00:00:00.000000000 Z
11
+ date: 2015-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry