kwartz 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. data/CHANGES +444 -0
  2. data/README.txt +4 -1
  3. data/bin/kwartz +2 -2
  4. data/doc-api/classes/Kwartz.html +16 -7
  5. data/doc-api/classes/Kwartz/Assertion.html +6 -6
  6. data/doc-api/classes/Kwartz/AssertionError.html +6 -6
  7. data/doc-api/classes/Kwartz/AttrInfo.html +71 -61
  8. data/doc-api/classes/Kwartz/BaseError.html +12 -12
  9. data/doc-api/classes/Kwartz/BaseTranslator.html +104 -74
  10. data/doc-api/classes/Kwartz/CharacterType.html +24 -24
  11. data/doc-api/classes/Kwartz/CommandOptionError.html +7 -7
  12. data/doc-api/classes/Kwartz/CommandOptions.html +50 -50
  13. data/doc-api/classes/Kwartz/Config.html +5 -0
  14. data/doc-api/classes/Kwartz/ConvertError.html +12 -12
  15. data/doc-api/classes/Kwartz/Converter.html +31 -33
  16. data/doc-api/classes/Kwartz/CssStyleParser.html +207 -168
  17. data/doc-api/classes/Kwartz/Defun.html +32 -31
  18. data/doc-api/classes/Kwartz/{HandlerArgument.html → Directive.html} +27 -53
  19. data/doc-api/classes/Kwartz/ElementInfo.html +68 -53
  20. data/doc-api/classes/Kwartz/EperlExpressionParser.html +185 -0
  21. data/doc-api/classes/Kwartz/EperlHandler.html +65 -58
  22. data/doc-api/classes/Kwartz/EperlTranslator.html +14 -7
  23. data/doc-api/classes/Kwartz/ErubisTranslator.html +14 -7
  24. data/doc-api/classes/Kwartz/ErubyTranslator.html +14 -7
  25. data/doc-api/classes/Kwartz/ExpandStatement.html +20 -20
  26. data/doc-api/classes/Kwartz/Expander.html +358 -0
  27. data/doc-api/classes/Kwartz/Handler.html +287 -157
  28. data/doc-api/classes/Kwartz/{StatementHelper.html → HandlerHelper.html} +307 -112
  29. data/doc-api/classes/Kwartz/Helper/ActionViewHelper.html +23 -23
  30. data/doc-api/classes/Kwartz/Helper/RailsTemplate.html +96 -96
  31. data/doc-api/classes/Kwartz/JstlExpressionParser.html +181 -0
  32. data/doc-api/classes/Kwartz/JstlHandler.html +134 -126
  33. data/doc-api/classes/Kwartz/JstlTranslator.html +21 -14
  34. data/doc-api/classes/Kwartz/KwartzError.html +6 -6
  35. data/doc-api/classes/Kwartz/Main.html +4 -4
  36. data/doc-api/classes/Kwartz/NativeExpression.html +19 -19
  37. data/doc-api/classes/Kwartz/NativeStatement.html +24 -24
  38. data/doc-api/classes/Kwartz/Node.html +7 -7
  39. data/doc-api/classes/Kwartz/PIErubisTranslator.html +21 -14
  40. data/doc-api/classes/Kwartz/ParseError.html +6 -6
  41. data/doc-api/classes/Kwartz/PerlExpressionParser.html +185 -0
  42. data/doc-api/classes/Kwartz/PerlHandler.html +353 -0
  43. data/doc-api/classes/Kwartz/PerlTranslator.html +226 -0
  44. data/doc-api/classes/Kwartz/PhpExpressionParser.html +185 -0
  45. data/doc-api/classes/Kwartz/PhpHandler.html +63 -56
  46. data/doc-api/classes/Kwartz/PhpTranslator.html +21 -14
  47. data/doc-api/classes/Kwartz/PresentationLogicParser.html +126 -123
  48. data/doc-api/classes/Kwartz/PrintStatement.html +18 -18
  49. data/doc-api/classes/Kwartz/RailsHandler.html +84 -85
  50. data/doc-api/classes/Kwartz/RailsTranslator.html +13 -6
  51. data/doc-api/classes/Kwartz/RubyExpressionParser.html +180 -0
  52. data/doc-api/classes/Kwartz/RubyHandler.html +73 -69
  53. data/doc-api/classes/Kwartz/RubyStyleParser.html +86 -86
  54. data/doc-api/classes/Kwartz/RubyTranslator.html +28 -21
  55. data/doc-api/classes/Kwartz/Ruleset.html +622 -1
  56. data/doc-api/classes/Kwartz/StrutsTranslator.html +14 -14
  57. data/doc-api/classes/Kwartz/TagInfo.html +52 -27
  58. data/doc-api/classes/Kwartz/TextConverter.html +75 -37
  59. data/doc-api/classes/Kwartz/Translator.html +54 -53
  60. data/doc-api/classes/Kwartz/Util.html +25 -25
  61. data/doc-api/created.rid +1 -1
  62. data/doc-api/files/__/README_txt.html +7 -2
  63. data/doc-api/files/kwartz/assert_rb.html +2 -2
  64. data/doc-api/files/kwartz/binding/eperl_rb.html +2 -2
  65. data/doc-api/files/kwartz/binding/erubis_rb.html +2 -2
  66. data/doc-api/files/kwartz/binding/eruby_rb.html +2 -2
  67. data/doc-api/files/kwartz/binding/jstl_rb.html +2 -2
  68. data/doc-api/files/kwartz/binding/perl_rb.html +115 -0
  69. data/doc-api/files/kwartz/binding/php_rb.html +2 -2
  70. data/doc-api/files/kwartz/binding/pierubis_rb.html +2 -2
  71. data/doc-api/files/kwartz/binding/rails_rb.html +2 -2
  72. data/doc-api/files/kwartz/binding/ruby_rb.html +2 -2
  73. data/doc-api/files/kwartz/binding/struts_rb.html +2 -2
  74. data/doc-api/files/kwartz/config_rb.html +2 -2
  75. data/doc-api/files/kwartz/converter_rb.html +2 -2
  76. data/doc-api/files/kwartz/defun_rb.html +2 -2
  77. data/doc-api/files/kwartz/error_rb.html +2 -2
  78. data/doc-api/files/kwartz/helper/rails_rb.html +2 -2
  79. data/doc-api/files/kwartz/main_rb.html +3 -2
  80. data/doc-api/files/kwartz/node_rb.html +2 -2
  81. data/doc-api/files/kwartz/parser_rb.html +2 -2
  82. data/doc-api/files/kwartz/translator_rb.html +2 -2
  83. data/doc-api/files/kwartz/util/assert-text-equal_rb.html +2 -2
  84. data/doc-api/files/kwartz/util/testcase-helper_rb.html +2 -2
  85. data/doc-api/files/kwartz/util_rb.html +2 -2
  86. data/doc-api/files/kwartz_rb.html +2 -2
  87. data/doc-api/fr_class_index.html +10 -5
  88. data/doc-api/fr_file_index.html +1 -0
  89. data/doc-api/fr_method_index.html +268 -239
  90. data/doc/docstyle.css +9 -3
  91. data/doc/img/fig05.png +0 -0
  92. data/doc/introduction-to-kwartz.html +3040 -0
  93. data/doc/pattern-catalog.html +5 -3
  94. data/doc/reference.html +680 -26
  95. data/doc/users-guide.html +222 -67
  96. data/kwartz.gemspec +4 -4
  97. data/lib/kwartz.rb +3 -3
  98. data/lib/kwartz/assert.rb +2 -2
  99. data/lib/kwartz/binding/eperl.rb +71 -31
  100. data/lib/kwartz/binding/erubis.rb +3 -2
  101. data/lib/kwartz/binding/eruby.rb +3 -2
  102. data/lib/kwartz/binding/jstl.rb +66 -29
  103. data/lib/kwartz/binding/perl.rb +230 -0
  104. data/lib/kwartz/binding/php.rb +69 -29
  105. data/lib/kwartz/binding/pierubis.rb +3 -2
  106. data/lib/kwartz/binding/rails.rb +18 -18
  107. data/lib/kwartz/binding/ruby.rb +74 -42
  108. data/lib/kwartz/binding/struts.rb +22 -21
  109. data/lib/kwartz/config.rb +4 -4
  110. data/lib/kwartz/converter.rb +465 -345
  111. data/lib/kwartz/defun.rb +2 -2
  112. data/lib/kwartz/error.rb +2 -2
  113. data/lib/kwartz/helper/rails.rb +2 -2
  114. data/lib/kwartz/main.rb +5 -4
  115. data/lib/kwartz/node.rb +92 -144
  116. data/lib/kwartz/parser.rb +112 -103
  117. data/lib/kwartz/translator.rb +14 -6
  118. data/lib/kwartz/util.rb +2 -2
  119. data/lib/kwartz/util/assert-text-equal.rb +2 -2
  120. data/lib/kwartz/util/testcase-helper.rb +1 -1
  121. data/test/test-compile.rb +2 -2
  122. data/test/test-compile.yaml +81 -0
  123. data/test/test-converter.rb +4 -8
  124. data/test/test-converter.yaml +152 -3
  125. data/test/test-directives.rb +2 -2
  126. data/test/test-directives.yaml +222 -0
  127. data/test/test-main.rb +6 -4
  128. data/test/test-main.yaml +66 -1
  129. data/test/test-parser.rb +12 -3
  130. data/test/test-parser.yaml +64 -51
  131. data/test/test-rails.rb +2 -2
  132. data/test/test-ruleset.rb +2 -2
  133. data/test/test-ruleset.yaml +465 -4
  134. data/test/test.log +6 -0
  135. data/test/test.rb +2 -2
  136. metadata +116 -106
  137. data/ChangeLog +0 -156
  138. data/doc-api/classes/Kwartz/DocumentRuleset.html +0 -369
  139. data/doc-api/classes/Kwartz/ElementExpander.html +0 -325
  140. data/doc-api/classes/Kwartz/ElementRuleset.html +0 -612
@@ -1,6 +1,6 @@
1
1
  ###
2
- ### $Rev: 128 $
3
- ### $Release: 3.1.2 $
2
+ ### $Rev$
3
+ ### $Release: 3.2.0 $
4
4
  ### copyright(c) 2004-2006 kuwata-lab.com all rights reserved
5
5
  ###
6
6
 
@@ -12,11 +12,45 @@ require 'kwartz/translator'
12
12
  module Kwartz
13
13
 
14
14
 
15
+ module RubyExpressionParser
16
+
17
+
18
+ def parse_expr_str(expr_str, linenum)
19
+ case expr_str
20
+ when /\A(\w+)\z/ # variable
21
+ expr = expr_str
22
+ when /\A(\w+)\.(\w+)\z/ # object.property
23
+ expr = expr_str
24
+ when /\A(\w+)\[('.*?'|".*?"|:\w+)\]\z/ # hash
25
+ expr = expr_str
26
+ when /\A(\w+)\[(\w+)\]\z/ # array or hash
27
+ expr = expr_str
28
+ else
29
+ raise convert_error("'#{expr_str}': invalid expression.", linenum)
30
+ end
31
+ return expr
32
+ end
33
+
34
+
35
+ def parse_expr_str!(expr_str)
36
+ begin
37
+ return parse_expr_str!(expr_str, -1)
38
+ rescue
39
+ return expr_str
40
+ end
41
+ end
42
+
43
+
44
+ end
45
+
46
+
47
+
15
48
 
16
49
  ##
17
50
  ## directive handler for Ruby
18
51
  ##
19
52
  class RubyHandler < Handler
53
+ include RubyExpressionParser
20
54
 
21
55
 
22
56
  RUBY_DIRECTIVE_PATTERN = /\A(\w+)(?:[:\s]\s*(.*))?\z/
@@ -40,24 +74,21 @@ module Kwartz
40
74
  end
41
75
 
42
76
 
43
- def handle(stmt_list, handler_arg)
77
+ def handle(directive, elem_info, stmt_list)
44
78
  ret = super
45
79
  return ret if ret
46
80
 
47
- arg = handler_arg
48
- d_name = arg.directive_name
49
- d_arg = arg.directive_arg
50
- d_str = arg.directive_str
51
- #stag_info = arg.stag_info
52
- #etag_info = arg.etag_info
53
- #cont_stmts = arg.cont_stmts
81
+ d_name = directive.name
82
+ d_arg = directive.arg
83
+ d_str = directive.str
84
+ e = elem_info
54
85
 
55
86
  case d_name
56
87
 
57
88
  when :for, :For, :FOR, :list, :List, :LIST
58
89
  unless d_arg =~ /\A(\w+)(?:,\s*(\w+))?\s+in\s+(.*)\z/ \
59
90
  || d_arg =~ /\A(\w+)(?:,(\w+))?\s*[:=]\s*(.*)\z/
60
- raise convert_error("'#{d_str}': invalid argument.", arg.stag_info.linenum)
91
+ raise convert_error("'#{d_str}': invalid argument.", e.stag_info.linenum)
61
92
  end
62
93
  loopvar = $1 ; loopval = $2 ; looplist = $3
63
94
  is_foreach = d_name == :for || d_name == :For || d_name == :FOR
@@ -71,70 +102,70 @@ module Kwartz
71
102
  code << " #{counter} += 1" if counter
72
103
  code << " #{toggle} = #{counter}%2==0 ? #{@even} : #{@odd}" if toggle
73
104
  if is_foreach
74
- wrap_element_with_native_stmt(stmt_list, arg, code, "end", :foreach)
105
+ wrap_element_with_native_stmt(elem_info, stmt_list, code, "end", :foreach)
75
106
  else
76
- wrap_content_with_native_stmt(stmt_list, arg, code, "end", :foreach)
107
+ wrap_content_with_native_stmt(elem_info, stmt_list, code, "end", :foreach)
77
108
  end
78
109
 
79
110
  when :while
80
- wrap_element_with_native_stmt(stmt_list, arg, "while #{d_arg} do", "end", :while)
111
+ wrap_element_with_native_stmt(elem_info, stmt_list, "while #{d_arg} do", "end", :while)
81
112
  #stmt_list << NativeStatement.new("while #{d_arg} do", :while)
82
- #stmt_list << stag_stmt(arg)
83
- #stmt_list.concat(arg.cont_stmts)
84
- #stmt_list << etag_stmt(arg)
113
+ #stmt_list << stag_stmt(elem_info)
114
+ #stmt_list.concat(e.cont_stmts)
115
+ #stmt_list << etag_stmt(elem_info)
85
116
  #stmt_list << NativeStatement.new("end", :while)
86
117
 
87
118
  when :loop
88
- error_if_empty_tag(arg)
89
- wrap_content_with_native_stmt(stmt_list, arg, "while #{d_arg} do", "end", :while)
90
- #stmt_list << stag_stmt(arg)
119
+ error_if_empty_tag(elem_info, d_str)
120
+ wrap_content_with_native_stmt(elem_info, stmt_list, "while #{d_arg} do", "end", :while)
121
+ #stmt_list << stag_stmt(elem_info)
91
122
  #stmt_list << NativeStatement.new("while #{d_arg} do", :while)
92
- #stmt_list.concat(arg.cont_stmts)
123
+ #stmt_list.concat(e.cont_stmts)
93
124
  #stmt_list << NativeStatement.new("end", :while)
94
- #stmt_list << etag_stmt(arg)
125
+ #stmt_list << etag_stmt(elem_info)
95
126
 
96
127
  when :set
97
- wrap_element_with_native_stmt(stmt_list, arg, d_arg, nil, :set)
128
+ wrap_element_with_native_stmt(elem_info, stmt_list, d_arg, nil, :set)
98
129
  #stmt_list << NativeStatement.new(d_arg, :set)
99
- #stmt_list << stag_stmt(arg)
100
- #stmt_list.concat(arg.cont_stmts)
101
- #stmt_list << etag_stmt(arg)
130
+ #stmt_list << stag_stmt(elem_info)
131
+ #stmt_list.concat(e.cont_stmts)
132
+ #stmt_list << etag_stmt(elem_info)
102
133
 
103
134
  when :if
104
- wrap_element_with_native_stmt(stmt_list, arg, "if #{d_arg} then", "end", :if)
135
+ wrap_element_with_native_stmt(elem_info, stmt_list, "if #{d_arg} then", "end", :if)
105
136
  #stmt_list << NativeStatement.new("if #{d_arg} then", :if)
106
- #stmt_list << stag_stmt(arg)
107
- #stmt_list.concat(arg.cont_stmts)
108
- #stmt_list << etag_stmt(arg)
137
+ #stmt_list << stag_stmt(elem_info)
138
+ #stmt_list.concat(e.cont_stmts)
139
+ #stmt_list << etag_stmt(elem_info)
109
140
  #stmt_list << NativeStatement.new("end", :if)
110
141
 
111
142
  when :elsif, :else
112
- error_when_last_stmt_is_not_if(stmt_list, arg)
143
+ error_when_last_stmt_is_not_if(elem_info, d_str, stmt_list)
113
144
  stmt_list.pop # delete 'end'
114
145
  kind = d_name == :else ? :else : :elseif
115
146
  code = d_name == :else ? "else" : "elsif #{d_arg} then"
116
- wrap_element_with_native_stmt(stmt_list, arg, code, "end", kind)
147
+ wrap_element_with_native_stmt(elem_info, stmt_list, code, "end", kind)
117
148
  #stmt_list << NativeStatement.new(code, kind)
118
- #stmt_list << stag_stmt(arg)
119
- #stmt_list.concat(arg.cont_stmts)
120
- #stmt_list << etag_stmt(arg)
149
+ #stmt_list << stag_stmt(elem_info)
150
+ #stmt_list.concat(e.cont_stmts)
151
+ #stmt_list << etag_stmt(elem_info)
121
152
  #stmt_list << NativeStatement.new("end", kind)
122
153
 
123
154
  when :default, :Default, :DEFAULT
124
- error_if_empty_tag(arg)
125
- expr_code = d_arg
155
+ error_if_empty_tag(elem_info, d_str)
156
+ expr_str = directive.dattr == 'id' ? parse_expr_str(d_arg, e.stag_info.linenum) : d_arg
126
157
  flag_escape = d_name == :default ? nil : (d_name == :Default)
127
- add_native_expr_with_default(stmt_list, arg, expr_code, flag_escape,
128
- "if (#{d_arg}) && !(#{d_arg}).to_s.empty? then",
158
+ add_native_expr_with_default(elem_info, stmt_list, expr_str, flag_escape,
159
+ "if (#{expr_str}) && !(#{d_arg}).to_s.empty? then",
129
160
  "else", "end")
130
- #stmt_list << stag_stmt(arg)
161
+ #stmt_list << stag_stmt(elem_info)
131
162
  #stmt_list << NativeStatement.new_without_newline("if (#{d_arg}) && !(#{d_arg}).to_s.empty? then", :if)
132
163
  #flag_escape = d_name == :default ? nil : (d_name == :Default)
133
164
  #stmt_list << PrintStatement.new([ NativeExpression.new(d_arg, flag_escape) ])
134
165
  #stmt_list << NativeStatement.new_without_newline("else", :else)
135
- #stmt_list.concat(arg.cont_stmts)
166
+ #stmt_list.concat(e.cont_stmts)
136
167
  #stmt_list << NativeStatement.new_without_newline("end", :else)
137
- #stmt_list << etag_stmt(arg)
168
+ #stmt_list << etag_stmt(elem_info)
138
169
 
139
170
  else
140
171
  return false
@@ -154,6 +185,7 @@ module Kwartz
154
185
  ## translator for eRuby
155
186
  ##
156
187
  class RubyTranslator < BaseTranslator
188
+ include RubyExpressionParser
157
189
 
158
190
 
159
191
  def initialize(properties={})
@@ -1,6 +1,6 @@
1
1
  ###
2
- ### $Rev: 111 $
3
- ### $Release: 3.1.2 $
2
+ ### $Rev$
3
+ ### $Release: 3.2.0 $
4
4
  ### copyright(c) 2004-2006 kuwata-lab.com all rights reserved
5
5
  ###
6
6
 
@@ -22,25 +22,26 @@ module Kwartz
22
22
 
23
23
 
24
24
 
25
- def handle(directive_name, directive_arg, directive_str, stag_info, etag_info, cont_stmts, attr_info, append_exprs, stmt_list)
25
+ def handle(directive, elem_info, stmt_list)
26
26
  ret = super
27
27
  return ret if ret
28
28
 
29
- d_name = directive_name
30
- d_arg = directive_arg
31
- d_str = directive_str
29
+ d_name = directive.name
30
+ d_arg = directive.arg
31
+ d_str = directive.str
32
+ e = elem_info
32
33
 
33
- case directive_name
34
+ case d_name
34
35
 
35
36
  when :struts
36
- case tag = stag_info.tagname
37
- when 'input' ; tag = attr_info['type'] || 'text' ; attr_info.delete('type')
37
+ case tag = e.stag_info.tagname
38
+ when 'input' ; tag = e.attr_info['type'] || 'text' ; e.attr_info.delete('type')
38
39
  when 'a' ; tag = 'link'
39
40
  when 'script' ; tag = 'javascript'
40
41
  end
41
- tag == :struts and raise convert_error("#{d_str}: unknown directive.", stag_info.linenum)
42
- return self.handle(tag.intern, d_arg, directive_str, stag_info, etag_info,
43
- cont_stmts, attr_info, append_exprs, stmt_list)
42
+ tag == :struts and raise convert_error("#{d_str}: unknown directive.", e.stag_info.linenum)
43
+ directive.name = tag.intern
44
+ return self.handle(directive, elem_info, stmt_list)
44
45
 
45
46
  else
46
47
  convert_mapping = {
@@ -48,21 +49,21 @@ module Kwartz
48
49
  'class'=>'cssClass'
49
50
  }
50
51
  convert_mapping.each do |html_aname, struts_aname|
51
- next unless attr_info[html_aname]
52
- attr_info[struts_aname] = attr_info[html_aname]
53
- attr_info.delete(html_aname)
52
+ next unless e.attr_info[html_aname]
53
+ e.attr_info[struts_aname] = e.attr_info[html_aname]
54
+ e.attr_info.delete(html_aname)
54
55
  end
55
56
  opts = eval "_evaluate_options(#{d_arg})"
56
57
  opts.each do |name, value|
57
- attr_info[name.to_s] = value.is_a?(Symbol) ? "${#{value}}" : value
58
+ e.attr_info[name.to_s] = value.is_a?(Symbol) ? "${#{value}}" : value
58
59
  end
59
60
  tagname = "html:#{d_name}"
60
- stag_info.tagname = tagname
61
- etag_info.tagname = tagname if etag_info
62
- stag_info.is_empty = true if !etag_info
63
- stmt_list << build_print_stmt(stag_info, attr_info, append_exprs)
61
+ e.stag_info.tagname = tagname
62
+ e.etag_info.tagname = tagname if e.etag_info
63
+ e.stag_info.is_empty = true if !e.etag_info
64
+ stmt_list << build_print_stmt(e.stag_info, e.attr_info, e.append_exprs)
64
65
  stmt_list.concat(cont_stmts)
65
- stmt_list << build_print_stmt(etag_info, nil, nil) if etag_info
66
+ stmt_list << build_print_stmt(e.etag_info, nil, nil) if e.etag_info
66
67
 
67
68
  end #case
68
69
  return true
@@ -1,6 +1,6 @@
1
1
  ###
2
- ### $Rev: 135 $
3
- ### $Release: 3.1.2 $
2
+ ### $Rev$
3
+ ### $Release: 3.2.0 $
4
4
  ### copyright(c) 2004-2006 kuwata-lab.com all rights reserved
5
5
  ###
6
6
 
@@ -20,10 +20,10 @@ module Kwartz
20
20
  PROPERTY_JSTL = 1.2 # jstl version (1.2 or 1.1)
21
21
  #
22
22
  NO_ETAGS = [ 'input', 'img' ,'br', 'hr', 'meta', 'link' ]
23
- #ALLOW_DUPLICATE_ID = false
23
+ ALLOW_DUPLICATE_ID = false # if true then enables to use duplicated id name.
24
24
 
25
25
 
26
26
  end
27
27
 
28
-
28
+
29
29
  end
@@ -1,6 +1,6 @@
1
1
  ###
2
- ### $Rev: 148 $
3
- ### $Release: 3.1.2 $
2
+ ### $Rev$
3
+ ### $Release: 3.2.0 $
4
4
  ### copyright(c) 2004-2006 kuwata-lab.com all rights reserved
5
5
  ###
6
6
 
@@ -83,6 +83,12 @@ module Kwartz
83
83
  end
84
84
 
85
85
 
86
+ def clear_as_dummy_tag # delete <span> tag
87
+ @tagname = nil
88
+ @head_space = @tail_space = nil if @head_space && @tail_space
89
+ end
90
+
91
+
86
92
  def _inspect
87
93
  return [ @prev_text, @head_space, @is_etag, @tagname, @attr_str, @extra_space, @is_empty, @tail_space ]
88
94
  end
@@ -104,20 +110,22 @@ module Kwartz
104
110
  @values[name] = value
105
111
  @spaces[name] = space
106
112
  end
107
- @directive = nil
108
- @linenum = nil
109
113
  end
110
114
  attr_reader :names, :values, :spaces
111
- attr_accessor :directive, :linenum
115
+
116
+
117
+ def has?(name)
118
+ return @values.key?(name)
119
+ end
112
120
 
113
121
 
114
122
  def [](name)
115
- @values[name]
123
+ return @values[name]
116
124
  end
117
125
 
118
126
 
119
127
  def []=(name, value)
120
- @names << name unless @values.key?(name)
128
+ @names << name unless has?(name)
121
129
  @values[name] = value
122
130
  @spaces[name] = ' ' unless @spaces.key?(name)
123
131
  end
@@ -125,15 +133,13 @@ module Kwartz
125
133
 
126
134
  def each
127
135
  @names.each do |name|
128
- space = @spaces[name]
129
- value = @values[name]
130
- yield(space, name, value)
136
+ yield(@spaces[name], name, @values[name])
131
137
  end
132
138
  end
133
139
 
134
140
 
135
141
  def delete(name)
136
- if @values.key?(name)
142
+ if has?(name)
137
143
  @names.delete(name)
138
144
  @values.delete(name)
139
145
  @spaces.delete(name)
@@ -153,55 +159,58 @@ module Kwartz
153
159
  class ElementInfo
154
160
 
155
161
 
156
- def initialize(name, stag_info, etag_info, cont_stmts, attr_info, append_exprs)
157
- @name = name # String
162
+ def initialize(stag_info, etag_info, cont_stmts, attr_info, append_exprs)
158
163
  @stag_info = stag_info # TagInfo
159
164
  @etag_info = etag_info # TagInfo
160
165
  @cont_stmts = cont_stmts # list of Statement
161
166
  @attr_info = attr_info # AttrInfo
162
167
  @append_exprs = append_exprs # list of NativeExpression
163
168
  @logic = [ ExpandStatement.new(:elem, @name) ]
164
- @merged = nil
165
169
  end
166
170
 
167
- attr_accessor :name, :stag_info, :etag_info, :cont_stmts, :attr_info, :append_exprs, :logic
171
+ attr_accessor :stag_info, :etag_info, :cont_stmts, :attr_info, :append_exprs
168
172
  attr_reader :stag_expr, :cont_expr, :etag_expr, :elem_expr
169
-
170
-
171
- def merged?
172
- !@merged.nil?
173
- end
173
+ attr_reader :logic, :before, :after
174
+ attr_accessor :name
175
+ attr_accessor :applied
174
176
 
175
177
 
176
178
  def self.create(values={})
177
- self.new(values[:name], values[:stag], values[:etag], values[:cont], values[:attr], values[:append])
179
+ v = values
180
+ return self.new(v[:name], v[:stag], v[:etag], v[:cont], v[:attr], v[:append])
178
181
  end
179
182
 
180
183
 
181
- def merge(elem_ruleset)
182
- return unless elem_ruleset.name == @name
183
- @merged = elem_ruleset
184
- @stag_expr = _to_native_expr(elem_ruleset.stag)
185
- @cont_expr = _to_native_expr(elem_ruleset.cont || elem_ruleset.value)
186
- @etag_expr = _to_native_expr(elem_ruleset.etag)
187
- @elem_expr = _to_native_expr(elem_ruleset.elem)
184
+ def apply(ruleset)
185
+ r = ruleset
186
+ @stag_expr = _to_native_expr(r.stag) if r.stag
187
+ @cont_expr = _to_native_expr(r.cont) if r.cont
188
+ @etag_expr = _to_native_expr(r.etag) if r.etag
189
+ @elem_expr = _to_native_expr(r.elem) if r.elem
188
190
  if @cont_expr
189
191
  @cont_stmts = [ PrintStatement.new([@cont_expr]) ]
190
192
  @stag_info.tail_space = ''
191
193
  @etag_info.head_space = ''
192
194
  @etag_info.rebuild_tag_text()
193
195
  end
194
- elem_ruleset.remove.each do |aname|
196
+ r.remove.each do |aname|
195
197
  @attr_info.delete(aname)
196
- end if elem_ruleset.remove
197
- elem_ruleset.attrs.each do |aname, avalue|
198
+ end if r.remove
199
+ r.attrs.each do |aname, avalue|
198
200
  @attr_info[aname] = _to_native_expr(avalue)
199
- end if elem_ruleset.attrs
200
- elem_ruleset.append.each do |expr|
201
+ end if r.attrs
202
+ r.append.each do |expr|
201
203
  (@append_exprs ||= []) << _to_native_expr(expr)
202
- end if elem_ruleset.append
203
- @tagname = elem_ruleset.tagname
204
- @logic = elem_ruleset.logic if elem_ruleset.logic
204
+ end if r.append
205
+ @tagname = r.tagname if r.tagname
206
+ @logic = r.logic if r.logic
207
+ (@before ||= []).concat(r.before) if r.before
208
+ (@after ||= []).concat(r.after) if r.after
209
+ end
210
+
211
+
212
+ def dummy_span_tag?(tagname='span')
213
+ return @stag_info.tagname == tagname && @attr_info.empty? && @append_exprs.nil?
205
214
  end
206
215
 
207
216
 
@@ -218,18 +227,9 @@ module Kwartz
218
227
 
219
228
 
220
229
  ##
221
- ## helper module for Converter and Handler
222
230
  ##
223
- ## Handler and Converter class include this module.
224
231
  ##
225
- module ConverterHelper # :nodoc:
226
-
227
-
228
- ## set @despan and @dattr
229
- def include_properties(properties)
230
- @dattr = properties[:dattr] || Config::PROPERTY_DATTR # default: 'kw:d'
231
- @delspan = properties.key?(:delspan) ? properties[:delspan] : Config::PROPERTY_DELSPAN # delete dummy <span> tag or not
232
- end
232
+ module ConvertErrorHelper # :nodoc:
233
233
 
234
234
 
235
235
  ## return ConvertError
@@ -238,25 +238,31 @@ module Kwartz
238
238
  end
239
239
 
240
240
 
241
- ## raise errror if etag_info is null
242
- def error_if_empty_tag(handler_arg)
243
- arg = handler_arg
244
- unless arg.etag_info
245
- d_name = arg.directive_name
246
- d_str = arg.directive_str
247
- msg = "'#{d_str}': #{d_name} directive is not available with empty tag."
248
- raise convert_error(msg, arg.stag_info.linenum)
241
+ end
242
+
243
+
244
+
245
+ ##
246
+ ##
247
+ ##
248
+ module HandlerHelper
249
+ #include ConvertErrorHelper
250
+
251
+
252
+ ## raise error if etag_info is null
253
+ def error_if_empty_tag(elem_info, directive_str)
254
+ unless elem_info.etag_info
255
+ msg = "'#{directive_str}': directive is not available with empty tag."
256
+ raise convert_error(msg, elem_info.stag_info.linenum)
249
257
  end
250
258
  end
251
259
 
252
260
 
253
- def error_when_last_stmt_is_not_if(stmt_list, handler_arg)
261
+ def error_when_last_stmt_is_not_if(elem_info, directive_str, stmt_list)
254
262
  kind = _last_stmt_kind(stmt_list)
255
263
  unless kind == :if || kind == :elseif
256
- d_str = handler_arg.directive_str
257
- linenum = handler_arg.stag_info.linenum
258
- msg = "'#{d_str}': previous statement should be 'if' or 'elsif'."
259
- raise convert_error(msg, linenum)
264
+ msg = "'#{directive_str}': previous statement should be 'if' or 'elsif'."
265
+ raise convert_error(msg, elem_info.stag_info.linenum)
260
266
  end
261
267
  end
262
268
 
@@ -272,13 +278,6 @@ module Kwartz
272
278
  end
273
279
 
274
280
 
275
- end
276
-
277
-
278
-
279
- module StatementHelper
280
-
281
-
282
281
  ## create print statement from text
283
282
  def create_text_print_stmt(text)
284
283
  return PrintStatement.new([text])
@@ -305,8 +304,9 @@ module Kwartz
305
304
  attr_info.each do |space, aname, avalue|
306
305
  sb << "#{space}#{aname}=\""
307
306
  if avalue.is_a?(NativeExpression)
307
+ native_expr = expand_attr_vars_in_native_expr(avalue, attr_info)
308
308
  args << sb # TextExpression.new(sb)
309
- args << avalue
309
+ args << native_expr
310
310
  sb = ''
311
311
  else
312
312
  sb << avalue
@@ -318,7 +318,10 @@ module Kwartz
318
318
  args << sb # TextExpression.new(sb)
319
319
  sb = ''
320
320
  end
321
- args.concat(append_exprs)
321
+ append_exprs.each do |append_expr|
322
+ native_expr = expand_attr_vars_in_native_expr(append_expr, attr_info)
323
+ args << native_expr
324
+ end
322
325
  end
323
326
  sb << "#{t.extra_space}#{t.is_empty ? '/' : ''}>#{t.tail_space}"
324
327
  args << sb # TextExpression.new(sb)
@@ -334,28 +337,67 @@ module Kwartz
334
337
 
335
338
 
336
339
  ## create PrintStatement for NativeExpression
337
- def build_print_expr_stmt(native_expr, stag_info, etag_info)
340
+ def build_print_expr_stmt(native_expr, stag_info, etag_info, attr_info=nil)
338
341
  head_space = (stag_info || etag_info).head_space
339
342
  tail_space = (etag_info || stag_info).tail_space
343
+ native_expr = expand_attr_vars_in_native_expr(native_expr, attr_info) if attr_info
340
344
  args = []
341
- args << head_space if head_space # TexExpression.new(head_space)
345
+ args << head_space if head_space # TextExpression.new(head_space)
342
346
  args << native_expr
343
347
  args << tail_space if tail_space # TextExpression.new(tail_space)
344
348
  return PrintStatement.new(args)
345
349
  end
346
350
 
347
351
 
352
+ ## expand attribute variables (such as '$(rows)' or '$(value)') and return new code
353
+ def expand_attr_vars(code, attr_info)
354
+ new_code = code.gsub(/\$\((\w+(?::\w+)?)\)/) do |m|
355
+ aname = $1
356
+ #unless attrs.key?(aname)
357
+ # raise "#{m}: attribute '#{aname}' expected but not found."
358
+ #end
359
+ avalue = attr_info[aname]
360
+ if avalue.is_a?(NativeExpression)
361
+ raise "#{m}: attribute value of '#{aname}' is NativeExpression object."
362
+ end
363
+ avalue
364
+ end
365
+ return new_code
366
+ end
367
+
368
+
369
+ ## expand attribute variables and return new NativeExpression
370
+ def expand_attr_vars_in_native_expr(native_expr, attr_info)
371
+ code = expand_attr_vars(native_expr.code, attr_info)
372
+ if code != native_expr.code
373
+ native_expr = NativeExpression.new(code, native_expr.escape)
374
+ end
375
+ return native_expr
376
+ end
377
+
378
+
379
+ ## expand attribute variables and return new NativeExpression
380
+ def expand_attr_vars_in_native_stmt(native_stmt, attr_info)
381
+ code = expand_attr_vars(native_stmt.code, attr_info)
382
+ if code != native_stmt.code
383
+ no_newline = native_stmt.no_newline
384
+ native_stmt = NativeStatement.new(code, native_stmt.kind)
385
+ native_stmt.no_newline = no_newline unless no_newline.nil?
386
+ end
387
+ return native_stmt
388
+ end
389
+
390
+
348
391
  ## build print statement of start-tag
349
- def stag_stmt(handler_arg)
350
- arg = handler_arg
351
- return build_print_stmt(arg.stag_info, arg.attr_info, arg.append_exprs)
392
+ def stag_stmt(elem_info)
393
+ e = elem_info
394
+ return build_print_stmt(e.stag_info, e.attr_info, e.append_exprs)
352
395
  end
353
396
 
354
397
 
355
398
  ## build print statemetn of end-tag
356
- def etag_stmt(handler_arg)
357
- arg = handler_arg
358
- return build_print_stmt(arg.etag_info, nil, nil)
399
+ def etag_stmt(elem_info)
400
+ return build_print_stmt(elem_info.etag_info, nil, nil)
359
401
  end
360
402
 
361
403
 
@@ -368,52 +410,50 @@ module Kwartz
368
410
  end
369
411
 
370
412
 
371
- def wrap_element_with_native_stmt(stmt_list, handler_arg, start_code, end_code, kind=nil)
413
+ def wrap_element_with_native_stmt(elem_info, stmt_list, start_code, end_code, kind=nil)
372
414
  add_native_code(stmt_list, start_code, kind)
373
- stmt_list << stag_stmt(handler_arg)
374
- stmt_list.concat(handler_arg.cont_stmts)
375
- stmt_list << etag_stmt(handler_arg)
415
+ stmt_list << stag_stmt(elem_info)
416
+ stmt_list.concat(elem_info.cont_stmts)
417
+ stmt_list << etag_stmt(elem_info)
376
418
  add_native_code(stmt_list, end_code, kind)
377
419
  end
378
420
 
379
421
 
380
- def wrap_content_with_native_stmt(stmt_list, handler_arg, start_code, end_code, kind=nil)
381
- stmt_list << stag_stmt(handler_arg)
422
+ def wrap_content_with_native_stmt(elem_info, stmt_list, start_code, end_code, kind=nil)
423
+ stmt_list << stag_stmt(elem_info)
382
424
  add_native_code(stmt_list, start_code, kind)
383
- stmt_list.concat(handler_arg.cont_stmts)
425
+ stmt_list.concat(elem_info.cont_stmts)
384
426
  add_native_code(stmt_list, end_code, kind)
385
- stmt_list << etag_stmt(handler_arg)
427
+ stmt_list << etag_stmt(elem_info)
386
428
  end
387
429
 
388
430
 
389
- def add_foreach_stmts(stmt_list, handler_arg, foreach_code, endforeach_code,
431
+ def add_foreach_stmts(elem_info, stmt_list, foreach_code, endforeach_code,
390
432
  content_only, counter, toggle, init_code, incr_code, toggle_code)
391
- arg = handler_arg
392
- stmt_list << stag_stmt(arg) if content_only
433
+ stmt_list << stag_stmt(elem_info) if content_only
393
434
  start_code.split(/\n/).each do |code|
394
435
  stmt_list << NativeStatement.new(code, kind)
395
436
  end if start_code
396
- stmt_list << stag_stmt(arg) if !content_only
397
- stmt_list.concat(arg.cont_stmts)
398
- stmt_list << etag_stmt(arg) if !content_only
437
+ stmt_list << stag_stmt(elem_info) if !content_only
438
+ stmt_list.concat(elem_info.cont_stmts)
439
+ stmt_list << etag_stmt(elem_info) if !content_only
399
440
  end_code.split(/\n/).each do |code|
400
441
  stmt_list << NativeStatement.new(code, kind)
401
442
  end
402
- stmt_list << etag_stmt(arg) if content_only
443
+ stmt_list << etag_stmt(elem_info) if content_only
403
444
  end
404
445
 
405
446
 
406
- def add_native_expr_with_default(stmt_list, handler_arg,
447
+ def add_native_expr_with_default(elem_info, stmt_list,
407
448
  expr_code, flag_escape,
408
449
  if_code, else_code, endif_code)
409
- arg = handler_arg
410
- stmt_list << stag_stmt(arg)
450
+ stmt_list << stag_stmt(elem_info)
411
451
  stmt_list << NativeStatement.new_without_newline(if_code, :if)
412
452
  stmt_list << PrintStatement.new([ NativeExpression.new(expr_code, flag_escape) ])
413
453
  stmt_list << NativeStatement.new_without_newline(else_code, :else)
414
- stmt_list.concat(arg.cont_stmts)
454
+ stmt_list.concat(elem_info.cont_stmts)
415
455
  stmt_list << NativeStatement.new_without_newline(endif_code, :else)
416
- stmt_list << etag_stmt(arg)
456
+ stmt_list << etag_stmt(elem_info)
417
457
  end
418
458
 
419
459
 
@@ -426,12 +466,12 @@ module Kwartz
426
466
  ##
427
467
  ## Handler class includes this module.
428
468
  ##
429
- module ElementExpander
469
+ module Expander
430
470
  include Assertion
431
471
 
432
472
 
433
- ## (abstract) get ElementRuleset
434
- def get_element_ruleset(name)
473
+ ## (abstract) get Ruleset
474
+ def get_ruleset(selector)
435
475
  not_implemented
436
476
  end
437
477
 
@@ -444,97 +484,109 @@ module Kwartz
444
484
 
445
485
  ## expand ElementInfo
446
486
  def expand_element_info(elem_info, stmt_list, content_only=false)
447
- #elem_ruleset = @ruleset_table[elem_info.name]
448
- elem_ruleset = get_element_ruleset(elem_info.name)
449
- if elem_ruleset && !elem_info.merged?
450
- elem_info.merge(elem_ruleset)
487
+ expand_statements(elem_info.before, stmt_list, elem_info) if elem_info.before
488
+ stmts = content_only ? [ ExpandStatement.new(:cont) ] : elem_info.logic
489
+ stmts.each do |stmt|
490
+ expand_statement(stmt, stmt_list, elem_info)
451
491
  end
452
- logic = content_only ? [ ExpandStatement.new(:cont, elem_info.name) ] : elem_info.logic
453
- logic.each do |stmt|
492
+ expand_statements(elem_info.after, stmt_list, elem_info) if elem_info.after
493
+ end
494
+
495
+
496
+ ## expand list of ExpandStatement
497
+ def expand_statements(stmts, stmt_list, elem_info)
498
+ stmts.each do |stmt|
454
499
  expand_statement(stmt, stmt_list, elem_info)
455
500
  end
456
- #if content_only
457
- # stmt = ExpandStatement.new(:cont, elem_info.name)
458
- # expand_statement(stmt, stmt_list, elem_info)
459
- #else
460
- # elem_info.logic.each do |stmt|
461
- # expand_statement(stmt, stmt_list, elem_info)
462
- # end
463
- #end
464
501
  end
465
502
 
466
503
 
467
504
  ## expand ExpandStatement
468
505
  def expand_statement(stmt, stmt_list, elem_info)
469
506
 
470
- if stmt.is_a?(ExpandStatement)
471
- e = elem_info
472
-
473
- ## delete dummy '<span>' tag
474
- if @delspan && e.stag_info.tagname == 'span' && e.attr_info.empty? && e.append_exprs.nil?
475
- e.stag_info.tagname = e.etag_info.tagname = nil
507
+ if stmt.is_a?(NativeStatement)
508
+ if elem_info
509
+ native_stmt = expand_attr_vars_in_native_stmt(stmt, elem_info.attr_info)
510
+ else
511
+ native_stmt = stmt
476
512
  end
513
+ stmt_list << native_stmt
514
+ return
515
+ end
477
516
 
478
- case stmt.kind
517
+ if ! stmt.is_a?(ExpandStatement)
518
+ stmt_list << stmt
519
+ return
520
+ end
479
521
 
480
- when :stag
481
- assert unless elem_info
482
- if e.stag_expr
483
- assert unless e.stag_expr.is_a?(NativeExpression)
484
- stmt_list << build_print_expr_stmt(e.stag_expr, e.stag_info, nil)
485
- else
486
- stmt_list << build_print_stmt(e.stag_info, e.attr_info, e.append_exprs)
487
- end
522
+ e = elem_info
488
523
 
489
- when :etag
490
- assert unless elem_info
491
- if e.etag_expr
492
- assert unless e.etag_expr.is_a?(NativeExpression)
493
- stmt_list << build_print_expr_stmt(e.etag_expr, nil, e.etag_info)
494
- elsif e.etag_info # e.etag_info is nil when <br>, <input>, <hr>, <img>, <meta>
495
- stmt_list << build_print_stmt(e.etag_info, nil, nil)
496
- end
524
+ ## remove dummy <span> tag
525
+ if @delspan && elem_info && elem_info.dummy_span_tag?('span')
526
+ #e.stag_info.tagname = e.etag_info.tagname = nil
527
+ e.stag_info.clear_as_dummy_tag()
528
+ e.etag_info.clear_as_dummy_tag()
529
+ end
497
530
 
498
- when :cont
499
- if e.cont_expr
500
- assert unless e.cont_expr.is_a?(NativeExpression)
501
- stmt_list << PrintStatement.new([e.cont_expr])
502
- else
503
- elem_info.cont_stmts.each do |cont_stmt|
504
- expand_statement(cont_stmt, stmt_list, nil)
505
- end
506
- end
531
+ case stmt.kind
507
532
 
508
- when :elem
509
- assert unless elem_info
510
- if e.elem_expr
511
- assert unless e.elem_expr.is_a?(NativeExpression)
512
- stmt_list << build_print_expr_stmt(e.elem_expr, e.stag_info, e.etag_info)
513
- else
514
- stmt.kind = :stag
515
- expand_statement(stmt, stmt_list, elem_info)
516
- stmt.kind = :cont
517
- expand_statement(stmt, stmt_list, elem_info)
518
- stmt.kind = :etag
519
- expand_statement(stmt, stmt_list, elem_info)
520
- stmt.kind = :elem
521
- end
533
+ when :stag
534
+ assert unless elem_info
535
+ if e.stag_expr
536
+ assert unless e.stag_expr.is_a?(NativeExpression)
537
+ stmt_list << build_print_expr_stmt(e.stag_expr, e.stag_info, nil, e.attr_info)
538
+ else
539
+ stmt_list << build_print_stmt(e.stag_info, e.attr_info, e.append_exprs)
540
+ end
541
+
542
+ when :etag
543
+ assert unless elem_info
544
+ if e.etag_expr
545
+ assert unless e.etag_expr.is_a?(NativeExpression)
546
+ stmt_list << build_print_expr_stmt(e.etag_expr, nil, e.etag_info, e.attr_info)
547
+ elsif e.etag_info # e.etag_info is nil when <br>, <input>, <hr>, <img>, <meta>
548
+ stmt_list << build_print_stmt(e.etag_info, nil, nil)
549
+ end
522
550
 
523
- when :element, :content
524
- content_only = stmt.kind == :content
525
- #elem_info = @elements[stmt.name]
526
- elem_info = get_element_info(stmt.name)
527
- unless elem_info
528
- raise convert_error("element '#{stmt.name}' is not found.", nil)
551
+ when :cont
552
+ if e.cont_expr
553
+ assert unless e.cont_expr.is_a?(NativeExpression)
554
+ #stmt_list << PrintStatement.new([e.cont_expr])
555
+ native_expr = expand_attr_vars_in_native_expr(e.cont_expr, e.attr_info)
556
+ stmt_list << PrintStatement.new([native_expr])
557
+ else
558
+ elem_info.cont_stmts.each do |cont_stmt|
559
+ expand_statement(cont_stmt, stmt_list, nil)
529
560
  end
530
- expand_element_info(elem_info, stmt_list, content_only)
561
+ end
531
562
 
563
+ when :elem
564
+ assert unless elem_info
565
+ if e.elem_expr
566
+ assert unless e.elem_expr.is_a?(NativeExpression)
567
+ stmt_list << build_print_expr_stmt(e.elem_expr, e.stag_info, e.etag_info, e.attr_info)
532
568
  else
533
- assert
534
- end #case
569
+ stmt.kind = :stag
570
+ expand_statement(stmt, stmt_list, elem_info)
571
+ stmt.kind = :cont
572
+ expand_statement(stmt, stmt_list, elem_info)
573
+ stmt.kind = :etag
574
+ expand_statement(stmt, stmt_list, elem_info)
575
+ stmt.kind = :elem
576
+ end
577
+
578
+ when :element, :content
579
+ content_only = stmt.kind == :content
580
+ #elem_info = @elements[stmt.name]
581
+ elem_info = get_element_info(stmt.name)
582
+ unless elem_info
583
+ raise convert_error("element '#{stmt.name}' is not found.", nil)
584
+ end
585
+ expand_element_info(elem_info, stmt_list, content_only)
586
+
535
587
  else
536
- stmt_list << stmt
537
- end #if
588
+ assert
589
+ end #case
538
590
  end
539
591
 
540
592
 
@@ -543,27 +595,21 @@ module Kwartz
543
595
 
544
596
 
545
597
  ##
546
- ## argument data for handler
598
+ ## directive
547
599
  ##
548
- class HandlerArgument
549
- include StatementHelper
600
+ class Directive
550
601
 
551
602
 
552
- def initialize(directive_name, directive_arg, directive_str,
553
- stag_info, etag_info, cont_stmts, attr_info, append_exprs)
554
- @directive_name = directive_name
555
- @directive_arg = directive_arg
556
- @directive_str = directive_str
557
- @stag_info = stag_info
558
- @etag_info = etag_info
559
- @cont_stmts = cont_stmts
560
- @attr_info = attr_info
561
- @append_exprs = append_exprs
603
+ def initialize(args={})
604
+ @name = args[:name]
605
+ @arg = args[:arg]
606
+ @dattr = args[:dattr]
607
+ @str = args[:str]
608
+ @linenum = args[:linenum]
562
609
  end
563
610
 
564
611
 
565
- attr_reader :directive_name, :directive_arg, :directive_str
566
- attr_reader :stag_info, :etag_info, :cont_stmts, :attr_info, :append_exprs
612
+ attr_accessor :name, :arg, :dattr, :str, :linenum
567
613
 
568
614
 
569
615
  end
@@ -575,35 +621,47 @@ module Kwartz
575
621
  ##
576
622
  class Handler
577
623
  include Assertion
578
- include ConverterHelper
579
- include StatementHelper
580
- include ElementExpander
624
+ include ConvertErrorHelper
625
+ include HandlerHelper
626
+ include Expander
581
627
 
582
628
 
583
- def initialize(elem_rulesets=[], properties={})
584
- @elem_rulesets = elem_rulesets
585
- #@elem_ruleset_table = elem_rulesets.inject({}) { |table, ruleset| table[ruleset.name] = ruleset; table }
586
- @elem_ruleset_table = {} ; elem_rulesets.each { |ruleset| @elem_ruleset_table[ruleset.name] = ruleset }
629
+ def initialize(rulesets=[], properties={})
630
+ @ruleset_table = {}
631
+ rulesets.each { |ruleset| _register_ruleset(ruleset) }
587
632
  @elem_info_table = {}
588
- include_properties(properties) # @delspan and @dattr
589
- @odd = properties[:odd] || Config::PROPERTY_ODD # "'odd'"
590
- @even = properties[:even] || Config::PROPERTY_EVEN # "'even'"
591
- @filename = nil
633
+ @delspan = properties.fetch(:delspan, Config::PROPERTY_DELSPAN) # delete dummy <span> tag or not
634
+ @odd = properties.fetch(:odd, Config::PROPERTY_ODD) # "'odd'"
635
+ @even = properties.fetch(:even, Config::PROPERTY_EVEN) # "'even'"
592
636
  end
593
637
  attr_reader :odd, :even
594
- attr_accessor :converter, :filename
638
+ attr_accessor :filename
595
639
 
596
640
 
597
- def get_element_ruleset(name) # for ElementExpander module and Converter class
598
- return @elem_ruleset_table[name]
641
+ def _register_ruleset(ruleset)
642
+ ruleset.selectors.each do |selector|
643
+ r = @ruleset_table[selector]
644
+ @ruleset_table[selector] = r ? r.merge(ruleset) : ruleset
645
+ end
599
646
  end
647
+ private :_register_ruleset
648
+
600
649
 
650
+ def get_ruleset(selector) # for Expander module and Converter class
651
+ return @ruleset_table[selector]
652
+ end
601
653
 
602
- def get_element_info(name) # for ElementExpander module
654
+
655
+ def get_element_info(name) # for Expander module
603
656
  return @elem_info_table[name]
604
657
  end
605
658
 
606
659
 
660
+ def register_element_info(name, elem_info)
661
+ @elem_info_table[name] = elem_info
662
+ end
663
+
664
+
607
665
  def _elem_info_table # :nodoc:
608
666
  return @elem_info_table
609
667
  end
@@ -640,97 +698,158 @@ module Kwartz
640
698
  end
641
699
 
642
700
 
643
- ## (abstract) directive format, which is used at has_directive?() method
644
- def directive_format
701
+ ## (abstract) convert universal expression string to native expression string
702
+ def parse_expr_str(expr_str, linenum)
645
703
  not_implemented
646
- #return '%s: %s'
647
704
  end
648
705
 
649
706
 
650
707
  public
651
708
 
652
709
 
710
+ def handle_directives(directive, elem_info, stmt_list)
711
+ e = elem_info
712
+ linenum = elem_info.stag_info.linenum
713
+ append_exprs = nil
714
+
715
+ if directive.dattr == 'id'
716
+ ## nothing
717
+ else
718
+ ## handle 'attr:' and 'append:' directives
719
+ d_str = nil
720
+ directive.str.split(/;/).each do |d_str|
721
+ d_str.strip!
722
+ unless d_str =~ self.directive_pattern # ex. /\A(\w+):\s*(.*)\z/
723
+ raise convert_error("'#{d_str}': invalid directive pattern", linenum)
724
+ end
725
+ d_name = $1.intern # directive name
726
+ d_arg = $2 || '' # directive arg
727
+ case d_name
728
+ when :attr, :Attr, :ATTR
729
+ directive2 = Directive.new(:name=>d_name, :arg=>d_arg, :sr=>d_str)
730
+ handle(directive2, elem_info, stmt_list)
731
+ when :append, :Append, :APPEND
732
+ append_exprs ||= []
733
+ elem_info.append_exprs = append_exprs
734
+ directive2 = Directive.new(:name=>d_name, :arg=>d_arg, :sr=>d_str)
735
+ handle(directive2, elem_info, stmt_list)
736
+ else
737
+ if directive.name
738
+ raise convert_error("'#{d_str}': not available with '#{directive.name}' directive.", linenum)
739
+ end
740
+ directive.name = d_name
741
+ directive.arg = d_arg
742
+ directive.str = d_str
743
+ end #case
744
+ end
745
+ end
746
+
747
+ ## remove dummy <span> tag
748
+ if @delspan && elem_info.dummy_span_tag?('span')
749
+ #e.stag_info.tagname = e.etag_info.tagname = nil
750
+ e.stag_info.clear_as_dummy_tag()
751
+ e.etag_info.clear_as_dummy_tag()
752
+ end
753
+
754
+ ## handle other directives
755
+ if directive.name
756
+ handled = handle(directive, elem_info, stmt_list)
757
+ handled or raise convert_error("'#{directive.str}': unknown directive.", linenum)
758
+ else # for 'attr' and 'append' directive
759
+ assert unless !elem_info.attr_info.empty? || !elem_info.append_exprs.empty?
760
+ stmt_list << stag_stmt(elem_info)
761
+ stmt_list.concat(elem_info.cont_stmts)
762
+ stmt_list << etag_stmt(elem_info) if elem_info.etag_info # when empty-tag
763
+ end
764
+
765
+ end
766
+
767
+
653
768
  ## handle directives ('stag', 'etag', 'elem', 'cont'(='value'))
654
769
  ##
655
770
  ## return true if directive name is one of 'stag', 'etag', 'elem', 'cont', and 'value',
656
771
  ## else return false.
657
- def handle(stmt_list, handler_arg)
658
- arg = handler_arg
659
- d_name = arg.directive_name
660
- d_arg = arg.directive_arg
661
- d_str = arg.directive_str
772
+ def handle(directive, elem_info, stmt_list)
773
+ d_name = directive.name
774
+ d_arg = directive.arg
775
+ d_str = directive.str
776
+ d_attr = directive.dattr
777
+ e = elem_info
778
+ linenum = e.stag_info.linenum
662
779
 
663
780
  case d_name
664
781
 
665
782
  when nil
666
- assert unless !arg.attr_info.empty? || !arg.append_exprs.empty?
667
- stmt_list << stag_stmt(arg)
668
- stmt_list.concat(arg.cont_stmts)
669
- stmt_list << etag_stmt(arg) if arg.etag_info # when empty-tag
783
+ assert false
670
784
 
671
785
  when :dummy
672
786
  # nothing
673
787
 
674
788
  when :id, :mark
675
- unless d_arg =~ /\A(\w+)\z/ || d_arg =~ /\A'(\w+)'\z/
676
- raise convert_error("'#{d_str}': invalid marking name.", arg.stag_info.linenum)
789
+ unless d_arg =~ /\A([-\w]+)\z/ || d_arg =~ /\A'([-\w]+)'\z/
790
+ raise convert_error("'#{d_str}': invalid marking name.", linenum)
677
791
  end
678
792
  name = $1
679
- elem_info = ElementInfo.new(name, arg.stag_info, arg.etag_info, arg.cont_stmts,
680
- arg.attr_info, arg.append_exprs)
681
- if @elem_info_table[name]
682
- #unless Config::ALLOW_DUPLICATE_ID
683
- previous_linenum = @elem_info_table[name].stag_info.linenum
793
+ if get_element_info(name)
794
+ unless Config::ALLOW_DUPLICATE_ID
795
+ previous_linenum = get_element_info(name).stag_info.linenum
684
796
  msg = "'#{d_str}': id '#{name}' is already used at line #{previous_linenum}."
685
- raise convert_error(msg, arg.stag_info.linenum)
686
- #end
687
- else
688
- @elem_info_table[name] = elem_info
797
+ raise convert_error(msg, linenum)
798
+ end
689
799
  end
800
+ ruleset = get_ruleset('#' + name)
801
+ elem_info.apply(ruleset) if ruleset
802
+ register_element_info(name, elem_info)
690
803
  #stmt_list << ExpandStatement.new(:element, name) # lazy expantion
691
804
  expand_element_info(elem_info, stmt_list)
692
805
 
693
806
  when :stag, :Stag, :STAG
694
- error_if_empty_tag(arg)
807
+ error_if_empty_tag(elem_info, d_str)
695
808
  flag_escape = d_name == :stag ? nil : (d_name == :Stag)
696
- expr = NativeExpression.new(d_arg, flag_escape)
697
- stmt_list << build_print_expr_stmt(expr, arg.stag_info, nil)
698
- stmt_list.concat(arg.cont_stmts)
699
- stmt_list << etag_stmt(arg)
809
+ expr_str = d_attr == 'id' ? parse_expr_str(d_arg, linenum) : d_arg
810
+ expr = NativeExpression.new(expr_str, flag_escape)
811
+ stmt_list << build_print_expr_stmt(expr, e.stag_info, nil)
812
+ stmt_list.concat(e.cont_stmts)
813
+ stmt_list << etag_stmt(elem_info)
700
814
 
701
815
  when :etag, :Etag, :ETAG
702
- error_if_empty_tag(arg)
816
+ error_if_empty_tag(elem_info, d_str)
703
817
  flag_escape = d_name == :etag ? nil : (d_name == :Etag)
704
- expr = NativeExpression.new(d_arg, flag_escape)
705
- stmt_list << stag_stmt(arg)
706
- stmt_list.concat(arg.cont_stmts)
707
- stmt_list << build_print_expr_stmt(expr, nil, arg.etag_info)
818
+ expr_str = d_attr == 'id' ? parse_expr_str(d_arg, linenum) : d_arg
819
+ expr = NativeExpression.new(expr_str, flag_escape)
820
+ stmt_list << stag_stmt(elem_info)
821
+ stmt_list.concat(e.cont_stmts)
822
+ stmt_list << build_print_expr_stmt(expr, nil, e.etag_info)
708
823
 
709
824
  when :elem, :Elem, :ELEM
710
825
  flag_escape = d_name == :elem ? nil : (d_name == :Elem)
711
- expr = NativeExpression.new(d_arg, flag_escape)
712
- stmt_list << build_print_expr_stmt(expr, arg.stag_info, arg.etag_info)
826
+ expr_str = d_attr == 'id' ? parse_expr_str(d_arg, linenum) : d_arg
827
+ expr = NativeExpression.new(expr_str, flag_escape)
828
+ stmt_list << build_print_expr_stmt(expr, e.stag_info, e.etag_info)
713
829
 
714
830
  when :cont, :Cont, :CONT, :value, :Value, :VALUE
715
- error_if_empty_tag(arg)
716
- arg.stag_info.tail_space = arg.etag_info.head_space = nil # delete spaces
717
- pargs = build_print_args(arg.stag_info, arg.attr_info, arg.append_exprs)
831
+ error_if_empty_tag(elem_info, directive.str)
832
+ e.stag_info.tail_space = e.etag_info.head_space = nil # delete spaces
833
+ pargs = build_print_args(e.stag_info, e.attr_info, e.append_exprs)
718
834
  flag_escape = (d_name == :cont || d_name == :value) ? nil : (d_name == :Cont || d_name == :Value)
719
- pargs << NativeExpression.new(d_arg, flag_escape)
720
- pargs << arg.etag_info.tag_text if arg.etag_info.tagname
835
+ expr_str = d_attr == 'id' ? parse_expr_str(d_arg, linenum) : d_arg
836
+ pargs << NativeExpression.new(expr_str, flag_escape)
837
+ pargs << e.etag_info.tag_text if e.etag_info.tagname
721
838
  stmt_list << PrintStatement.new(pargs)
722
839
 
723
840
  when :attr, :Attr, :ATTR
724
841
  unless d_arg =~ self.mapping_pattern() # ex. /\A'([-:\w]+)'\s+(.*)\z/
725
- raise convert_error("'#{d_str}': invalid attr pattern.", arg.stag_info.linenum)
842
+ raise convert_error("'#{d_str}': invalid attr pattern.", linenum)
726
843
  end
727
844
  aname = $1; avalue = $2
728
845
  flag_escape = d_name == :attr ? nil : (d_name == :Attr)
729
- arg.attr_info[aname] = NativeExpression.new(avalue, flag_escape)
846
+ expr_str = d_attr == 'id' ? parse_expr_str(avalue, linenum) : avalue
847
+ e.attr_info[aname] = NativeExpression.new(expr_str, flag_escape)
730
848
 
731
849
  when :append, :Append, :APPEND
732
850
  flag_escape = d_name == :append ? nil : (d_name == :Append)
733
- arg.append_exprs << NativeExpression.new(d_arg, flag_escape)
851
+ expr_str = d_attr == 'id' ? parse_expr_str(d_arg, linenum) : d_arg
852
+ e.append_exprs << NativeExpression.new(expr_str, flag_escape)
734
853
 
735
854
  when :replace_element_with_element, :replace_element_with_content,
736
855
  :replace_content_with_element, :replace_content_with_content
@@ -739,35 +858,35 @@ module Kwartz
739
858
  with_content = arr[3] == 'content'
740
859
  name = d_arg
741
860
  #
742
- error_if_empty_tag(arg) if replace_cont
743
- stmt_list << stag_stmt(arg) if replace_cont
861
+ error_if_empty_tag(elem_info, d_str) if replace_cont
862
+ stmt_list << stag_stmt(elem_info) if replace_cont
744
863
  #stmt_list << ExpandStatement.new(:element, name)
745
- elem_info = @elem_info_table[name]
864
+ elem_info2 = @elem_info_table[name]
746
865
  unless elem_info
747
- raise convert_error("'#{d_str}': element '#{name}' not found.", arg.stag_info.linenum)
866
+ raise convert_error("'#{d_str}': element '#{name}' not found.", linenum)
748
867
  end
749
- expand_element_info(elem_info, stmt_list, with_content)
750
- stmt_list << etag_stmt(arg) if replace_cont
868
+ expand_element_info(elem_info2, stmt_list, with_content)
869
+ stmt_list << etag_stmt(elem_info) if replace_cont
751
870
 
752
871
  when :replace_element_with, :replace_content_with, :replace, :placeholder
753
872
  unless d_arg =~ /\A_?(element|content)\(["']?(\w+)["']?\)\z/
754
- raise convert_error("'#{d_str}': invalid #{d_name} format.", stag_info.linenum)
873
+ raise convert_error("'#{d_str}': invalid #{d_name} format.", linenum)
755
874
  end
756
875
  kind = $1
757
876
  name = $2
758
877
  replace_cont = d_name == :replace_content_with || d_name == :placeholder
759
878
  with_content = kind == 'content'
760
879
  #
761
- error_if_empty_tag(arg) if replace_cont
762
- stmt_list << stag_stmt(arg) if replace_cont
880
+ error_if_empty_tag(elem_info, d_str) if replace_cont
881
+ stmt_list << stag_stmt(elem_info) if replace_cont
763
882
  #stmt_list << ExpandStatement.new(:element, name)
764
- elem_info = @elem_info_table[name]
765
- unless elem_info
883
+ elem_info2 = @elem_info_table[name]
884
+ unless elem_info2
766
885
  msg = "'#{d_str}': element '#{name}' not found."
767
- raise convert_error(msg, arg.stag_info.linenum)
886
+ raise convert_error(msg, linenum)
768
887
  end
769
- expand_element_info(elem_info, stmt_list, with_content)
770
- stmt_list << etag_stmt(arg) if replace_cont
888
+ expand_element_info(elem_info2, stmt_list, with_content)
889
+ stmt_list << etag_stmt(elem_info) if replace_cont
771
890
 
772
891
  else
773
892
  return false
@@ -778,6 +897,19 @@ module Kwartz
778
897
  end
779
898
 
780
899
 
900
+ def apply_rulesets(elem_info)
901
+ assert unless !elem_info.applied
902
+ elem_info.applied = true
903
+ tagname = elem_info.stag_info.tagname
904
+ classname = elem_info.attr_info['class']
905
+ #idname = elem_info.name || elem_info.attr_info['id']
906
+ ruleset = nil
907
+ elem_info.apply(ruleset) if ruleset = get_ruleset(tagname)
908
+ elem_info.apply(ruleset) if classname && (ruleset = get_ruleset('.'+classname))
909
+ #elem_info.apply(ruleset) if idname && (ruleset = get_ruleset('#'+idname))
910
+ end
911
+
912
+
781
913
  def extract(elem_name, content_only=false)
782
914
  elem_info = @elem_info_table[elem_name]
783
915
  elem_info or raise convert_error("element '#{elem_name}' not found.", nil)
@@ -809,13 +941,11 @@ module Kwartz
809
941
  ## (abstract) covnert presentation data into list of Statement.
810
942
  ##
811
943
  class Converter
812
- include ConverterHelper
813
- include StatementHelper
944
+ include ConvertErrorHelper
814
945
 
815
946
 
816
947
  def initialize(handler, properties={})
817
948
  @handler = handler
818
- @handler.converter = self
819
949
  end
820
950
 
821
951
  attr_reader :handler #, :dattr, :input
@@ -853,7 +983,7 @@ module Kwartz
853
983
 
854
984
  def initialize(handler, properties={})
855
985
  super
856
- include_properties(properties) # set @delspan and @dattr
986
+ @dattr = properties.fetch(:dattr, Config::PROPERTY_DATTR) # default: 'kw:d'
857
987
  end
858
988
 
859
989
 
@@ -868,18 +998,28 @@ module Kwartz
868
998
  end
869
999
  protected :reset
870
1000
 
1001
+
871
1002
  attr_reader :rest, :linenum
872
1003
 
873
1004
 
874
1005
  def convert(input, filename='')
875
1006
  reset(input, filename)
876
1007
  stmt_list = []
877
- doc_ruleset = @handler.get_element_ruleset('DOCUMENT')
878
- stmt_list += doc_ruleset.begin if doc_ruleset && doc_ruleset.begin
879
- #stmt_list << NativeStatement.new(doc_ruleset.head.chomp, nil) if doc_ruleset && doc_ruleset.head
880
1008
  _convert(stmt_list)
881
- stmt_list += doc_ruleset.end if doc_ruleset && doc_ruleset.end
882
- #stmt_list << NativeStatement.new(doc_ruleset.tail.chomp, nil) if doc_ruleset && doc_ruleset.tail
1009
+ ruleset = @handler.get_ruleset('#DOCUMENT')
1010
+ if ruleset
1011
+ stmt_list2 = []
1012
+ elem_info = nil
1013
+ r = ruleset
1014
+ @handler.expand_statements(r.before, stmt_list2, elem_info) if r.before
1015
+ if r.logic
1016
+ @handler.expand_statements(r.logic, stmt_list2, elem_info)
1017
+ else
1018
+ stmt_list2.concat(stmt_list)
1019
+ end
1020
+ @handler.expand_statements(r.after, stmt_list2, elem_info) if r.after
1021
+ stmt_list = stmt_list2
1022
+ end
883
1023
  return stmt_list
884
1024
  end
885
1025
 
@@ -896,10 +1036,19 @@ module Kwartz
896
1036
  end
897
1037
 
898
1038
 
1039
+ def match_ruleset(taginfo, attr_info)
1040
+ idname = attr_info['id']
1041
+ return true if idname && @handler.get_ruleset("#"+idname)
1042
+ classname = attr_info['class']
1043
+ return true if classname && @handler.get_ruleset("."+classname)
1044
+ return @handler.get_ruleset(taginfo.tagname) ? true : false
1045
+ end
1046
+
1047
+
899
1048
  private
900
1049
 
901
1050
 
902
- def fetch
1051
+ def _fetch
903
1052
  str = @scanner.scan(@@fetch_pattern)
904
1053
  unless str
905
1054
  @rest = @scanner.scan(/.*/m)
@@ -918,11 +1067,11 @@ module Kwartz
918
1067
  start_linenum = @linenum
919
1068
 
920
1069
  ##
921
- while taginfo = fetch()
1070
+ while taginfo = _fetch()
922
1071
  #tag_text, prev_text, head_space, is_etag, tagname, attr_str, extra_space, is_empty, tail_space = taginfo.to_a
923
1072
 
924
1073
  prev_text = taginfo.prev_text
925
- stmt_list << create_text_print_stmt(prev_text) if prev_text && !prev_text.empty?
1074
+ stmt_list << _create_text_print_stmt(prev_text) if prev_text && !prev_text.empty?
926
1075
 
927
1076
  if taginfo.is_etag? # end tag
928
1077
 
@@ -930,36 +1079,49 @@ module Kwartz
930
1079
  etag_info = taginfo
931
1080
  return etag_info
932
1081
  else
933
- stmt_list << create_text_print_stmt(taginfo.tag_text)
1082
+ stmt_list << _create_text_print_stmt(taginfo.tag_text)
934
1083
  end
935
1084
 
936
1085
  elsif taginfo.is_empty? || skip_etag?(taginfo) # empty tag
937
1086
 
938
1087
  attr_info = AttrInfo.new(taginfo.attr_str)
939
- if has_directive?(attr_info, taginfo)
1088
+ directive = _get_directive(attr_info, taginfo)
1089
+ if directive
940
1090
  stag_info = taginfo
941
1091
  etag_info = nil
942
1092
  cont_stmts = []
943
- handle_directive(stag_info, etag_info, cont_stmts, attr_info, stmt_list)
1093
+ elem_info = ElementInfo.new(stag_info, etag_info, cont_stmts, attr_info, nil)
1094
+ @handler.apply_rulesets(elem_info)
1095
+ @handler.handle_directives(directive, elem_info, stmt_list)
944
1096
  else
945
- stmt_list << create_text_print_stmt(taginfo.tag_text)
1097
+ stmt_list << _create_text_print_stmt(taginfo.tag_text)
946
1098
  end
947
1099
 
948
1100
  else # start tag
949
1101
 
950
1102
  attr_info = AttrInfo.new(taginfo.attr_str)
951
- if has_directive?(attr_info, taginfo)
1103
+ directive = _get_directive(attr_info, taginfo)
1104
+ if directive
952
1105
  stag_info = taginfo
953
1106
  cont_stmts = []
954
- etag_info = _convert(cont_stmts, taginfo)
955
- handle_directive(stag_info, etag_info, cont_stmts, attr_info, stmt_list)
1107
+ etag_info = _convert(cont_stmts, stag_info)
1108
+ elem_info = ElementInfo.new(stag_info, etag_info, cont_stmts, attr_info, nil)
1109
+ @handler.apply_rulesets(elem_info)
1110
+ @handler.handle_directives(directive, elem_info, stmt_list)
1111
+ elsif match_ruleset(taginfo, attr_info)
1112
+ stag_info = taginfo
1113
+ cont_stmts = []
1114
+ etag_info = _convert(cont_stmts, stag_info)
1115
+ elem_info = ElementInfo.new(stag_info, etag_info, cont_stmts, attr_info, nil)
1116
+ @handler.apply_rulesets(elem_info)
1117
+ @handler.expand_element_info(elem_info, stmt_list)
956
1118
  elsif taginfo.tagname == start_tagname
957
1119
  stag_info = taginfo
958
- stmt_list << create_text_print_stmt(stag_info.tag_text)
1120
+ stmt_list << _create_text_print_stmt(stag_info.tag_text)
959
1121
  etag_info = _convert(stmt_list, stag_info)
960
- stmt_list << create_text_print_stmt(etag_info.tag_text)
1122
+ stmt_list << _create_text_print_stmt(etag_info.tag_text)
961
1123
  else
962
- stmt_list << create_text_print_stmt(taginfo.tag_text)
1124
+ stmt_list << _create_text_print_stmt(taginfo.tag_text)
963
1125
  end
964
1126
 
965
1127
  end #if
@@ -970,64 +1132,14 @@ module Kwartz
970
1132
  raise convert_error("'<#{start_tagname}>' is not closed.", start_tag_info.linenum)
971
1133
  end
972
1134
 
973
- stmt_list << create_text_print_stmt(@rest) if @rest
1135
+ stmt_list << _create_text_print_stmt(@rest) if @rest && ! @rest.empty?
974
1136
  nil
975
1137
 
976
1138
  end #def
977
1139
 
978
1140
 
979
- def handle_directive(stag_info, etag_info, cont_stmts, attr_info, stmt_list)
980
- directive_name = directive_arg = directive_str = nil
981
- append_exprs = nil
982
-
983
- ## handle 'attr:' and 'append:' directives
984
- d_str = nil
985
- attr_info.directive.split(/;/).each do |d_str|
986
- d_str.strip!
987
- unless d_str =~ @handler.directive_pattern # ex. /\A(\w+):\s*(.*)\z/
988
- raise convert_error("'#{d_str}': invalid directive pattern", stag_info.linenum)
989
- end
990
- d_name = $1.intern # directive name
991
- d_arg = $2 || '' # directive arg
992
- case d_name
993
- when :attr, :Attr, :ATTR
994
- handler_args = HandlerArgument.new(d_name, d_arg, d_str, stag_info, etag_info,
995
- cont_stmts, attr_info, append_exprs)
996
- @handler.handle(stmt_list, handler_args)
997
- when :append, :Append, :APPEND
998
- append_exprs ||= []
999
- handler_args = HandlerArgument.new(d_name, d_arg, d_str, stag_info, etag_info,
1000
- cont_stmts, attr_info, append_exprs)
1001
- @handler.handle(stmt_list, handler_args)
1002
- else
1003
- if directive_name
1004
- raise convert_error("'#{d_str}': not available with '#{directive_name}' directive.", stag_info.linenum)
1005
- end
1006
- directive_name = d_name
1007
- directive_arg = d_arg
1008
- directive_str = d_str
1009
- end #case
1010
- end if attr_info.directive
1011
-
1012
- ## remove dummy <span> tag
1013
- if @delspan && stag_info.tagname == 'span' && attr_info.empty? && append_exprs.nil? && directive_name != :id
1014
- stag_info.tagname = etag_info.tagname = nil
1015
- end
1016
-
1017
- ## handle other directives
1018
- handler_args = HandlerArgument.new(directive_name, directive_arg, directive_str,
1019
- stag_info, etag_info, cont_stmts,
1020
- attr_info, append_exprs)
1021
- ret = @handler.handle(stmt_list, handler_args)
1022
- if directive_name && !ret
1023
- raise convert_error("'#{directive_str}': unknown directive.", stag_info.linenum)
1024
- end
1025
-
1026
- end
1027
-
1028
-
1029
- ## detect whether directive is exist or not
1030
- def has_directive?(attr_info, taginfo)
1141
+ ## get directive object
1142
+ def _get_directive(attr_info, taginfo)
1031
1143
  ## kw:d attribute
1032
1144
  val = attr_info[@dattr] # ex. @dattr == 'kw:d'
1033
1145
  if val && val.is_a?(String) && !val.empty?
@@ -1037,8 +1149,9 @@ module Kwartz
1037
1149
  #return false
1038
1150
  elsif val =~ @handler.directive_pattern() # ex. /\A(\w+):\s*(.*)/
1039
1151
  attr_info.delete(@dattr)
1040
- attr_info.directive = val
1041
- return true
1152
+ #directive = Directive.new(:name=>$1.intern, :arg=>$2, :dattr=>@dattr, :str=>val)
1153
+ directive = Directive.new(:dattr=>@dattr, :str=>val)
1154
+ return directive
1042
1155
  else
1043
1156
  raise convert_error("'#{@dattr}=\"#{val}\"': invalid directive pattern.", taginfo.linenum)
1044
1157
  end
@@ -1047,21 +1160,22 @@ module Kwartz
1047
1160
  val = attr_info['id']
1048
1161
  if val
1049
1162
  case val
1050
- when /\A\w+\z/
1051
- attr_info.directive = @handler.directive_format() % ['mark', val]
1052
- return true
1053
- #when @handler.directive_pattern() # ex. /\A\w+:/
1163
+ when /\A[-\w]+\z/
1164
+ directive = Directive.new(:name=>:mark, :arg=>val, :dattr=>'id', :str=>val)
1165
+ return directive
1166
+ #when @handler.directive_pattern() # ex. /\A(\w+):(.*)/
1054
1167
  # attr_info.delete('id')
1055
- # attr_info.directive = val
1056
- # return true
1057
- when /\A(mark|dummy):(\w+)\z/,
1058
- /\A(replace_(?:element|content)_with_(?:element|content)):(\w+)\z/
1059
- attr_info.directive = @handler.directive_format() % [$1, $2]
1168
+ # directive = Directive.new(:name=>$1.intern, :arg=>$2, :dattr=>'id', :str=>val)
1169
+ # return directive
1170
+ when /\A(mark|dummy):([-\w]+)\z/,
1171
+ /\A(value|stag|cont|etag|elem|default):(.*)\z/i,
1172
+ /\A(replace_[a-z]+_with_[a-z]+):([-\w]+)\z/
1060
1173
  attr_info.delete('id')
1061
- return true
1174
+ directive = Directive.new(:name=>$1.intern, :arg=>$2, :dattr=>'id', :str=>val)
1175
+ return directive
1062
1176
  end
1063
1177
  end
1064
- return false
1178
+ return nil
1065
1179
  end
1066
1180
 
1067
1181
 
@@ -1075,6 +1189,12 @@ module Kwartz
1075
1189
  end
1076
1190
 
1077
1191
 
1192
+ def _create_text_print_stmt(text)
1193
+ return PrintStatement.new([text])
1194
+ #return PritnStatement.new([TextExpression.new(text)])
1195
+ end
1196
+
1197
+
1078
1198
  end #class
1079
1199
  Converter.register_class('text', TextConverter)
1080
1200