udon 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -12,5 +12,5 @@ group :development do
12
12
  gem "rcov", ">= 0"
13
13
  gem "reek", "~> 1.2.8"
14
14
  gem "roodi", "~> 2.1.0"
15
- gem "genmachine", "~> 0.2.2"
15
+ gem "genmachine", "~> 0.2.4"
16
16
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -22,18 +22,18 @@ class String
22
22
  def reset; d=dup;d.reset!;d end
23
23
  end
24
24
 
25
+ class Array
26
+ def into(v); into!(v) unless size == 0 end
27
+ def into!(v); v << self end
28
+ def reset!; self.clear end
29
+ def reset; d=dup;d.reset!;d end
30
+ end
25
31
 
26
32
  module UdonParser
27
33
  def self.parse(str) Parser.new(str).parse end
28
34
  def self.parse_file(fname) Parser.new(IO.read(fname)).parse end
29
35
 
30
36
 
31
- class UArray < Array
32
- def into(v); into!(v) unless size == 0 end
33
- def into!(v); v << self end
34
- def reset!; self.clear end
35
- def reset; d=dup;d.reset!;d end
36
- end
37
37
 
38
38
  class UHash < Hash
39
39
  def into!(v) v << self end
@@ -158,7 +158,7 @@ module UdonParser
158
158
 
159
159
  def document(p=nil,name='document')
160
160
  __state=':data_or_child'
161
- s = UArray.new
161
+ s = []
162
162
  a ||= ''
163
163
  b ||= ''
164
164
  loop do
@@ -252,12 +252,14 @@ module UdonParser
252
252
  when nl?; __i.into(a); a.into(s.c.last); __state=':ident:nl'; next
253
253
  when !eof?; __i.into(a); __state=':ident:child'; next
254
254
  end
255
+ when ':ident:idret'
256
+ @fwd=true; id=['id',s.c.pop]; id.into(s.a); __state=':ident:nxt'; next
255
257
  when ':ident'
256
258
  case
257
259
  when (eof?); @fwd=true; error('er1'); return(retstate)
258
260
  when __i==9,space?; __state=':ident:nxt'; next
259
261
  when nl?; __state=':ident:nl'; next
260
- when (__i>45&&__i<48),__i==123; @fwd=true; __state=':ident:nxt'; next
262
+ when __i==46,__i==91,__i==123; @fwd=true; __state=':ident:nxt'; next
261
263
  when !eof?; @fwd=true; __state=cstr(':ident:nameret',s); next
262
264
  end
263
265
  when ':ident:attr:val'
@@ -267,7 +269,8 @@ module UdonParser
267
269
  when ':ident:nxt'
268
270
  case
269
271
  when (eof?); @fwd=true; s.into(p); return(retstate)
270
- when (__i>45&&__i<48),__i==123; error('nyi'); return(retstate)
272
+ when __i==91; __state=idstr(':ident:idret',s); next
273
+ when __i==46; error('nyi'); return(retstate)
271
274
  when nl?; __state=':ident:nl'; next
272
275
  when __i==9,space?; next
273
276
  when !eof?; @fwd=true; __state=cstr(':ident:a_or_c',s); next
@@ -290,63 +293,96 @@ module UdonParser
290
293
  end
291
294
 
292
295
  def cstr(retstate,p=nil,name='cstr')
296
+ nst=0
293
297
  __state=':first'
294
- s = UArray.new
298
+ s = []
295
299
  a ||= ''
296
300
  b ||= ''
297
301
  loop do
298
302
  __i = nextchar
299
303
  case __state
300
- when ':bt-dat'
304
+ when ':delimited:donecheck'
305
+ case
306
+ when (nst==0); @fwd=true; a.into!(p); return(retstate)
307
+ when !eof?; @fwd=true; ')'.into(a); __state=':delimited'; next
308
+ end
309
+ when ':delimited'
301
310
  case
302
- when __i==96; a.into!(p); return(retstate)
311
+ when __i==92; __i.into(b); __state=':delimited:esc'; next
312
+ when __i==40; __i.into(a); nst+=1; next
313
+ when __i==41; nst-=1; __state=':delimited:donecheck'; next
303
314
  when !eof?; __i.into(a); next
304
315
  end
305
316
  when ':first'
306
317
  case
307
318
  when (eof?); @fwd=true; a.into!(p); return(retstate)
308
- when __i==34; __state=':dq-dat'; next
309
- when __i==39; __state=':sq-dat'; next
310
- when __i==96; __state=':bt-dat'; next
319
+ when __i==40; nst=1; __state=':delimited'; next
311
320
  when nl?,(__i>8&&__i<11),space?; @fwd=true; a.into!(p); return(retstate)
312
- when !eof?; __i.into(a); __state=':dat'; next
321
+ when !eof?; __i.into(a); __state=':normal'; next
313
322
  end
314
- when ':dq-dat:esc'
323
+ when ':normal'
315
324
  case
316
- when __i==116; "\t".into(a); __state=':dq-dat'; next
317
- when __i==110; "\n".into(a); __state=':dq-dat'; next
318
- when __i==114; "\r".into(a); __state=':dq-dat'; next
319
- when __i==102; "\f".into(a); __state=':dq-dat'; next
320
- when __i==98; "\b".into(a); __state=':dq-dat'; next
321
- when __i==97; "\a".into(a); __state=':dq-dat'; next
322
- when __i==101; "\e".into(a); __state=':dq-dat'; next
323
- when __i==115; "\s".into(a); __state=':dq-dat'; next
324
- when !eof?; __i.into(a); __state=':dq-dat'; next
325
+ when (eof?); @fwd=true; a.into!(p); return(retstate)
326
+ when __i==92; __i.into(b); __state=':normal:esc'; next
327
+ when nl?,(__i>8&&__i<11),space?,__i==46,__i==91; @fwd=true; a.into!(p); return(retstate)
328
+ when !eof?; __i.into(a); next
325
329
  end
326
- when ':sq-dat'
330
+ when ':normal:esc'
327
331
  case
328
- when __i==92; __state=':sq-dat:esc'; next
329
- when __i==39; a.into!(p); return(retstate)
330
- when !eof?; __i.into(a); next
332
+ when (eof?); @fwd=true; b.into(a); a.into!(p); return(retstate)
333
+ when __i==9,space?,__i==46,__i==91; __i.into(a); __state=':normal'; next
334
+ when !eof?; __i.into(b); b.into(a); __state=':normal'; next
331
335
  end
332
- when ':dq-dat'
336
+ when ':delimited:esc'
333
337
  case
334
- when __i==92; __state=':dq-dat:esc'; next
335
- when __i==34; a.into!(p); return(retstate)
336
- when !eof?; __i.into(a); next
338
+ when __i==92; __state=':delimited:esc:2'; next
339
+ when (__i>39&&__i<42); __i.into(a); __state=':delimited'; next
340
+ when !eof?; __i.into(b); b.into(a); __state=':delimited'; next
337
341
  end
338
- when ':sq-dat:esc'
342
+ when ':delimited:esc:2'
339
343
  case
340
- when __i==92; __i.into(a); __state=':sq-dat'; next
341
- when __i==39; __i.into(a); __state=':sq-dat'; next
342
- when !eof?; __i.into(b); '\\'.into(a); b.into(a); __state=':sq-dat'; next
344
+ when (__i>39&&__i<42); @fwd=true; b.into(a); __state=':delimited'; next
345
+ when !eof?; __i.into(b); '\\'.into(a); b.into(a); __state=':delimited'; next
343
346
  end
344
- when ':dat'
347
+ end
348
+ error("Unexpected \"#{[__i].pack("U*")}\"")
349
+ @fwd = true
350
+ return
351
+ end
352
+ end
353
+
354
+ def idstr(retstate,p=nil,name='idstr')
355
+ nst=1
356
+ __state=':delimited'
357
+ s = []
358
+ a ||= ''
359
+ b ||= ''
360
+ loop do
361
+ __i = nextchar
362
+ case __state
363
+ when ':delimited:donecheck'
345
364
  case
346
- when (eof?); @fwd=true; a.into!(p); return(retstate)
347
- when nl?,(__i>8&&__i<11),space?; @fwd=true; a.into!(p); return(retstate)
365
+ when (nst==0); @fwd=true; a.into!(p); return(retstate)
366
+ when !eof?; @fwd=true; ']'.into(a); __state=':delimited'; next
367
+ end
368
+ when ':delimited'
369
+ case
370
+ when __i==92; __i.into(b); __state=':delimited:esc'; next
371
+ when __i==91; __i.into(a); nst+=1; next
372
+ when __i==93; nst-=1; __state=':delimited:donecheck'; next
348
373
  when !eof?; __i.into(a); next
349
374
  end
375
+ when ':delimited:esc'
376
+ case
377
+ when __i==92; __state=':delimited:esc:2'; next
378
+ when __i==91,__i==93; __i.into(a); __state=':delimited'; next
379
+ when !eof?; __i.into(b); b.into(a); __state=':delimited'; next
380
+ end
381
+ when ':delimited:esc:2'
382
+ case
383
+ when __i==91,__i==93; @fwd=true; b.into(a); __state=':delimited'; next
384
+ when !eof?; __i.into(b); '\\'.into(a); b.into(a); __state=':delimited'; next
385
+ end
350
386
  end
351
387
  error("Unexpected \"#{[__i].pack("U*")}\"")
352
388
  @fwd = true
@@ -18,7 +18,7 @@
18
18
 
19
19
  Block comments
20
20
  +-----------------+-----------------+-----+-----------------+------------------------+
21
- | comment(retstate)::U | | | ibase=$indent+1 | :first:ws |
21
+ | comment(retstate)::U | | | ibase=$indent+1 | :first:ws |
22
22
  : : : : ipar=$indent : :
23
23
  +-----------------+-----------------+-----+-----------------+------------------------+
24
24
  | :first:ws | [ \t] | >> | ibase += 1 | :first:ws |
@@ -45,16 +45,19 @@
45
45
  | :ident | {eof?} | | error('er1') | <retstate> |
46
46
  | :ident | [ \t] | >> | | :ident:nxt |
47
47
  | :ident | [\n] | >> | | :ident:nl |
48
- | :ident | [./{] | | | :ident:nxt |
48
+ | :ident | [.{\[] | | | :ident:nxt |
49
49
  | :ident | . | | | cstr(:ident:nameret) |
50
50
  | :ident:nameret | | | s.name>> | :ident:nxt |
51
51
  : : : : s.c.pop>>s.name : :
52
52
  +-----------------+-----------------+-----+-----------------+------------------------+
53
53
  | :ident:nxt | {eof?} | | s>>p | <retstate> |
54
- | :ident:nxt | [./{] | >> | error('nyi') | <retstate> |
54
+ | :ident:nxt | [\[] | >> | | idstr(:ident:idret) |
55
+ | :ident:nxt | [.] | >> | error('nyi') | <retstate> |
55
56
  | :ident:nxt | [\n] | >> | | :ident:nl |
56
57
  | :ident:nxt | [ \t] | >> | | :ident:nxt |
57
58
  | :ident:nxt | . | | | cstr(:ident:a_or_c) |
59
+ | :ident:idret | | | id=['id',s.c.pop] | :ident:nxt |
60
+ : : : : id>>s.a : : # two lines here because of genmachine defect
58
61
  +-----------------+-----------------+-----+-----------------+------------------------+
59
62
  | :ident:nl | {eof?} | | error('er3') | <retstate> |
60
63
  | :ident:nl | [ \t] | >> | | :ident:nl |
@@ -81,41 +84,52 @@
81
84
 
82
85
  Basic Control Strings
83
86
  +-----------------+-----------------+-----+-----------------+------------------------+
84
- | cstr(retstate) | | | | :first |
87
+ | cstr(retstate) | | | nst=0 | :first |
85
88
  | :first | {eof?} | | a>>>p | <retstate> |
86
- | :first | ["] | >> | | :dq-dat |
87
- | :first | ['] | >> | | :sq-dat |
88
- | :first | [`] | >> | | :bt-dat |
89
+ | :first | [(] | >> | nst=1 | :delimited |
89
90
  | :first | [ \t\n] | | a>>>p | <retstate> |
90
- | :first | . | >>a | | :dat |
91
- +-----------------+-----------------+-----+-----------------+------------------------+
92
- | :dat | {eof?} | | a>>>p | <retstate> |
93
- | :dat | [ \t\n] | | a>>>p | <retstate> |
94
- | :dat | . | >>a | | :dat |
95
- +-----------------+-----------------+-----+-----------------+------------------------+
96
- | :dq-dat | [\\] | >> | | :dq-dat:esc |
97
- | :dq-dat | ["] | >> | a>>>p | <retstate> |
98
- | :dq-dat | . | >>a | | :dq-dat |
99
- +-----------------+-----------------+-----+-----------------+------------------------+
100
- # TODO: move these to a separate metachar function?
101
- | :dq-dat:esc | [t] | >> | "\t">>a | :dq-dat |
102
- | :dq-dat:esc | [n] | >> | "\n">>a | :dq-dat |
103
- | :dq-dat:esc | [r] | >> | "\r">>a | :dq-dat |
104
- | :dq-dat:esc | [f] | >> | "\f">>a | :dq-dat |
105
- | :dq-dat:esc | [b] | >> | "\b">>a | :dq-dat |
106
- | :dq-dat:esc | [a] | >> | "\a">>a | :dq-dat |
107
- | :dq-dat:esc | [e] | >> | "\e">>a | :dq-dat |
108
- | :dq-dat:esc | [s] | >> | "\s">>a | :dq-dat |
109
- | :dq-dat:esc | . | >>a | | :dq-dat |
110
- +-----------------+-----------------+-----+-----------------+------------------------+
111
- | :sq-dat | [\\] | >> | | :sq-dat:esc |
112
- | :sq-dat | ['] | >> | a>>>p | <retstate> |
113
- | :sq-dat | . | >>a | | :sq-dat |
114
- +-----------------+-----------------+-----+-----------------+------------------------+
115
- | :sq-dat:esc | [\\] | >>a | | :sq-dat |
116
- | :sq-dat:esc | ['] | >>a | | :sq-dat |
117
- | :sq-dat:esc | . | >>b | '\\'>>a; b>>a | :sq-dat |
118
- +-----------------+-----------------+-----+-----------------+------------------------+
119
- | :bt-dat | [`] | >> | a>>>p | <retstate> |
120
- | :bt-dat | . | >>a | | :bt-dat |
91
+ | :first | . | >>a | | :normal |
92
+ +-----------------+-----------------+-----+-----------------+------------------------+
93
+ | :delimited | [\\] | >>b | | :delimited:esc |
94
+ | :delimited | [(] | >>a | nst+=1 | :delimited |
95
+ | :delimited | [)] | >> | nst-=1 | :delimited:donecheck |
96
+ | :delimited | . | >>a | | :delimited |
97
+ +-----------------+-----------------+-----+-----------------+------------------------+
98
+ | :delimited:donecheck | {nst==0} | | a>>>p | <retstate> |
99
+ | :delimited:donecheck | . | | ')'>>a | :delimited |
100
+ +-----------------+-----------------+-----+-----------------+------------------------+
101
+ | :delimited:esc | [\\] | >> | | :delimited:esc:2 |
102
+ | :delimited:esc | [()] | >>a | | :delimited | # Escaped parenths
103
+ | :delimited:esc | . | >>b | b>>a | :delimited |
104
+ +-----------------+-----------------+-----+-----------------+------------------------+
105
+ | :delimited:esc:2 | [()] | | b>>a | :delimited | # Escaped backslash before parenths -> \ and actual (
106
+ | :delimited:esc:2 | . | >>b | '\\'>>a; b>>a | :delimited | # Just two backslashes, moving on
107
+ +-----------------+-----------------+-----+-----------------+------------------------+
108
+ | :normal | {eof?} | | a>>>p | <retstate> |
109
+ | :normal | [\\] | >>b | | :normal:esc |
110
+ | :normal | [\[\s\n\t.] | | a>>>p | <retstate> |
111
+ | :normal | . | >>a | | :normal |
112
+ +-----------------+-----------------+-----+-----------------+------------------------+
113
+ | :normal:esc | {eof?} | | b>>a; a>>>p | <retstate> |
114
+ | :normal:esc | [\[\s\t.] | >>a | | :normal |
115
+ | :normal:esc | . | >>b | b>>a | :normal |
116
+ +-----------------+-----------------+-----+-----------------+------------------------+
117
+
118
+ ID Strings - like cstr but with square brackets
119
+ +-----------------+-----------------+-----+-----------------+------------------------+
120
+ | idstr(retstate) | | | nst=1 | :delimited |
121
+ | :delimited | [\\] | >>b | | :delimited:esc |
122
+ | :delimited | [\[] | >>a | nst+=1 | :delimited |
123
+ | :delimited | [\]] | >> | nst-=1 | :delimited:donecheck |
124
+ | :delimited | . | >>a | | :delimited |
125
+ +-----------------+-----------------+-----+-----------------+------------------------+
126
+ | :delimited:donecheck | {nst==0} | | a>>>p | <retstate> |
127
+ | :delimited:donecheck | . | | ']'>>a | :delimited |
128
+ +-----------------+-----------------+-----+-----------------+------------------------+
129
+ | :delimited:esc | [\\] | >> | | :delimited:esc:2 |
130
+ | :delimited:esc | [\[\]] | >>a | | :delimited | # Escaped parenths
131
+ | :delimited:esc | . | >>b | b>>a | :delimited |
132
+ +-----------------+-----------------+-----+-----------------+------------------------+
133
+ | :delimited:esc:2 | [\[\]] | | b>>a | :delimited | # Escaped backslash before parenths -> \ and actual [
134
+ | :delimited:esc:2 | . | >>b | '\\'>>a; b>>a | :delimited | # Just two backslashes, moving on
121
135
  +-----------------+-----------------+-----+-----------------+------------------------+
@@ -86,10 +86,20 @@ def randstr(avg_length, char_dists = nil)
86
86
  end
87
87
  end
88
88
  end
89
+ return fix_utf8(ret)
90
+ end
91
+
92
+ def fix_utf8(str)
89
93
  # (To fix iconv bug: cr http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/ )
90
- ret = ret + ' '
91
- Iconv.iconv('UTF-8//IGNORE', 'UTF-8', ret)
92
- return ret[0..-2]
94
+ str = str + ' '
95
+ Iconv.iconv('UTF-8//IGNORE', 'UTF-8', str)
96
+ return str[0..-2]
97
+ end
98
+
99
+ def udon_safe(str)
100
+ str.gsub! /^(\s*)(#|\|)/u, '\\1\\\\\2'
101
+ str.gsub! /(\||!)\{/u, '\\1{{'
102
+ str + "\n"
93
103
  end
94
104
 
95
105
  class MiniTest::Unit::TestCase
@@ -2,7 +2,6 @@ require 'helper'
2
2
  $KCODE='U'
3
3
 
4
4
  class TestUdon < MiniTest::Unit::TestCase
5
- TRIGGER_UDON = /(^\s*(#|\||<).*$|<\||<:)/u
6
5
  WHITESPACE = " \t\n\r"
7
6
 
8
7
  def test_blank_documents
@@ -19,7 +18,7 @@ class TestUdon < MiniTest::Unit::TestCase
19
18
 
20
19
  def test_passthru_documents
21
20
  (0..3).each do
22
- s = randstr(100).gsub(TRIGGER_UDON,'')
21
+ s = udon_safe(randstr(100))
23
22
  ##############
24
23
  assert_equal s, s.udon.join('')
25
24
  ##############
@@ -62,8 +61,8 @@ class TestUdon < MiniTest::Unit::TestCase
62
61
  end
63
62
 
64
63
  def test_block_comment_in_passthru
65
- leading = randstr(200).gsub(TRIGGER_UDON,'') + "\n"
66
- following = randstr(200).gsub(TRIGGER_UDON,'')
64
+ leading = udon_safe(randstr(200))
65
+ following = udon_safe(randstr(200))
67
66
  comment = <<-COMMENT
68
67
  # the-comment
69
68
  and back to normal
@@ -92,55 +91,241 @@ class TestUdon < MiniTest::Unit::TestCase
92
91
  ##############
93
92
  end
94
93
 
95
- def test_node_name
96
- ##############
97
- assert_equal 'hello-there!', '|hello-there!'.udon[0].name
98
- assert_equal "hello there!\t", '|"hello there!\t"'.udon[0].name
99
- assert_equal 'hello there!\t', "|'hello there!\\t'".udon[0].name
100
- assert_equal 'hello there!\t', '|`hello there!\t`'.udon[0].name
101
- ##############
94
+ def test_node_name_undelimited_cstring
95
+ (0..20).each do
96
+ name = randstr(50).unpack("U*")
97
+ name = name - [0x0b, 0x0c, 0x85, 0x2028, 0x2029, 0x0a, 0x0d] # No newlines
98
+ name = name - [0x20, 0x09] # No spaces
99
+ name = name - '[|.'.unpack("U*") # No [ or |
100
+ name << '-'[0] if name.last == '\\'[0] # Make sure it doesn't end with a \
101
+ name.unshift('-'[0]) if name.first == '{'[0] # Make sure it doesn't start with a {
102
+ name.unshift('-'[0]) if name.first == '('[0] # Make sure it doesn't start with a (
103
+ name = name.pack("U*")
104
+ name = 'node' if name.length == 0 # Make sure it is not blank
105
+ assert_equal name, "|#{name} a".udon[0].name
106
+ end
102
107
  end
103
108
 
104
- def test_node_name_with_inline_children
105
- ##############
106
- assert_equal 'hello-there!', '|hello-there! c'.udon[0].name
107
- assert_equal "hello there!\t", '|"hello there!\t" c'.udon[0].name
108
- assert_equal 'hello there!\t', "|'hello there!\\t' c".udon[0].name
109
- assert_equal 'hello there!\t', '|`hello there!\t` c'.udon[0].name
110
- ##############
109
+ def test_node_name_delimited_cstring
110
+ (0..20).each do
111
+ name = randstr(50).gsub(/\(|\)/u,'').scan(/./u)
112
+ # Inject some balanced parenthases
113
+ (0..rand(10)).each do
114
+ pos1 = rand(name.size)
115
+ pos2 = rand(name.size - pos1) + pos1 + 1
116
+ unless name[pos1-1]=="\\" || name[pos2-1]=="\\"
117
+ name = name.insert(pos2,')').insert(pos1,'(')
118
+ end
119
+ end
120
+ name << ' ' if name.last=='\\'
121
+ name = name.join('')
122
+ assert_equal name, "|(#{name}) a".udon[0].name
123
+ end
111
124
  end
112
125
 
113
- def test_node_name_with_nextline_children
114
- ##############
115
- assert_equal 'hello-there!', "|hello-there!\nc".udon[0].name
116
- assert_equal "hello there!\t", "|\"hello there!\\t\"\nc".udon[0].name
117
- assert_equal 'hello there!\t', "|'hello there!\\t'\nc".udon[0].name
118
- assert_equal 'hello there!\t', "|`hello there!\\t`\nc".udon[0].name
119
- ##############
126
+ def test_node_id_after_name
127
+ assert_equal 'my id!', "|this-node[my id!]".udon[0].a['id']
120
128
  end
121
129
 
122
- SCRATCH=<<-SCRATCH
130
+ =begin
123
131
 
124
- |one # Sets ipar
125
- a:b # no base
126
- c:d # no base
127
- e:f # no base
128
- g h i # sets base to indent
132
+ --------------------------- TODO
133
+ ---- MISC
134
+ [ ] - Change passthru tests so they replace udon triggers w/ escaped triggers
135
+ instead of removing the line.
129
136
 
130
- |one blah # Sets ipar to indent
131
- asdf # sets base to indent
137
+ ---- TOP LEVEL DATA
138
+ [ ] - Lines beginning with `|` or `#` must be escaped
139
+ [ ] - Any internal `|{...` or `!{...` must be escaped by doubling the { to
140
+ pass it through literally
132
141
 
133
- # SO: first non-ident non-inline child sets base (or its own ipar)
142
+ ---- BLOCK-COMMENTS
143
+
144
+ ---- BASIC DATA (children)
145
+ [ ] - Rules for top level data apply
146
+ [ ] - Started with a `| `
147
+ [ ] - Leading whitespace for first node is not retained and sets base
148
+ [ ] - If the data is on the same line as the node began, any isolated hash
149
+ marks it wants to retain also need to be escaped or they become EOL
150
+ comments.
151
+ [ ] - Full embeds
152
+
153
+ ---- SPECIAL DATA children
154
+ [ ] - Special Basic `|'` -- Same as basic but no EOL comments and can have
155
+ leading space.
156
+ [ ] - Special String `|"`
157
+ [ ] - Metachars
158
+ [ ] - Full embeds
159
+
160
+ ---- DATA NODES
161
+ [d] - Triggered with '|'
162
+ [d] - (Inline) Name (control-string)
163
+ [ ] - Inline ID (bracketed-string - like control-string but w/ required square delims)
164
+ [ ] - Nextline ID
165
+ [ ] - Inline Tags (control-strings starting with '.')
166
+ [ ] - Nextline Tags
167
+ [ ] - Inline attributes no whitespace values
168
+ [ ] - Inline attributes w/ values w/ whitespaces
169
+ [ ] - Inline EOL comments
170
+ [ ] -
171
+
172
+ --------------------------- NOTES
173
+ ---- EOL COMMENTS
174
+ * Only available on lines that begin w/ `|` or `:` unless it's an
175
+ anonymous (!') pipe.
176
+ * The hash mark must have a space before it
177
+
178
+ ---- BUILT-IN
179
+
180
+
181
+
182
+ ---------------------------- SCRATCH
183
+ # Normal udon-level comment
184
+ |# Application-defined block comment (such as html comments)
185
+ !#
186
+
187
+ First class data; only embeds allowed, no inline comments, no metacharacters
188
+ First class => (document text) == `!'` == `| `
189
+ CString => (...) in ident == `!"` well, `!{" "}`
190
+
191
+ |something :one two| three
192
+ four
193
+
194
+ *** Attribute values must escape their pipes if not delimited
195
+ *** Allow parenthasese to delimit values w/ whitespaces
196
+ *** Attribute values extend to next `\s:`, `|`, or newline, or are delimited by () (balanced inner)
197
+ *** To start child text w/ whitespace, escape the first whitespace:
198
+ |blah \ I'm indented quite a bit
199
+
200
+
201
+ * Make sure attributes can easily be ruby symbols - start with :
202
+ - ::blahspace:url http://example.com:80:
203
+
204
+ |node :a1 v1
205
+ :'a 2' v 2
206
+
207
+
208
+ |node >|another asdf:2 > bcdg:2
209
+
210
+
211
+ |node normal children
212
+ blah blah blah
213
+
214
+ |(another-node kajsdf jewifowe) asdf
215
+ normal children blah blah blah
134
216
 
217
+ |yet-another-node
218
+ !"child with some metachars \n \t to think about
219
+ but no need to have an ending quote, because that's determined by the
220
+ indent
221
+ !'and another child !{`with an embedded string`}
135
222
 
136
223
 
137
- |asdf
138
- `howdy fejw ioafj weifj <:oawj:> fa weoi`: kvjjfejiwo
139
- `howdy fejw ioafj weifj <:oawj:> fa weoi` kvjjfejiwo
224
+ first class text
225
+ |node also first class text
226
+ just with a different baseline
227
+ (at least once it gets to the line above this one)
228
+ and when I want something special I just do an
229
+ embedded !{'something or other'}
140
230
 
141
231
 
232
+ !'blah blah blah'
142
233
 
234
+ |div.red.ugly.blah[leftcol]
235
+ |.blah[heya].torn.(fejwio fjeiwo).jfeiwo.(j fjeiwo fejiofjwe f)
236
+ |[geo].trans
237
+
238
+ |===[hm jfeiwo fei]
239
+
240
+ |(t > fjeio:[blah=feio], fjeiwo)[13th of id]
241
+ :(something this way) (george the carpenter)
242
+
243
+ --OR--
244
+
245
+
246
+ |my-awesome-node (The blah and blah) # Comments allowed because child is inline
247
+
248
+ command-string:
249
+ NAME, (.)TAGS, (*)ID, ATTRIBUTE-NAMES(:), & (sometimes) ATTRIBUTE-VALUES
250
+ - NOT available for children... children that start with a paren need to escape it(?)
251
+ - no whitespace if no delimiter or escaped spaces (usually single word)
252
+ - value embeds available; must evaluate to a string
253
+ - delimited by () - can contain them also as long as they're balanced
254
+ - preserves whitespace(?)
255
+
256
+ value-string:
257
+ VALUE-EMBEDS,
258
+
259
+
260
+ | -> node (values accumulate)
261
+ : -> attribute (values override)
262
+ ! -> directive - inject result
263
+ !- -> directive, ignore result
264
+ (.)-> text (or, if inline, possibly simple-value)
265
+
266
+ |{...}
267
+ !{...}
268
+ !{-...} ignore result
269
+ !{'...'}
270
+ !{"..."}
271
+ !{`...`}
272
+
273
+ |name[id].tag.tag2
274
+
275
+ |hello
276
+ I hope this message finds you well, Mr. !{$blah}
277
+ !urlencode
278
+
279
+ INLINE
280
+ |asdf |bcal
281
+ |child of bcal always
282
+
283
+ |asdf |bcal this
284
+ sentence continues here below
285
+
286
+ |asdf |bcal but
287
+ this is now a sibling (obviously) of |asdf
288
+
289
+ |house
290
+ :fixtures
291
+ :south 12
292
+ :north 14
293
+ :color
294
+ :summer green # Comment allowed
295
+ :winter
296
+ white # Comment not allowed - this is part of the text
297
+ :something\ else blah
298
+ simple value
299
+ and some more
300
+ muahaha
301
+ |something
302
+ :strange
303
+ |good[1]
304
+ |good[2]
305
+
306
+ |house
307
+
308
+
309
+
310
+ INLINES
311
+ * Goes depth-wise `|a |b |c d` == `<|a <|b <|c d|>|>|>`
312
+ * Carries over to the next line (indented children of `|a |b |c` are children of `|c`
313
+
314
+
315
+
316
+ ----------------------------
317
+
318
+ |one # Sets ipar
319
+ a: b # no base
320
+ c: d # no base
321
+ e: f # no base
322
+ g h i # sets base to indent
323
+
324
+ |one blah # Sets ipar to indent
325
+ asdf # sets base to indent
326
+
327
+ # SO: first non-ident non-inline child sets base (or its own ipar)
143
328
 
144
- SCRATCH
329
+ =end
145
330
 
146
331
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{udon}
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joseph Wecker"]
12
- s.date = %q{2011-08-20}
12
+ s.date = %q{2011-08-23}
13
13
  s.description = %q{Parse and generate udon, inspired by zml, haml, json, and more.}
14
14
  s.email = %q{joseph.wecker@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -47,7 +47,7 @@ Gem::Specification.new do |s|
47
47
  s.add_development_dependency(%q<rcov>, [">= 0"])
48
48
  s.add_development_dependency(%q<reek>, ["~> 1.2.8"])
49
49
  s.add_development_dependency(%q<roodi>, ["~> 2.1.0"])
50
- s.add_development_dependency(%q<genmachine>, ["~> 0.2.2"])
50
+ s.add_development_dependency(%q<genmachine>, ["~> 0.2.4"])
51
51
  else
52
52
  s.add_dependency(%q<minitest>, [">= 0"])
53
53
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -55,7 +55,7 @@ Gem::Specification.new do |s|
55
55
  s.add_dependency(%q<rcov>, [">= 0"])
56
56
  s.add_dependency(%q<reek>, ["~> 1.2.8"])
57
57
  s.add_dependency(%q<roodi>, ["~> 2.1.0"])
58
- s.add_dependency(%q<genmachine>, ["~> 0.2.2"])
58
+ s.add_dependency(%q<genmachine>, ["~> 0.2.4"])
59
59
  end
60
60
  else
61
61
  s.add_dependency(%q<minitest>, [">= 0"])
@@ -64,7 +64,7 @@ Gem::Specification.new do |s|
64
64
  s.add_dependency(%q<rcov>, [">= 0"])
65
65
  s.add_dependency(%q<reek>, ["~> 1.2.8"])
66
66
  s.add_dependency(%q<roodi>, ["~> 2.1.0"])
67
- s.add_dependency(%q<genmachine>, ["~> 0.2.2"])
67
+ s.add_dependency(%q<genmachine>, ["~> 0.2.4"])
68
68
  end
69
69
  end
70
70
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: udon
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joseph Wecker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-20 00:00:00 -07:00
18
+ date: 2011-08-23 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -116,12 +116,12 @@ dependencies:
116
116
  requirements:
117
117
  - - ~>
118
118
  - !ruby/object:Gem::Version
119
- hash: 19
119
+ hash: 31
120
120
  segments:
121
121
  - 0
122
122
  - 2
123
- - 2
124
- version: 0.2.2
123
+ - 4
124
+ version: 0.2.4
125
125
  name: genmachine
126
126
  version_requirements: *id007
127
127
  prerelease: false