uga_uga 0.1.0 → 1.0.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
  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