trac-wiki 0.2.16 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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