jsduck 5.0.0.beta2 → 5.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Rakefile +14 -4
  2. data/bin/jsduck +3 -1
  3. data/jsduck.gemspec +2 -2
  4. data/lib/jsduck/app.rb +8 -0
  5. data/lib/jsduck/assets.rb +3 -0
  6. data/lib/jsduck/batch_processor.rb +2 -0
  7. data/lib/jsduck/categories/class_name.rb +2 -26
  8. data/lib/jsduck/categories/factory.rb +5 -43
  9. data/lib/jsduck/columns.rb +56 -0
  10. data/lib/jsduck/doc/delimited_parser.rb +105 -0
  11. data/lib/jsduck/doc/scanner.rb +2 -1
  12. data/lib/jsduck/doc/standard_tag_parser.rb +37 -71
  13. data/lib/jsduck/guide_anchors.rb +32 -0
  14. data/lib/jsduck/guide_toc.rb +49 -0
  15. data/lib/jsduck/guides.rb +14 -32
  16. data/lib/jsduck/inline/video.rb +2 -8
  17. data/lib/jsduck/js/ast.rb +13 -305
  18. data/lib/jsduck/js/class.rb +245 -0
  19. data/lib/jsduck/js/event.rb +34 -0
  20. data/lib/jsduck/js/fires.rb +42 -0
  21. data/lib/jsduck/js/method.rb +94 -0
  22. data/lib/jsduck/js/method_calls.rb +40 -0
  23. data/lib/jsduck/js/node.rb +29 -0
  24. data/lib/jsduck/js/property.rb +64 -0
  25. data/lib/jsduck/js/{function.rb → returns.rb} +8 -3
  26. data/lib/jsduck/js/scoped_traverser.rb +42 -0
  27. data/lib/jsduck/logger.rb +13 -1
  28. data/lib/jsduck/merger.rb +34 -27
  29. data/lib/jsduck/news.rb +128 -0
  30. data/lib/jsduck/options.rb +59 -2
  31. data/lib/jsduck/params_merger.rb +47 -0
  32. data/lib/jsduck/process/accessors.rb +8 -2
  33. data/lib/jsduck/process/fires.rb +71 -0
  34. data/lib/jsduck/process/importer.rb +19 -1
  35. data/lib/jsduck/render/class.rb +11 -4
  36. data/lib/jsduck/render/signature_util.rb +14 -0
  37. data/lib/jsduck/tag/alias.rb +0 -20
  38. data/lib/jsduck/tag/alternate_class_names.rb +0 -5
  39. data/lib/jsduck/tag/cfg.rb +30 -5
  40. data/lib/jsduck/tag/class.rb +45 -2
  41. data/lib/jsduck/tag/css_mixin.rb +8 -4
  42. data/lib/jsduck/tag/css_var.rb +26 -5
  43. data/lib/jsduck/tag/default.rb +2 -8
  44. data/lib/jsduck/tag/enum.rb +7 -10
  45. data/lib/jsduck/tag/event.rb +12 -4
  46. data/lib/jsduck/tag/extends.rb +0 -6
  47. data/lib/jsduck/tag/fires.rb +53 -0
  48. data/lib/jsduck/tag/icons/cfg.png +0 -0
  49. data/lib/jsduck/tag/icons/css_mixin.png +0 -0
  50. data/lib/jsduck/tag/icons/css_var.png +0 -0
  51. data/lib/jsduck/tag/icons/event.png +0 -0
  52. data/lib/jsduck/tag/icons/method.png +0 -0
  53. data/lib/jsduck/tag/icons/property.png +0 -0
  54. data/lib/jsduck/tag/member_tag.rb +130 -0
  55. data/lib/jsduck/tag/method.rb +44 -4
  56. data/lib/jsduck/tag/param.rb +8 -60
  57. data/lib/jsduck/tag/property.rb +28 -5
  58. data/lib/jsduck/tag/tag.rb +3 -75
  59. data/lib/jsduck/tag/type.rb +1 -11
  60. data/lib/jsduck/tag_registry.rb +6 -48
  61. data/lib/jsduck/web/css.rb +8 -1
  62. data/lib/jsduck/web/data.rb +2 -1
  63. data/lib/jsduck/web/index_html.rb +1 -0
  64. data/lib/jsduck/web/member_icons.rb +43 -0
  65. data/lib/jsduck/web/search.rb +3 -2
  66. data/lib/jsduck/web/writer.rb +8 -0
  67. metadata +31 -27
  68. data/lib/jsduck/docs_code_comparer.rb +0 -44
  69. data/lib/jsduck/render/signature.rb +0 -94
  70. data/lib/jsduck/tag/autodetected.rb +0 -21
  71. data/lib/jsduck/tag/name.rb +0 -36
data/Rakefile CHANGED
@@ -159,6 +159,11 @@ class JsDuckRunner
159
159
  add_options("--comments-domain", db_name+"/"+version)
160
160
  end
161
161
 
162
+ def add_search(product, version)
163
+ add_options("--search-url", "http://support-test.sencha.com:8080/docsearch/search")
164
+ add_options("--search-domain", product+"/"+version)
165
+ end
166
+
162
167
  def add_ext4
163
168
  @options += [
164
169
  "--title", "Sencha Docs - Ext JS 4.0",
@@ -263,6 +268,7 @@ task :sdk => :sass do
263
268
  )
264
269
  runner.add_debug
265
270
  runner.add_comments('ext-js', '4')
271
+ runner.add_search('Ext JS', '4.2.0')
266
272
  runner.run
267
273
 
268
274
  system("ln -s #{EXT_BUILD} #{OUT_DIR}/extjs-build")
@@ -275,10 +281,14 @@ task :touch2 => :sass do
275
281
  "--output", OUT_DIR,
276
282
  "--config", "#{SDK_DIR}/touch/docs/config.json",
277
283
  "--examples-base-url", "touch-build/examples/production/",
278
- # "--import", "Touch 1.1:../docs.sencha.com/exports/touch-1.1",
279
- # "--import", "Touch 2.0:../docs.sencha.com/exports/touch-2.0.1",
280
- # "--import", "Touch 2.1.0:../docs.sencha.com/exports/touch-2.1.0",
281
- # "--import", "Touch 2.1.1",
284
+ # "--import", "1.1.0:../docs.sencha.com/exports/touch-1.1.0",
285
+ # "--import", "1.1.1:../docs.sencha.com/exports/touch-1.1.1",
286
+ # "--import", "2.0.0:../docs.sencha.com/exports/touch-2.0.0",
287
+ # "--import", "2.0.1:../docs.sencha.com/exports/touch-2.0.1",
288
+ # "--import", "2.1.0:../docs.sencha.com/exports/touch-2.1.0",
289
+ # "--import", "2.1.1:../docs.sencha.com/exports/touch-2.1.1",
290
+ # "--import", "2.2.0:../docs.sencha.com/exports/touch-2.2.0",
291
+ # "--import", "2.2.1",
282
292
  "--seo"
283
293
  )
284
294
 
data/bin/jsduck CHANGED
@@ -22,4 +22,6 @@ require 'jsduck/options'
22
22
 
23
23
  opts = JsDuck::Options.new
24
24
  opts.parse!(ARGV)
25
- JsDuck::App.new(opts).run
25
+ exit_code = JsDuck::App.new(opts).run
26
+
27
+ exit exit_code
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
2
2
  s.required_rubygems_version = ">= 1.3.5"
3
3
 
4
4
  s.name = 'jsduck'
5
- s.version = '5.0.0.beta2'
5
+ s.version = '5.0.0.beta3'
6
6
  s.date = Time.new.strftime('%Y-%m-%d')
7
7
  s.summary = "Simple JavaScript Duckumentation generator"
8
8
  s.description = "Documentation generator for Sencha JS frameworks"
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency 'json'
24
24
  s.add_dependency 'parallel'
25
25
  s.add_dependency 'execjs'
26
- s.add_dependency 'therubyracer', '>= 0.10.0', '< 0.11.0'
26
+ s.add_dependency 'therubyracer', '>= 0.10.0'
27
27
  s.add_dependency 'dimensions'
28
28
 
29
29
  s.add_development_dependency 'rspec'
@@ -4,6 +4,7 @@ require 'jsduck/assets'
4
4
  require 'jsduck/tag_registry'
5
5
  require 'jsduck/export_writer'
6
6
  require 'jsduck/web/writer'
7
+ require 'jsduck/logger'
7
8
 
8
9
  module JsDuck
9
10
 
@@ -15,6 +16,7 @@ module JsDuck
15
16
  end
16
17
 
17
18
  # Main App logic.
19
+ # Returns application exit code.
18
20
  def run
19
21
  parse
20
22
 
@@ -25,6 +27,12 @@ module JsDuck
25
27
  else
26
28
  generate_web_page
27
29
  end
30
+
31
+ if @opts.warnings_exit_nonzero && Logger.warnings_logged?
32
+ return 2
33
+ else
34
+ return 0
35
+ end
28
36
  end
29
37
 
30
38
  private
@@ -6,6 +6,7 @@ require 'jsduck/videos'
6
6
  require 'jsduck/examples'
7
7
  require 'jsduck/categories/factory'
8
8
  require 'jsduck/format/doc'
9
+ require 'jsduck/news'
9
10
 
10
11
  module JsDuck
11
12
 
@@ -22,6 +23,7 @@ module JsDuck
22
23
  attr_reader :videos
23
24
  attr_reader :examples
24
25
  attr_reader :categories
26
+ attr_reader :news
25
27
 
26
28
  def initialize(relations, opts)
27
29
  @relations = relations
@@ -35,6 +37,7 @@ module JsDuck
35
37
  @videos = Videos.create(@opts.videos)
36
38
  @examples = Examples.create(@opts.examples, @opts)
37
39
  @categories = Categories::Factory.create(@opts.categories_path, doc_formatter, @relations)
40
+ @news = News.create(@relations, doc_formatter, @opts)
38
41
  end
39
42
 
40
43
  # Writes out the assets that can be written out separately:
@@ -12,6 +12,7 @@ require 'jsduck/process/overrides'
12
12
  require 'jsduck/process/inherit_doc'
13
13
  require 'jsduck/process/versions'
14
14
  require 'jsduck/process/return_values'
15
+ require 'jsduck/process/fires'
15
16
  require 'jsduck/process/lint'
16
17
  require 'jsduck/process/circular_deps'
17
18
 
@@ -68,6 +69,7 @@ module JsDuck
68
69
  Process::InheritDoc.new(relations).process_all!
69
70
  Process::Versions.new(relations, opts).process_all!
70
71
  Process::ReturnValues.new(relations).process_all!
72
+ Process::Fires.new(relations).process_all!
71
73
  Process::Lint.new(relations).process_all!
72
74
  relations
73
75
  end
@@ -27,36 +27,12 @@ module JsDuck
27
27
  # Adds small star to new classes in the current version.
28
28
  def render_new_label(cls)
29
29
  if cls[:new]
30
- "&nbsp;<span class='new-class' title='New class'>#{stars(1)}</span>"
30
+ "&nbsp;<span class='new-class' title='New class'>&#9733;</span>"
31
31
  else
32
- n = new_members_count(cls)
33
- if n > 0
34
- title = "#{n} new member#{(n>1) ? 's' : ''}"
35
- "&nbsp;<span class='new-members' title='#{title}'>#{stars(n)}</span>"
36
- else
37
- ""
38
- end
32
+ ""
39
33
  end
40
34
  end
41
35
 
42
- # Produces string of n stars.
43
- # First 3 stars are rendered as "<unicode-star>", the following as "+".
44
- # At max 15 stars are rendered.
45
- def stars(n)
46
- if n > 15
47
- stars(3) + ("+" * (15-3))
48
- elsif n > 3
49
- stars(3) + ("+" * (n-3))
50
- else
51
- "&#9733;" * n
52
- end
53
- end
54
-
55
- # Returns number of new members the class has in the current version
56
- def new_members_count(cls)
57
- cls.find_members(:local => true).find_all {|m| m[:new] && !m[:private] }.length
58
- end
59
-
60
36
  end
61
37
 
62
38
  end
@@ -2,6 +2,7 @@ require 'jsduck/logger'
2
2
  require 'jsduck/categories/file'
3
3
  require 'jsduck/categories/auto'
4
4
  require 'jsduck/categories/class_name'
5
+ require 'jsduck/columns'
5
6
 
6
7
  module JsDuck
7
8
  module Categories
@@ -20,6 +21,7 @@ module JsDuck
20
21
  def initialize(categories, doc_formatter, relations={})
21
22
  @categories = categories
22
23
  @class_name = Categories::ClassName.new(doc_formatter, relations)
24
+ @columns = Columns.new("classes")
23
25
  end
24
26
 
25
27
  # Returns HTML listing of classes divided into categories
@@ -41,10 +43,12 @@ module JsDuck
41
43
  EOHTML
42
44
  end
43
45
 
46
+ private
47
+
44
48
  def render_columns(groups)
45
49
  align = ["left-column", "middle-column", "right-column"]
46
50
  i = -1
47
- return split(groups, 3).map do |col|
51
+ return @columns.split(groups, 3).map do |col|
48
52
  i += 1
49
53
  [
50
54
  "<div class='#{align[i]}'>",
@@ -65,48 +69,6 @@ module JsDuck
65
69
  end
66
70
  end
67
71
 
68
- # Splits the array of items into n chunks so that the sum of
69
- # largest chunk is as small as possible.
70
- #
71
- # This is a brute-force implementation - we just try all the
72
- # combinations and choose the best one.
73
- def split(items, n)
74
- if n == 1
75
- [items]
76
- elsif items.length <= n
77
- Array.new(n) {|i| items[i] ? [items[i]] : [] }
78
- else
79
- min_max = nil
80
- min_arr = nil
81
- i = 0
82
- while i <= items.length-n
83
- i += 1
84
- # Try placing 1, 2, 3, ... items to first chunk.
85
- # Calculate the remaining chunks recursively.
86
- cols = [items[0,i]] + split(items[i, items.length], n-1)
87
- max = max_sum(cols)
88
- # Is this the optimal solution so far? Remember it.
89
- if !min_max || max < min_max
90
- min_max = max
91
- min_arr = cols
92
- end
93
- end
94
- min_arr
95
- end
96
- end
97
-
98
- def max_sum(cols)
99
- cols.map {|col| sum(col) }.max
100
- end
101
-
102
- # Finds the total size of items in array
103
- #
104
- # The size of one item is it's number of classes + the space for header
105
- def sum(arr)
106
- header_size = 3
107
- arr.reduce(0) {|sum, item| sum + item["classes"].length + header_size }
108
- end
109
-
110
72
  end
111
73
 
112
74
  end
@@ -0,0 +1,56 @@
1
+ module JsDuck
2
+
3
+ # Splits array of items with subitems into roughly equal size groups.
4
+ class Columns
5
+ # Initialized with the name of subitems field.
6
+ def initialize(subitems_field)
7
+ @header_size = 3
8
+ @subitems_field = subitems_field
9
+ end
10
+
11
+ # Splits the array of items into n chunks so that the sum of
12
+ # largest chunk is as small as possible.
13
+ #
14
+ # This is a brute-force implementation - we just try all the
15
+ # combinations and choose the best one.
16
+ def split(items, n)
17
+ if n == 1
18
+ [items]
19
+ elsif items.length <= n
20
+ Array.new(n) {|i| items[i] ? [items[i]] : [] }
21
+ else
22
+ min_max = nil
23
+ min_arr = nil
24
+ i = 0
25
+ while i <= items.length-n
26
+ i += 1
27
+ # Try placing 1, 2, 3, ... items to first chunk.
28
+ # Calculate the remaining chunks recursively.
29
+ cols = [items[0,i]] + split(items[i, items.length], n-1)
30
+ max = max_sum(cols)
31
+ # Is this the optimal solution so far? Remember it.
32
+ if !min_max || max < min_max
33
+ min_max = max
34
+ min_arr = cols
35
+ end
36
+ end
37
+ min_arr
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def max_sum(cols)
44
+ cols.map {|col| sum(col) }.max
45
+ end
46
+
47
+ # Finds the total size of items in array
48
+ #
49
+ # The size of one item is it's number of classes + the space for header
50
+ def sum(arr)
51
+ arr.reduce(0) {|sum, item| sum + item[@subitems_field].length + @header_size }
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,105 @@
1
+ module JsDuck
2
+ module Doc
3
+
4
+ # Helper in parsing the default values and type definitions where
5
+ # we take into account correctly nested parenthesis and strings.
6
+ # But at the same time we don't care much about the actual
7
+ # contents.
8
+ class DelimitedParser
9
+ # Initialized with Doc::Scanner instance
10
+ def initialize(doc_scanner)
11
+ @ds = doc_scanner
12
+ end
13
+
14
+ # Parses until a closing "}".
15
+ def parse_until_close_curly
16
+ parse_until_close_paren(/\}/, /[^\}]*/)
17
+ end
18
+
19
+ # Parses until a closing "]".
20
+ def parse_until_close_square
21
+ parse_until_close_paren(/\]/, /[^\]]*/)
22
+ end
23
+
24
+ # Parses until a closing parenthesis or space.
25
+ def parse_until_space
26
+ begin
27
+ parse_while(/[^\[\]\{\}\(\)'"\s]/)
28
+ rescue
29
+ nil
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # Parses until a given closing parenthesis.
36
+ # When unsuccessful, try simple parsing.
37
+ def parse_until_close_paren(re_paren, re_simple)
38
+ begin
39
+ start_pos = @ds.input.pos
40
+ result = parse_while(/[^\[\]\{\}\(\)'"]/)
41
+ if look(re_paren)
42
+ result
43
+ else
44
+ throw "Closing brace expected"
45
+ end
46
+ rescue
47
+ @ds.input.pos = start_pos
48
+ match(re_simple)
49
+ end
50
+ end
51
+
52
+ def parse_while(regex)
53
+ result = ""
54
+ while r = parse_compound || match(regex)
55
+ result += r
56
+ end
57
+ result
58
+ end
59
+
60
+ def parse_compound
61
+ if look(/\[/)
62
+ parse_balanced(/\[/, /\]/)
63
+ elsif look(/\{/)
64
+ parse_balanced(/\{/, /\}/)
65
+ elsif look(/\(/)
66
+ parse_balanced(/\(/, /\)/)
67
+ elsif look(/"/)
68
+ parse_string('"')
69
+ elsif look(/'/)
70
+ parse_string("'")
71
+ end
72
+ end
73
+
74
+ def parse_balanced(re_open, re_close)
75
+ result = match(re_open)
76
+
77
+ result += parse_while(/[^\[\]\{\}\(\)'"]/)
78
+
79
+ if r = match(re_close)
80
+ result + r
81
+ else
82
+ throw "Unbalanced parenthesis"
83
+ end
84
+ end
85
+
86
+ # Parses "..." or '...' including the escape sequence \' or '\"
87
+ def parse_string(quote)
88
+ re_quote = Regexp.new(quote)
89
+ re_rest = Regexp.new("(?:[^"+quote+"\\\\]|\\\\.)*")
90
+ match(re_quote) + match(re_rest) + (match(re_quote) || "")
91
+ end
92
+
93
+ ### Forward these calls to Doc::Scanner
94
+
95
+ def look(re)
96
+ @ds.look(re)
97
+ end
98
+
99
+ def match(re)
100
+ @ds.match(re)
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -1,4 +1,5 @@
1
1
  require 'jsduck/doc/standard_tag_parser'
2
+ require 'jsduck/logger'
2
3
 
3
4
  module JsDuck
4
5
  module Doc
@@ -20,7 +21,7 @@ module JsDuck
20
21
  end
21
22
 
22
23
  # Provides access to StringScanner
23
- attr_reader :input
24
+ attr_accessor :input
24
25
 
25
26
  # Parses standard pattern common in several builtin tags, which
26
27
  # goes like this:
@@ -1,3 +1,5 @@
1
+ require 'jsduck/doc/delimited_parser'
2
+
1
3
  module JsDuck
2
4
  module Doc
3
5
 
@@ -10,6 +12,7 @@ module JsDuck
10
12
  # Initialized with Doc::Scanner instance
11
13
  def initialize(doc_scanner)
12
14
  @ds = doc_scanner
15
+ @delimited_parser = Doc::DelimitedParser.new(doc_scanner)
13
16
  end
14
17
 
15
18
  # Parses the standard tag pattern.
@@ -19,21 +22,25 @@ module JsDuck
19
22
  #
20
23
  # - :tagname => The :tagname of the hash to return.
21
24
  #
22
- # - :type => True to parse {Type} section.
23
- # Produces :type and :optional keys.
25
+ # - :type => True to parse `{Type}` section.
26
+ #
27
+ # - :name => True to parse `some.name` section.
28
+ #
29
+ # - :default => True to parse `=<default-value>` after name.
24
30
  #
25
- # - :name => Trye to parse [some.name=default] section.
26
- # Produces :name, :default and :optional keys.
31
+ # - :optional => True to allow placing name and default value
32
+ # inside [ and ] brackets to denote optionality.
33
+ # Also returns :optional=>true when {SomType=} syntax used.
27
34
  #
28
- # Returns tag definition hash containing the given :tagname and a
29
- # set of other fields depending on whether :type and :name configs
30
- # were specified and how their matching succeeded.
35
+ # Returns tag definition hash containing the fields specified by
36
+ # config.
31
37
  #
32
38
  def parse(cfg)
33
39
  @tagname = cfg[:tagname]
34
- tag = {:tagname => cfg[:tagname]}
35
- add_type(tag) if cfg[:type]
36
- add_name_with_default(tag) if cfg[:name]
40
+ tag = {}
41
+ tag[:tagname] = cfg[:tagname] if cfg[:tagname]
42
+ add_type(tag, cfg) if cfg[:type]
43
+ add_name_with_default(tag, cfg) if cfg[:name]
37
44
  tag
38
45
  end
39
46
 
@@ -41,11 +48,11 @@ module JsDuck
41
48
 
42
49
  # matches {type} if possible and sets it on given tag hash.
43
50
  # Also checks for {optionality=} in type definition.
44
- def add_type(tag)
51
+ def add_type(tag, cfg)
45
52
  if hw.look(/\{/)
46
53
  tdf = typedef
47
54
  tag[:type] = tdf[:type]
48
- tag[:optional] = true if tdf[:optional]
55
+ tag[:optional] = true if tdf[:optional] && cfg[:optional]
49
56
  end
50
57
  end
51
58
 
@@ -53,7 +60,11 @@ module JsDuck
53
60
  def typedef
54
61
  match(/\{/)
55
62
 
56
- name = parse_balanced(/\{/, /\}/, /[^{}'"]*/)
63
+ name = @delimited_parser.parse_until_close_curly
64
+
65
+ unless match(/\}/)
66
+ warn("@#{@tagname} tag syntax: '}' expected")
67
+ end
57
68
 
58
69
  if name =~ /=$/
59
70
  name = name.chop
@@ -62,74 +73,29 @@ module JsDuck
62
73
  optional = nil
63
74
  end
64
75
 
65
- match(/\}/) or warn("@#{@tagname} tag syntax: '}' expected")
66
-
67
76
  return {:type => name, :optional => optional}
68
77
  end
69
78
 
70
- # matches: <ident-chain> | "[" <ident-chain> [ "=" <default-value> ] "]"
71
- def add_name_with_default(tag)
72
- if hw.match(/\[/)
79
+ # matches: <ident-chain>
80
+ # | <ident-chain> [ "=" <default-value>
81
+ # | "[" <ident-chain> [ "=" <default-value> ] "]"
82
+ def add_name_with_default(tag, cfg)
83
+ if hw.look(/\[/) && cfg[:optional]
84
+ match(/\[/)
73
85
  tag[:name] = hw.ident_chain
74
86
  if hw.match(/=/)
75
87
  hw
76
- tag[:default] = default_value
88
+ tag[:default] = @delimited_parser.parse_until_close_square
77
89
  end
78
90
  hw.match(/\]/) or warn("@#{@tagname} tag syntax: ']' expected")
79
91
  tag[:optional] = true
80
- else
81
- tag[:name] = hw.ident_chain
82
- end
83
- end
84
-
85
- # Attempts to allow balanced braces in default value.
86
- # When the nested parsing doesn't finish at closing "]",
87
- # roll back to beginning and simply grab anything up to closing "]".
88
- def default_value
89
- start_pos = @ds.input.pos
90
- value = parse_balanced(/\[/, /\]/, /[^\[\]'"]*/)
91
- if look(/\]/)
92
- value
93
- else
94
- @ds.input.pos = start_pos
95
- match(/[^\]]*/)
96
- end
97
- end
98
-
99
- # Helper method to parse a string up to a closing brace,
100
- # balancing opening-closing braces in between.
101
- #
102
- # @param re_open The beginning brace regex
103
- # @param re_close The closing brace regex
104
- # @param re_rest Regex to match text without any braces and strings
105
- def parse_balanced(re_open, re_close, re_rest)
106
- result = parse_with_strings(re_rest)
107
- while look(re_open)
108
- result += match(re_open)
109
- result += parse_balanced(re_open, re_close, re_rest)
110
- result += match(re_close)
111
- result += parse_with_strings(re_rest)
112
- end
113
- result
114
- end
115
-
116
- # Helper for parse_balanced to parse rest of the text between
117
- # braces, taking account the strings which might occur there.
118
- def parse_with_strings(re_rest)
119
- result = match(re_rest)
120
- while look(/['"]/)
121
- result += parse_string('"') if look(/"/)
122
- result += parse_string("'") if look(/'/)
123
- result += match(re_rest)
92
+ elsif name = ident_chain
93
+ tag[:name] = name
94
+ if cfg[:default] && hw.match(/=/)
95
+ hw
96
+ tag[:default] = @delimited_parser.parse_until_space
97
+ end
124
98
  end
125
- result
126
- end
127
-
128
- # Parses "..." or '...' including the escape sequence \' or '\"
129
- def parse_string(quote)
130
- re_quote = Regexp.new(quote)
131
- re_rest = Regexp.new("(?:[^"+quote+"\\\\]|\\\\.)*")
132
- match(re_quote) + match(re_rest) + (match(re_quote) || "")
133
99
  end
134
100
 
135
101
  ### Forward these calls to Doc::Scanner