trac-wiki 0.2.16 → 0.2.20

Sign up to get free protection for your applications and to get access to all the features.
data/lib/trac-wiki.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'trac-wiki/parser'
2
2
  require 'trac-wiki/tree'
3
3
  require 'trac-wiki/version'
4
+ require 'trac-wiki/env'
4
5
 
5
6
  module TracWiki
6
7
  # Convert the argument in Trac format to HTML and return the
@@ -0,0 +1,256 @@
1
+ module TracWiki
2
+
3
+ class Env
4
+ def initialize(parser, env = {})
5
+ @parser = parser
6
+ @env = env
7
+ end
8
+
9
+ def parse_macro_all(macro_name, str)
10
+ #print "macro_all: #{macro_name}, str:#{str}.\n"
11
+ if macro_name =~ /\A!/
12
+ # {{!cmd}}
13
+ mac_out, rest, lines = parse_macro_cmd(macro_name, str)
14
+ else
15
+ # {{$cmd}}, {{template}}, ...
16
+ mac_out, rest, lines = parse_macro_vartempl(macro_name, str)
17
+ end
18
+ return mac_out || '', rest, lines
19
+ end
20
+
21
+ # read to args to }} (while balancing {{ and }})
22
+ # ret: (arg, rest, lines)
23
+ # mac_out -- string to }} (macros inside expanded)
24
+ # rest -- str aftrer }}
25
+ # lines -- howmany \n eaten from str (from begining to }})
26
+ def parse_macro_vartempl(macro_name, str)
27
+ str_orig = str
28
+ lines = 0
29
+ arg = ''
30
+ # FIXME: MACRO_REX
31
+ # prefix }}... {{macro_name
32
+ while str =~ TracWiki::Parser::MACRO_END_REX
33
+ prefix, bracket, sub_macro_name, str = $1, $2, $3, $'
34
+ arg << prefix
35
+ lines += prefix.count("\n")
36
+ if bracket == '}}'
37
+ #print "prefix: #{prefix}\n"
38
+ return do_macro_var($1, arg), str, lines if macro_name =~ /^\$(.*)/
39
+ return do_macro_templ(macro_name, arg), str, lines
40
+ end
41
+
42
+ # we need to go deeper!
43
+ mac_out, str, l = parse_macro_all(sub_macro_name, str)
44
+ arg << mac_out
45
+ lines += l
46
+ end
47
+ print "Error parsing macro(#{macro_name}) near '#{str}'(#{str_orig}) (arg:#{arg}, lines=#{lines})\n"
48
+ raise "Error parsing macro near '#{str}' (arg:#{arg}, lines=#{lines})"
49
+ end
50
+
51
+ # parse to next }} (with balanced {{..}})
52
+ # like parse_macro_vartempl but not expand content
53
+ # r: [expansion, rest_of_str, count_of_consumed_lines]
54
+ def parse_macro_cmd(macro_name, str)
55
+ str.sub!(/\A\s*\|?/, '')
56
+ return do_macro_cmd(macro_name, []), $', 0 if str =~ /\A}}/
57
+ #print "parse_macro_cmd: #{macro_name}, str#{str}\n"
58
+ dep = 0
59
+ lines = 0
60
+ args = ['']
61
+ while str =~ /{{|}}|\|/
62
+ prefix, match, str = $`, $&, $'
63
+ args[-1] += prefix
64
+ lines += prefix.count("\n")
65
+ if match == '{{'
66
+ dep += 1
67
+ args[-1] += $&
68
+ elsif match == '}}'
69
+ dep -= 1
70
+ return do_macro_cmd(macro_name, args), str, lines if dep < 0
71
+ args[-1] += $&
72
+ elsif match == '|' && dep == 0
73
+ args.push('')
74
+ else
75
+ args[-1] += $&
76
+ end
77
+ end
78
+ raise "eol in parsing macro params"
79
+ end
80
+
81
+ # calls {{!cmd}} (if exists
82
+ # r: result of {{!cmd}}
83
+ def do_macro_cmd(macro_name, args)
84
+ return '|' if macro_name == '!'
85
+ if @parser.plugins.key?(macro_name)
86
+ @env['args'] = args
87
+ @env['arg0'] = macro_name
88
+ #print "mac: #{macro_name} env:" ; pp (@env)
89
+ ret = @parser.plugins[macro_name].call(self)
90
+ return ret
91
+ end
92
+ "UCMD(#{macro_name}|#{@env['arg']})"
93
+ end
94
+ def arg(idx)
95
+ @env['args'][idx] || ''
96
+ end
97
+
98
+ def prepare_y
99
+ #print "prepare_y\n"
100
+ return if @env.key? 'y'
101
+ arg = @env['arg']
102
+ return if arg.nil?
103
+ begin
104
+ @env['y'] = YAML.load(arg)
105
+ #print "y"
106
+ #pp @env['y']
107
+ rescue
108
+ @env['y'] = nil
109
+ #print "y:nil\n"
110
+ end
111
+ end
112
+
113
+ def at(key, default = nil, to_str = true)
114
+ #print "at(#{key}), env:"
115
+ #pp @env
116
+ return @env[key] || default if key.is_a? Symbol
117
+ prepare_y if key =~ /^y\./
118
+ cur = @env
119
+ key.split(/\./).each do |subkey|
120
+ subkey = at($1, '') if subkey =~ /\A\$(.*)/
121
+ #print "at:subkey: #{subkey}\n"
122
+ if cur.is_a? Hash
123
+ cur = cur[subkey]
124
+ elsif cur.is_a? Array
125
+ cur = cur[subkey.to_i]
126
+ else
127
+ #print "at(#{key})->: default"
128
+ return default
129
+ end
130
+ #print "at(#{key}) -> default\n" if cur.nil?
131
+ return default if cur.nil?
132
+ end
133
+ #print "at(#{key})->#{cur}\n"
134
+ to_str ? cur.to_s : cur
135
+ end
136
+ def atput(key, val = nil)
137
+ #print "atput: #{key}, #{val} env:"
138
+ #pp @env
139
+ cur = @env
140
+ if val.is_a? Symbol
141
+ @env[key] = val
142
+ return
143
+ end
144
+ keys = key.split(/\./)
145
+ lastkey = keys.pop
146
+ keys.each do |subkey|
147
+ if cur.is_a? Hash
148
+ cur = cur[subkey]
149
+ elsif cur.is_a? Array
150
+ cur = cur[subkey.to_i]
151
+ else
152
+ return
153
+ end
154
+ end
155
+ if cur.is_a? Hash
156
+ cur[lastkey] = val
157
+ elsif cur.is_a? Array
158
+ cur[lastkey.to_i] = val
159
+ end
160
+ #print "atput:env:"
161
+ #pp @env
162
+ end
163
+
164
+ def [](key)
165
+ at(key)
166
+ end
167
+
168
+ def []=(key,val)
169
+ #print "set #{key} to #{val}\n"
170
+ atput(key,val)
171
+ end
172
+
173
+ # expand macro `macro_name` with `args`
174
+ # afer expansion all {{macros}} will be expanded recursively
175
+ # r: expanded string
176
+ def do_macro_templ(macro_name, arg)
177
+ return "!{{toc}}" if macro_name == 'toc'
178
+ return arg.strip if macro_name == '#echo'
179
+ return '' if macro_name == '#'
180
+
181
+ env = do_macro_arg_to_env(arg, @env[:depth])
182
+
183
+ #print "templ:#{macro_name}env:"
184
+ #pp(env)
185
+
186
+ if ! @parser.template_handler.nil?
187
+ str = @parser.template_handler.call(macro_name, env)
188
+ if !str.nil?
189
+ #print "dep:#{env[:depth]}(#{macro_name}, #{str})\n"
190
+ if env[:depth] > 32
191
+ return "TOO_DEEP_RECURSION(`#{str}`)\n"
192
+ #return "TOO_DEEP_RECURSION"
193
+ end
194
+ # FIXME: melo by nahlasit jestli to chce expandovat | wiki expadnovat |raw html
195
+ #print "temp(#{macro_name}) --> : #{str}\n"
196
+ #print "bf ex: [#{str}]\n"
197
+ str = env.expand(str)
198
+ #print "af ex: [#{str}]\n"
199
+ return str
200
+ end
201
+ end
202
+ #print "UMACRO(#{macro_name}|#{arg})\n"
203
+ "UMACRO(#{macro_name}|#{arg})"
204
+ end
205
+
206
+ def do_macro_arg_to_env(arg, depth)
207
+ arg.sub!(/\A\s*\|?/, '')
208
+ env = { 'arg' => arg , depth: (depth||0) + 1 }
209
+ idx = 1
210
+ arg.split(/\|/).each do |val|
211
+ if val =~ /\A\s*(\w+)\s*=\s*(.*)/s
212
+ env[$1] = $2
213
+ else
214
+ env[idx.to_s] = val
215
+ idx+=1
216
+ end
217
+ end
218
+ return Env.new(@parser, env)
219
+ end
220
+
221
+ def do_macro_var(var_name, arg)
222
+ #print "var(#{var_name})env:"
223
+ #pp(@env)
224
+ ret = at(var_name, nil)
225
+ return ret if !ret.nil?
226
+ return arg.sub(/\A\s*\|?/, '') if arg
227
+ "UVAR(#{macro_name}|#{@env['arg']})"
228
+ end
229
+
230
+ # template expand
231
+ def expand_arg(idx)
232
+ expand(@env['args'][idx])
233
+ end
234
+
235
+ def pp_env
236
+ pp(@env)
237
+ end
238
+ def expand(str)
239
+ ret = ''
240
+ return '' if str.nil?
241
+ while str =~ TracWiki::Parser::MACRO_BEG_INSIDE_REX
242
+ prefix, macro_name2, str = $1, $2, $'
243
+ ret << prefix
244
+ # FIXME if macro_name2 =~ /^!/
245
+ mac_out, str, lines = parse_macro_all(macro_name2, str)
246
+ ret << mac_out
247
+ #print "Too long macro expadion" if ret.size > 1_000_000
248
+ raise TooLongException if ret.size > 1_000_000
249
+ end
250
+ #print "text: #{text.nil?}\n"
251
+ #print "ret: #{ret.nil?}\n"
252
+ return ret + str
253
+ end
254
+ end
255
+
256
+ end
@@ -1,6 +1,7 @@
1
1
  require 'cgi'
2
2
  require 'uri'
3
3
  require 'iconv'
4
+ require 'yaml'
4
5
 
5
6
  # :main: TracWiki
6
7
 
@@ -38,6 +39,9 @@ require 'iconv'
38
39
  # Inherit this to provide custom handling of links. The overrideable
39
40
  # methods are: make_local_link
40
41
  module TracWiki
42
+ class TooLongException < Exception
43
+ end
44
+
41
45
  class Parser
42
46
 
43
47
  # Allowed url schemes
@@ -85,18 +89,23 @@ module TracWiki
85
89
 
86
90
  # when id_from_heading, non ascii char are transliterated to ascii
87
91
  attr_writer :id_translit
92
+ attr_accessor :plugins
93
+ @plugins = {}
88
94
 
89
95
  # string begins with macro
90
- MACRO_BEG_REX = /\A\{\{ ( [\$]?\w+ | \#\w* ) /x
91
- MACRO_BEG_INSIDE_REX = /(.*?)(?<!\{)\{\{ ( \$\w+ | \#\w* | \w+ ) /x
96
+ MACRO_BEG_REX = /\A\{\{ ( \$[\$\.\w]+ | [\#!]\w* |\w+ ) /x
97
+ MACRO_BEG_INSIDE_REX = /\A(.*?)(?<!\{)\{\{ ( \$[\$\.\w]+ | [\#!]\w* | \w+ ) /xm
92
98
  # find end of marcro or begin of inner macro
93
- MACRO_END_REX = /\A(.*?) ( \}\} | \{\{ (\$\w+|\#\w*|\w+) )/mx
99
+ MACRO_END_REX = /\A(.*?) ( \}\} | \{\{ ( \$[\$\.\w]+ | [\#!]\w* | \w+) )/mx
94
100
  def id_translit?; @id_translit; end
95
101
 
96
102
  # Create a new Parser instance.
97
103
  def initialize(text, options = {})
104
+ init_plugins
98
105
  @allowed_schemes = %w(http https ftp ftps)
99
106
  @anames = {}
107
+ plugins = options.delete :plugins
108
+ @plugins.merge! plugins if ! plugins.nil?
100
109
  @text = text
101
110
  @no_escape = nil
102
111
  @base = ''
@@ -104,8 +113,47 @@ module TracWiki
104
113
  @base += '/' if !@base.empty? && @base[-1] != '/'
105
114
  end
106
115
 
116
+ def init_plugins
117
+ @plugins = {
118
+ '!ifeq' => proc { |env| env.expand_arg(0) == env.expand_arg(1) ? env.expand_arg(2) : env.expand_arg(3) },
119
+ '!ifdef' => proc { |env| env.at(env.expand_arg(0), nil, false).nil? ? env.expand_arg(2) : env.expand_arg(1) },
120
+ '!set' => proc { |env| env[env.expand_arg(0)] = env.expand_arg(1); '' },
121
+ '!yset' => proc { |env| env[env.expand_arg(0)] = YAML.load(env.arg(1)); '' },
122
+
123
+ '!html' => proc { |env| "\n{{{!\n#{env.arg(0)}\n}}}\n" },
124
+ '!sub' => proc { |env| pat = env.expand_arg(1)
125
+ pat = Regexp.new(pat[1..-2]) if pat =~ /\A\/.*\/\Z/
126
+ env.expand_arg(0).gsub(pat, env.expand_arg(2))
127
+ },
128
+ '!for' => proc { |env| i_name = env.arg(0)
129
+ top = env.arg(1)
130
+ tmpl = env.arg(2)
131
+ #print "top#{top}\n"
132
+ if top =~ /^\d+/
133
+ set = (0..(top.to_i-1))
134
+ else
135
+ set = env.at(top, nil, false)
136
+ if set.is_a?(Hash)
137
+ set = set.keys.sort
138
+ elsif set.is_a?(Array)
139
+ set = (0 .. set.size-1)
140
+ else
141
+ print "error top(#{top}), set#{set} #{set.class}\n"
142
+ env.pp_env
143
+ raise "Error in {{!for #{i_name}|#{top}|#{tmpl}}}"
144
+ end
145
+ end
146
+ set.map do |i|
147
+ env[i_name] = i.to_s
148
+ env.expand(tmpl)
149
+ end.join('')
150
+ },
151
+ }
152
+
153
+ end
154
+
107
155
  # th(macroname) -> template_text
108
- attr_writer :template_handler
156
+ attr_accessor :template_handler
109
157
 
110
158
  @was_math = false
111
159
  def was_math?; @was_math; end
@@ -138,6 +186,12 @@ module TracWiki
138
186
  @tree.to_html
139
187
  end
140
188
 
189
+ def add_plugin(name, &block)
190
+ @plugins[name] = block
191
+ end
192
+
193
+
194
+
141
195
  protected
142
196
 
143
197
  # Escape any characters with special meaning in HTML using HTML
@@ -407,11 +461,13 @@ module TracWiki
407
461
 
408
462
  def parse_inline_tag(str)
409
463
  case
410
- when str =~ /\A\{\{\{(.*?\}*)\}\}\}/ # inline pre (tt)
464
+ when raw_html? && str =~ /\A\{\{\{!(.*?\}*)\}\}\}/ # inline {{{! raw html }}}
465
+ do_raw_html($1, true)
466
+ when str =~ /\A\{\{\{(.*?\}*)\}\}\}/ # inline {{{ }}} pre (tt)
411
467
  @tree.tag(:tt, $1)
412
468
  when str =~ MACRO_BEG_REX # macro {{
413
469
  str, lines = parse_macro($1, $')
414
- #print "MACRO.inline(#{$1})"
470
+ #print "MACRO.inline(#{$1}), next:#{str}"
415
471
  return str
416
472
  when str =~ /\A`(.*?)`/ # inline pre (tt)
417
473
  @tree.tag(:tt, $1)
@@ -421,7 +477,7 @@ module TracWiki
421
477
  #@tree.tag(:span, {class:'math'}, $1)
422
478
  @was_math = true
423
479
  when str =~ /\A(\&\w*;)/ # html entity
424
- print "add html ent: #{$1}\n"
480
+ #print "add html ent: #{$1}\n"
425
481
  @tree.add_raw($1)
426
482
  when str =~ /\A([:alpha:]|[:digit:])+/
427
483
  @tree.add($&) # word
@@ -455,103 +511,31 @@ module TracWiki
455
511
  return $'
456
512
  end
457
513
 
514
+ #################################################################
515
+ # macro {{ }}
516
+ # convetntion {{!cmd}} {{template}} {{$var}} {{# comment}} {{!}} (pipe)
517
+
458
518
  # r: expanded macro + rest of str, count lines taken from str
459
519
  # sideefect: parse result of macro
460
520
  def parse_macro(macro_name, str)
521
+ @env = Env.new(self) if @env.nil?
461
522
  begin
462
- mac_out, rest, lines = parse_macro_arg(macro_name, str, {})
463
- #parse_inline(mac)
464
- #@tree.add(mac)
465
- #print "MACOUT:'#{mac_out}'\n"
523
+ mac_out, rest, lines = @env.parse_macro_all(macro_name, str)
524
+ #print "mac: '#{mac_out}' rest: '#{rest}'\n"
466
525
  return mac_out + rest, lines
467
- rescue Exception => a
468
- return "TOO_LONG_EXPANSION_OF_MACRO(#{macro_name})QUIT"
469
- end
470
- end
471
-
472
- # read to args to }} (while balancing {{ and }})
473
- # ret: (arg, rest, lines)
474
- # mac_out -- string to }} (macros inside expanded)
475
- # rest -- str aftrer }}
476
- # lines -- howmany \n eaten from str (from begining to }})
477
- def parse_macro_arg(macro_name, str, env)
478
-
479
- lines = 0
480
- arg = ''
481
- # FIXME: MACRO_REX
482
- # prefix }}... {{macro_name
483
- while str =~ MACRO_END_REX
484
- prefix, bracket, sub_macro_name, str = $1, $2, $3, $'
485
- arg << prefix
486
- lines += prefix.count("\n")
487
- if bracket == '}}'
488
- #print "prefix: #{prefix}\n"
489
- env = do_macro_arg_to_env(arg, env[:depth])
490
- return do_macro(macro_name, env), str, lines
491
- end
492
-
493
- # we need to go deeper!
494
- mac_out, str, l = parse_macro_arg(sub_macro_name, str, env)
495
- arg << mac_out
496
- lines += l
526
+ rescue TooLongException => e
527
+ return "TOO_LONG_EXPANSION_OF_MACRO(#{macro_name})QUIT", 0
497
528
  end
498
- raise "Error parsing macro near '#{str}' (arg:#{arg}, lines=#{lines})"
499
529
  end
500
530
 
501
- # expand macro `macro_name` with `args`
502
- # afer expansion all {{macros}} will be expanded recursively
503
- # r: expanded string
504
- def do_macro(macro_name, env)
505
- return "!{{toc}}" if macro_name == 'toc'
506
- return env[:arg].strip if macro_name == '#echo'
507
- return '' if macro_name == '#'
508
531
 
509
- return do_macro_var(macro_name, env) if macro_name =~ /^\$/
510
532
 
511
-
512
- if ! @template_handler.nil?
513
- text = @template_handler.call(macro_name, env)
514
- if !text.nil?
515
- #print "dep:#{env[:depth]}(#{macro_name}, #{text})\n"
516
- if env[:depth] > 32
517
- return "TOO_DEEP_RECURSION(`#{text}`)\n"
518
- #return "TOO_DEEP_RECURSION"
519
- end
520
- # FIXME: melo by nahlasit jestli to chce expandovat | wiki expadnovat |raw html
521
- #print "temp(#{macro_name}) --> : #{text}\n"
522
- text = do_macro_expand_result(text, env)
523
- #print "af expand:#{text}\n"
524
-
525
- return text
526
- end
527
- end
528
- "UMACRO(#{macro_name}#{env[:arg]})"
529
- end
530
-
531
- def do_macro_var(macro_name, env)
532
- "VAR(#{macro_name})"
533
- end
534
-
535
- def do_macro_arg_to_env(arg, depth)
536
- { arg: arg , depth: (depth||0) + 1 }
537
- end
538
-
539
- # template expand
540
- def do_macro_expand_result(text, env)
541
- ret = ''
542
- while text =~ MACRO_BEG_INSIDE_REX
543
- prefix, macro_name2, text = $1, $2, $'
544
- ret << prefix
545
- mac_out, text, lines = parse_macro_arg(macro_name2, text, env)
546
- ret << mac_out
547
- raise "Too long macro expadion" if ret.size > 1_000_000
548
- end
549
- return ret + text
550
- end
533
+ #################################################################
551
534
 
552
535
 
553
536
  def parse_table_row(str)
554
537
  start_tag('tr') if !@stack.include?('tr')
538
+ str.sub!(/\r/, '')
555
539
  colspan = 1
556
540
  print_tr = true
557
541
  last_tail = ''
@@ -674,8 +658,8 @@ module TracWiki
674
658
  @tree.tag(:pre, nowikiblock)
675
659
  end
676
660
 
677
- def do_raw_html(text)
678
- end_paragraph
661
+ def do_raw_html(text, inline=false)
662
+ end_paragraph if !inline
679
663
  @tree.add_raw(text)
680
664
  end
681
665
 
@@ -741,7 +725,8 @@ module TracWiki
741
725
  # macro
742
726
  when str =~ MACRO_BEG_REX
743
727
  str, lines = parse_macro($1, $')
744
- #print "MACRO.block(#{$1})\n"
728
+ #print "MACRO.block(#{$1})next:#{str}\n"
729
+ @line_no += lines
745
730
  next
746
731
  # display math $$
747
732
  when math? && str =~ /\A\$\$(.*?)\$\$/m
@@ -778,7 +763,7 @@ module TracWiki
778
763
  do_citation($1.count('>'), $2)
779
764
  # ordinary line
780
765
  when str =~ /\A(\s*)(\S+.*?)$(\r?\n)?/
781
- do_ord_line($1.size, $2)
766
+ do_ord_line($1.size, $2)
782
767
  else # case str
783
768
  raise "Parse error at #{str[0,30].inspect}"
784
769
  end
@@ -786,7 +771,7 @@ module TracWiki
786
771
  str = $'
787
772
  end
788
773
  end_paragraph
789
- @headings.last[:eline] = @line_no - 1
774
+ @headings.last[:eline] = @line_no - 1
790
775
  end
791
776
 
792
777
  def aname_nice(aname, title)
@@ -145,9 +145,11 @@ module TracWiki
145
145
 
146
146
  def san_conf
147
147
  return @san_conf if @san_conf
148
- conf = { elements: ['form', 'input'],
148
+ conf = { elements: ['form', 'input', 'span', 'div'],
149
149
  attributes: { 'form' => ['action', 'meth'],
150
150
  'input' => ['type', 'value'],
151
+ 'span' => ['class'],
152
+ 'div' => ['class'],
151
153
  },
152
154
  }
153
155
 
@@ -1,3 +1,3 @@
1
1
  module TracWiki
2
- VERSION = '0.2.16'
2
+ VERSION = '0.2.20'
3
3
  end
data/test/parser_test.rb CHANGED
@@ -5,13 +5,26 @@ require 'pp'
5
5
 
6
6
  class Bacon::Context
7
7
  def tc(html, wiki, options = {})
8
- #options[:template_handler] = proc {|tname,env| template_handler(tname, env) }
8
+ options[:plugins] = { '!print' => proc { |env| env.arg(0) + '! ' },
9
+ }
9
10
  options[:template_handler] = self.method(:template_handler)
10
- TracWiki.render(wiki, options).should.equal html
11
+
12
+ parser = TracWiki.parser(wiki, options)
13
+ parser.to_html.should.equal html
11
14
  end
12
15
 
13
16
  def template_handler(tname, env)
14
17
  case tname
18
+ when 'ifeqtest'
19
+ "{{!ifeq {{$1}}|{{$2}}|TRUE|FALSE}}"
20
+ when 'vartest2'
21
+ "{{vartest {{$1}}|{{$dva}}|p={{$p}}|{{$3 |tridef}}}}"
22
+ when 'ytest'
23
+ "{{$y.ahoj}},{{$y.bhoj.1}}"
24
+ when 'ytest2'
25
+ "{{!set i|ahoj}}{{$y.$i}},{{$y.bhoj.1}}"
26
+ when 'vartest'
27
+ "jedna:{{$1}},dve:{{$2}},p:{{$p}},arg:{{$arg}}"
15
28
  when 'test'
16
29
  "{{west}}"
17
30
  when 'west'
@@ -20,6 +33,8 @@ class Bacon::Context
20
33
  "{{deep}}"
21
34
  when 'wide'
22
35
  "0123456789{{wide}}" * 10
36
+ when 'fortest'
37
+ "{{$y.data.a}},({{!for i|y.data|AHOJ({{$i}})\n{{$y.data.$i}};\n}}),{{$y.data.a}}"
23
38
  else
24
39
  nil
25
40
  #"UNK_TEMPL(#{tname})"
@@ -574,6 +589,8 @@ describe TracWiki::Parser do
574
589
 
575
590
  it 'should parse table' do
576
591
  tc "<table><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||World!||"
592
+ tc "<table><tr><td>Hello</td><td>World!</td></tr><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||World!||\n||Hello||World!||\n\n"
593
+ tc "<table><tr><td>Hello</td><td>World!</td></tr><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||World!||\r\n||Hello||World!||\r\n\n"
577
594
  tc "<table><tr><td>Hello</td><td>World!</td></tr></table>", "||Hello||\\\n||World!||"
578
595
  tc "<table><tr><td>He</td><td>llo</td><td>World!</td></tr></table>", "||He||llo||\\\n||World!||"
579
596
  tc "<table><tr><td>Hello</td><td colspan=\"2\">World!</td></tr></table>", "||Hello||||World!||"
@@ -893,12 +910,12 @@ eos
893
910
 
894
911
  tc "<h1>h1</h1>" , "{{# co{{HUU}}mment }}\n\n\n= h1 =\n{{# Comment2}}\n"
895
912
 
896
- tc "<p>UMACRO(macr ahoj )</p>\n" , "{{macr\nahoj\n}}"
897
- tc "<p>ahoj UMACRO(macrUMACRO(o))</p>\n" , "ahoj {{macr{{o}}}}"
898
- tc "<p>ahoj UMACRO(macro)</p>\n" , "ahoj {{macro}}"
899
- tc "<p>ahoj {{%macrUMACRO(o)}}</p>\n" , "ahoj {{%macr{{o}}}}"
900
- tc "<p>ahoj UMACRO(macrUMACRO(mac <strong>o</strong>))</p>\n" , "ahoj {{macr{{mac **o**}}}}"
901
- tc "<p>ahoj VAR($mac)</p>\n" , "ahoj {{$mac|ahoj}}"
913
+ tc "<p>UMACRO(macr|ahoj )</p>\n" , "{{macr\nahoj\n}}"
914
+ tc "<p>ahoj UMACRO(macr|UMACRO(o|))</p>\n" , "ahoj {{macr{{o}}}}"
915
+ tc "<p>ahoj UMACRO(macro|)</p>\n" , "ahoj {{macro}}"
916
+ tc "<p>ahoj {{%macrUMACRO(o|)}}</p>\n" , "ahoj {{%macr{{o}}}}"
917
+ tc "<p>ahoj UMACRO(macr|UMACRO(mac|<strong>o</strong>))</p>\n" , "ahoj {{macr{{mac **o**}}}}"
918
+ tc "<p>ahoj ahoj</p>\n" , "ahoj {{$mac|ahoj}}"
902
919
  end
903
920
 
904
921
  it 'should do temlate' do
@@ -908,23 +925,84 @@ eos
908
925
  # macro errors:
909
926
  tc "<p>TOO_DEEP_RECURSION(<tt>{{deep}}</tt>) 3</p>\n", "{{deep}}3"
910
927
  tc "<p>TOO_LONG_EXPANSION_OF_MACRO(wide)QUIT</p>\n", "{{wide}}3"
911
- tc "<p>UMACRO(unknown)3</p>\n", "{{unknown}}3"
928
+ tc "<p>UMACRO(unknown|)3</p>\n", "{{unknown}}3"
929
+ end
930
+ it 'should do temlate with args' do
931
+ tc "<p>jedna:VARTESTPARAM,dve:,p:DVE,arg:VARTESTPARAM|p=DVE</p>\n", "{{vartest VARTESTPARAM|p=DVE}}"
932
+ tc "<p>jedna:VARTESTPARAM,dve:TRI,p:DVE,arg:VARTESTPARAM|p=DVE|TRI</p>\n", "{{vartest VARTESTPARAM|p=DVE|TRI}}"
933
+ tc "<p>jedna:VARTESTPARAM,dve:TRI,p:DVE,arg:VARTESTPARAM|TRI|p=DVE|tridef</p>\n", "{{vartest2 VARTESTPARAM|p=DVE|dva=TRI}}"
934
+ tc "<p>ahoj |</p>\n", "ahoj {{!}}"
935
+ #FIXME: should be: '... jedna:be||no to be,dve: ..'
936
+ tc "<p>jedna:be,dve:,p:,arg:be||not to be</p>\n", "{{vartest be{{!}}{{!}}not to be}}"
912
937
  end
913
938
  it 'should support options' do
914
939
  tc "<h3>h1<a class=\"editheading\" href=\"?edit=1\">edit</a></h3>", "=== h1 ==", edit_heading: true
915
940
  end
916
941
  it 'should not html' do
917
- tc "<p>{{{! &lt;a&gt;&lt;/a&gt; }}}</p>\n", "{{{!\n<a></a>\n}}}\n"
942
+ #tc "<p>{{{! &lt;a&gt;&lt;/a&gt; }}}</p>\n", "{{{!\n<a></a>\n}}}\n"
918
943
  tc '<a></a>', "{{{!\n<a></a>\n}}}\n", raw_html: true
919
944
  tc '<a></a>', "{{{!\n<a></a>\n}}}\n", raw_html: true
920
945
  tc "<form meth=\"POST\" action=\"http://www.example.com\"><input type=\"hidden\" value=\"VAL\"></form>",
921
946
  "{{{!\n<form meth=\"POST\" action=\"http://www.example.com\"><input type=\"hidden\" value=\"VAL\"/></form>\n}}}\n", raw_html: true
922
947
  tc 'alert(444);', "{{{!\n<script>alert(444);</script>\n}}}\n", raw_html: true
923
948
  end
924
- it 'should not entity' do
949
+ it 'should entity' do
925
950
  tc "<p>\u00a0</p>\n", "&nbsp;"
926
951
  tc "<p>„text“</p>\n", "&bdquo;text&ldquo;"
927
952
  end
953
+ it 'should plugin' do
954
+ tc "<p>AHOJTE!</p>\n", "{{!print AHOJTE}}"
955
+ tc "<p>test:AHOJTE! AHOJTE! </p>\n", "test:{{!print AHOJTE}}{{!print AHOJTE}}"
956
+ tc "<p>FALSE</p>\n", "{{ifeqtest JEDNA|DVE}}"
957
+ tc "<p>TRUE</p>\n", "{{ifeqtest JEDNA|JEDNA}}"
958
+ tc "<p>AHOJ</p>\n", "{{!set ahoj|AHOJ}}{{$ahoj}}"
959
+ tc "<p>BHOJ</p>\n", "{{!ifeq a|b|{{!set ahoj|AHOJ}}|{{!set ahoj|BHOJ}}}}{{$ahoj}}"
960
+ tc "<p>AHOJ</p>\n", "{{!ifeq a|a|{{!set ahoj|AHOJ}}|{{!set ahoj|BHOJ}}}}{{$ahoj}}"
961
+ tc "<p>TRUE</p>\n", "{{!set a|a}}{{!ifeq {{$a}}|a|TRUE|FALSE}}"
962
+ tc "<p>FALSE</p>\n", "{{!set a|a}}{{!ifeq {{$a}}|b|TRUE|FALSE}}"
963
+ tc "<p>,AHOJ! ,FALSE</p>\n", "{{!set a|a}},{{!print AHOJ}},{{!ifeq {{$a}}|b|TRUE|FALSE}}"
964
+ tc "", "{{!ifeq a|b|TRUE}}"
965
+ tc "<p>AHOJ,dve</p>\n", "{{ytest \nahoj: AHOJ\nbhoj: [ jedna, dve ]\n}}"
966
+ tc "<p>,malo</p>\n", "{{!yset ahoj|data: [1,2]\ndesc: malo}},{{$ahoj.desc}}"
967
+ tc "<p>,BETA</p>\n", "{{!yset ahoj|data: [ALFA,BETA]\ndesc: malo}},{{$ahoj.data.1}}"
968
+ tc "<p>,GAMA</p>\n", "{{!yset ahoj|data: [ALFA,BETA]\ndesc: malo}},{{!set ahoj.data.3|GAMA}}{{$ahoj.data.3}}"
969
+ tc "<p>,2</p>\n", "{{!yset ahoj|data: [1,2]\ndesc: malo}},{{$ahoj.data.1}}"
970
+ tc "<p>AHOJ,dve</p>\n", "{{ytest2 \nahoj: AHOJ\nbhoj: [ jedna, dve ]\n}}"
971
+ tc "<p>,,BHOJ</p>\n", "{{!set ahoj|AHOJ}},{{!set AHOJ|BHOJ}},{{$$ahoj}}"
972
+ tc "<p>(0),(1),(2),</p>\n", "{{!for i|3|({{$i}}),}}", raw_html: true
973
+ tc "<p>(0),(1),(2),(3),</p>\n", "{{!for i|4|({{$i}}),}}", raw_html: true
974
+ tc "<p>,(ALFA),(BETA),</p>\n", "{{!yset data|[ALFA,BETA]}},{{!for i|data|({{$data.$i}}),}}"
975
+ tc "<p>,(1),(2),</p>\n", "{{!yset data|[1,2]}},{{!for i|data|({{$data.$i}}),}}"
976
+ tc "<p>,(alfa:ALFA),(beta:BETA),</p>\n", "{{!yset data|beta: BETA\nalfa: ALFA\n}},{{!for i|data|({{$i}}:{{$data.$i}}),}}"
977
+
978
+ tc "<p>,FALSE</p>\n", "{{!yset data|[1,2]}},{{!ifdef data.55|TRUE|FALSE}}"
979
+ tc "<p>,TRUE</p>\n", "{{!yset data|[1,2]}},{{!ifdef data.1|TRUE|FALSE}}"
980
+ tc "<p>,TRUE</p>\n", "{{!yset data|{a: 1, b: 2} }},{{!ifdef data.a|TRUE|FALSE}}"
981
+ tc "<p>,FALSE</p>\n", "{{!yset data|{a: 1, b: 2} }},{{!ifdef data.q|TRUE|FALSE}}"
982
+ tc "<p>,1,(1;2;),1</p>\n", "{{!yset data|{a: 1, b: 2} }},{{$data.a}},({{!for i|data|{{$data.$i}};}}),{{$data.a}}"
983
+ tc "<p>1,(AHOJ(a) 1; AHOJ(b) 2; ),1</p>\n", "{{fortest data:\n a: 1\n b: 2 }}"
984
+ end
985
+
986
+ it 'should {{!sub}}' do
987
+ tc "<p>ahoj_you_one</p>\n", "{{!sub ahoj you one| |_}}"
988
+ tc "<p>-h-j --- -n-</p>\n", "{{!sub ahoj you one|/[aeiouy]/|-}}"
989
+ tc "<p>ahoj MATCH(you) one</p>\n", "{{!sub ahoj you one|/(y.u)/|MATCH(\\1)}}"
990
+ end
991
+
992
+ it 'should {{!html}}' do
993
+ tc "alert(666)", "{{!html <script>alert(666)</script>}}", raw_html: true
994
+ tc "<p><b>T</b>E</p>", "{{!html <p><b>T</b>E</p>}}\n", raw_html: true
995
+ tc "<span>Span</span>", "{{!html <span>Span</span>}}\n", raw_html: true
996
+ #tc "<span>Span</span>", "**{{!html <span>Span</span>}}**\n", raw_html: true
997
+ tc "<div class=\"ahoj\">Div</div>", "{{!html <div class=\"ahoj\">Div</div>}}\n", raw_html: true
998
+ tc "<span>Span</span><span>Span</span>", "{{!html <span>Span</span>}}{{!html <span>Span</span>}}\n", raw_html: true
999
+ tc "<p>ahoj <span class=\"spanclass\">span</span> bhoj dhoj choj</p>\n", "ahoj {{{!<span class=\"spanclass\">span</span> bhoj}}} dhoj \nchoj\n", raw_html: true
1000
+ tc "<p>ahoj Q<span class=\"spanclass\">span</span> bhojQ dhoj choj</p>\n", "ahoj Q{{{!<span class=\"spanclass\">span</span> bhoj}}}Q dhoj \nchoj\n", raw_html: true
1001
+ end
1002
+ # it 'last test' do
1003
+ # #tc "<p>1,(AHOJ(a) 1; AHOJ(b) 2; ),1</p>\n", "{{fortest data:\n a: 1\n b: 2 }}"
1004
+ #
1005
+ # end
928
1006
  end
929
1007
  end
930
1008
  # vim: tw=0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trac-wiki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.16
4
+ version: 0.2.20
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-27 00:00:00.000000000 Z
12
+ date: 2014-01-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bacon
@@ -60,6 +60,7 @@ files:
60
60
  - Rakefile
61
61
  - bin/trac-wiki.rb
62
62
  - lib/trac-wiki.rb
63
+ - lib/trac-wiki/env.rb
63
64
  - lib/trac-wiki/parser.rb
64
65
  - lib/trac-wiki/tree.rb
65
66
  - lib/trac-wiki/version.rb