trac-wiki 0.2.20 → 0.2.21

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.
@@ -65,9 +65,8 @@ module TracWiki
65
65
  attr_writer :math
66
66
  def math?; @math; end
67
67
 
68
- # allow {{{! ... html ... }}}
68
+ # allow some <b> <form> <html>
69
69
  # html will be sanitized
70
- # {{{!\n html here \n}}}\n
71
70
  attr_writer :raw_html
72
71
  def raw_html?; @raw_html; end
73
72
 
@@ -120,7 +119,7 @@ module TracWiki
120
119
  '!set' => proc { |env| env[env.expand_arg(0)] = env.expand_arg(1); '' },
121
120
  '!yset' => proc { |env| env[env.expand_arg(0)] = YAML.load(env.arg(1)); '' },
122
121
 
123
- '!html' => proc { |env| "\n{{{!\n#{env.arg(0)}\n}}}\n" },
122
+ # '!html' => proc { |env| "\n{{{!\n#{env.arg(0)}\n}}}\n" },
124
123
  '!sub' => proc { |env| pat = env.expand_arg(1)
125
124
  pat = Regexp.new(pat[1..-2]) if pat =~ /\A\/.*\/\Z/
126
125
  env.expand_arg(0).gsub(pat, env.expand_arg(2))
@@ -461,8 +460,9 @@ module TracWiki
461
460
 
462
461
  def parse_inline_tag(str)
463
462
  case
464
- when raw_html? && str =~ /\A\{\{\{!(.*?\}*)\}\}\}/ # inline {{{! raw html }}}
465
- do_raw_html($1, true)
463
+ when raw_html? && str =~ /\A<(\/)?(\w+)(?:([^>]*?))?(\/\s*)?>/ # single inline <html> tag
464
+ eot, tag, args, closed = $1, $2, $3, $4
465
+ do_raw_tag(eot, tag, args, closed, $'.size)
466
466
  when str =~ /\A\{\{\{(.*?\}*)\}\}\}/ # inline {{{ }}} pre (tt)
467
467
  @tree.tag(:tt, $1)
468
468
  when str =~ MACRO_BEG_REX # macro {{
@@ -658,9 +658,32 @@ module TracWiki
658
658
  @tree.tag(:pre, nowikiblock)
659
659
  end
660
660
 
661
- def do_raw_html(text, inline=false)
662
- end_paragraph if !inline
663
- @tree.add_raw(text)
661
+ def do_raw_tag(eot, tag, attrs, closed, tail_size)
662
+ if !eot
663
+ end_paragraph if tag == 'p' || tag == 'div'
664
+ #print "open tag #{tag},'#{attrs}'\n"
665
+ attrs_h = _parse_attrs_to_hash(attrs)
666
+ @tree.tag_beg(tag, attrs_h)
667
+ @tree.tag_end(tag) if closed
668
+ else
669
+ #print "close tag #{tag}\n"
670
+ @tree.tag_end(tag)
671
+ if tag == 'p' || tag == 'div'
672
+ end_paragraph
673
+ start_paragraph if tail_size > 0
674
+ end
675
+ end
676
+ end
677
+
678
+ def _parse_attrs_to_hash(str)
679
+ ret = {}
680
+ while str =~ /\A\s*(\w+)\s*=\s*'([^>']*)'/ ||
681
+ str =~ /\A\s*(\w+)\s*=\s*"([^>"]*)"/ ||
682
+ str =~ /\A\s*(\w+)\s*=\s*(\S*)/
683
+ ret[$1] = $2
684
+ str = $'
685
+ end
686
+ ret
664
687
  end
665
688
 
666
689
  def do_hr
@@ -734,9 +757,6 @@ module TracWiki
734
757
  # merge
735
758
  when merge? && str =~ /\A(<{7}|={7}|>{7}|\|{7}) *(\S*).*$(\r?\n)?/
736
759
  do_merge($1, $2)
737
- # raw_html {{{! ... }}}
738
- when raw_html? && str =~ /\A\{\{\{!\r?\n(.*?)\r?\n\}\}\}/m
739
- do_raw_html($1)
740
760
  # pre {{{ ... }}}
741
761
  when str =~ /\A\{\{\{\r?\n(.*?)\r?\n\}\}\}/m
742
762
  do_pre($1)
@@ -55,12 +55,24 @@ module TracWiki
55
55
  end
56
56
 
57
57
  def tag_end(tag_name)
58
- if @cur.tag == tag_name.to_sym
59
- @cur = @cur.par
60
- else
61
- raise "tag_end: cur tag is not <#{tag_name}>, but <#{@cur.tag}>"
58
+ c = @cur
59
+ ts = tag_name.to_sym
60
+ while c.tag != ts
61
+ c = c.par
62
+ if c.nil?
63
+ return "no such tag in stack, ingoring "
64
+ end
62
65
  end
66
+ @cur = c.par
63
67
  self
68
+
69
+ # if @cur.tag == tag_name.to_sym
70
+ # @cur = @cur.par
71
+ # else
72
+ # #pp(@root)
73
+ # raise "tag_end: cur tag is not <#{tag_name}>, but <#{@cur.tag}>"
74
+ # end
75
+ # self
64
76
  end
65
77
 
66
78
  # add space if needed
@@ -80,8 +92,8 @@ module TracWiki
80
92
  end
81
93
 
82
94
  def add_raw(cont)
83
- cont_san = Sanitize.clean(cont, san_conf)
84
- @cur.add(RawHtml.new(cont_san))
95
+ #cont_san = Sanitize.clean(cont, san_conf)
96
+ @cur.add(RawHtml.new(cont))
85
97
  self
86
98
  end
87
99
 
@@ -98,27 +110,80 @@ module TracWiki
98
110
  end
99
111
 
100
112
  def to_html
101
- tree_to_html(@root)
113
+ ret = tree_to_html(@root)
114
+ #print "bf san:", ret, "\n"
115
+ #ret = Sanitize.clean(ret, san_conf)
116
+ #print "af san:", ret, "\n"
117
+ #ret + "\n"
118
+ ret
102
119
  end
103
-
104
120
  def tree_to_html(node)
105
121
  tag = node.tag
106
122
  if tag.nil?
107
123
  return cont_to_s(node.cont)
108
124
  end
109
125
 
110
- nl = ""
111
- #nl = "\n" if [:div, :h1, :h2, :h3, :h4, :h5, :p].include? tag
112
- nl = "\n" if [:div, :p].include? tag
126
+ nl = ''
127
+ nl = "\n" if TAGS_APPEND_NL.include? tag
113
128
 
129
+ if ! TAGS_ALLOVED.include? tag
130
+ return '' if node.cont.size == 0
131
+ return cont_to_s(node.cont)
132
+ end
114
133
  if node.cont.size == 0
115
- if [:a, :td, :h1, :h2, :h3, :h4, :h5, :h6,:strong, :script].include? tag
116
- return "<#{tag}#{attrs_to_s(node.attrs)}></#{tag}>"
134
+ if TAGS_SKIP_EMPTY.include? tag
135
+ return ''
136
+ end
137
+ if TAGS_FORCE_PAIR.include? tag
138
+ return "<#{tag}#{attrs_to_s(tag, node.attrs)}></#{tag}>#{nl}"
117
139
  end
118
- return "<#{tag}#{attrs_to_s(node.attrs)}/>#{nl}"
140
+ return "<#{tag}#{attrs_to_s(tag, node.attrs)}/>#{nl}"
119
141
  end
120
142
 
121
- return "<#{tag}#{attrs_to_s(node.attrs)}>#{cont_to_s(node.cont)}</#{tag}>#{nl}"
143
+ return "<#{tag}#{attrs_to_s(tag, node.attrs)}>#{cont_to_s(node.cont)}</#{tag}>#{nl}"
144
+ end
145
+
146
+
147
+ TAGS_APPEND_NL = [:div, :p]
148
+ TAGS_FORCE_PAIR = [:a, :td, :h1, :h2, :h3, :h4, :h5, :h6, :div, :strong, :script]
149
+ TAGS_ALLOVED = [:a,
150
+ :h1, :h2, :h3, :h4, :h5, :h6,
151
+ :div, :span, :p, :pre,
152
+ :li, :ul, :ol, :dl, :dt, :dd,
153
+ :b, :tt, :u, :del, :blockquote, :strong, :em, :sup, :sub,
154
+ :table, :tr, :td, :th,
155
+ :br , :img, :hr,
156
+ :form, :textarea, :input, :select, :option,
157
+ ]
158
+ TAGS_SKIP_EMPTY = [ :p ]
159
+ ATTRIBUTES_ALLOWED = { :form => [:action, :meth],
160
+ :input => [:size, :type, :value, :name],
161
+ :select => [:multiple, :name],
162
+ :option => [:disabled, :selected, :label, :value, :name],
163
+ :a => [:name, :href],
164
+ :img => [:src, :width, :height, :align, :valign, :style, :alt, :title],
165
+ :td => [:colspan, :rowspan, :style],
166
+ :th => [:colspan, :rowspan, :style],
167
+ :_all => [:class, :id],
168
+ }
169
+
170
+ ATTRIBUTE_STYLE_REX = /\A( text-align:(center|right|left) |
171
+ margin: \d+(px|em)? |
172
+ ;
173
+ )+\Z/x
174
+ def attrs_to_s(tag, attrs)
175
+ return '' if attrs.nil? || attrs.size == 0
176
+ ret = ['']
177
+ tag_attrs = ATTRIBUTES_ALLOWED[tag] || []
178
+ attrs.each_pair do |k,v|
179
+ next if v.nil?
180
+ k_sym = k.to_sym
181
+ next if ! ATTRIBUTES_ALLOWED[:_all].include?(k_sym) && ! tag_attrs.include?(k_sym)
182
+ next if k == :style && v !~ ATTRIBUTE_STYLE_REX
183
+ #print "style: #{v}\n" if k == :style
184
+ ret.push "#{TracWiki::Parser.escapeHTML(k.to_s)}=\"#{TracWiki::Parser.escapeHTML(v.to_s)}\""
185
+ end
186
+ return ret.sort.join(' ')
122
187
  end
123
188
 
124
189
  def cont_to_s(cont)
@@ -134,26 +199,20 @@ module TracWiki
134
199
  end.join('')
135
200
  end
136
201
 
137
- def attrs_to_s(attrs)
138
- return '' if attrs.nil? || attrs.size == 0
139
- ret = ['']
140
- attrs.each_pair do |k,v|
141
- ret.push "#{TracWiki::Parser.escapeHTML(k.to_s)}=\"#{TracWiki::Parser.escapeHTML(v.to_s)}\"" if !v.nil?
142
- end
143
- return ret.sort.join(' ')
144
- end
145
-
146
202
  def san_conf
147
203
  return @san_conf if @san_conf
148
- conf = { elements: ['form', 'input', 'span', 'div'],
204
+ conf = { elements: ['tt', 'form', 'input', 'span', 'div'],
205
+ output: :xhtml,
149
206
  attributes: { 'form' => ['action', 'meth'],
150
207
  'input' => ['type', 'value'],
151
- 'span' => ['class'],
152
- 'div' => ['class'],
208
+ 'span' => ['class', 'id'],
209
+ 'div' => ['class', 'id'],
210
+ 'a' => ['class', 'id', 'name', 'href'],
211
+ :all => ['class', 'id'],
153
212
  },
154
213
  }
155
214
 
156
- @san_conf = conf.merge(Sanitize::Config::RELAXED){|k,o,n| o.is_a?(Hash) ? o.merge(n) :
215
+ @san_conf = Sanitize::Config::RELAXED.merge(conf){|k,o,n| o.is_a?(Hash) ? o.merge(n) :
157
216
  o.is_a?(Array) ? o + n :
158
217
  n }
159
218
 
@@ -1,3 +1,3 @@
1
1
  module TracWiki
2
- VERSION = '0.2.20'
2
+ VERSION = '0.2.21'
3
3
  end
data/test/parser_test.rb CHANGED
@@ -33,8 +33,6 @@ class Bacon::Context
33
33
  "{{deep}}"
34
34
  when 'wide'
35
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}}"
38
36
  else
39
37
  nil
40
38
  #"UNK_TEMPL(#{tname})"
@@ -185,7 +183,8 @@ describe TracWiki::Parser do
185
183
  tc "<h1>Heading 1</h1>", "= Heading 1 ="
186
184
  tc "<h2>Heading 2</h2>", "== Heading 2 =="
187
185
  tc "<h3>Heading 3</h3>", "=== Heading 3 ==="
188
- tc "<h3>Heading 3\u00a0B</h3>", "=== Heading 3~B ==="
186
+ #tc "<h3>Heading 3\u00a0B</h3>", "=== Heading 3~B ==="
187
+ tc "<h3>Heading 3&nbsp;B</h3>", "=== Heading 3~B ==="
189
188
  tc "<h3 id=\"HE3\">Heading 3</h3>", "=== Heading 3 === #HE3"
190
189
  tc "<h3 id=\"Heading-3\">Heading 3</h3>", "=== Heading 3 === #Heading-3"
191
190
  tc "<h3 id=\"Heading/3\">Heading 3</h3>", "=== Heading 3 === #Heading/3"
@@ -551,7 +550,8 @@ describe TracWiki::Parser do
551
550
  tc "<p>// Not Italic //</p>\n", "!// Not Italic !//"
552
551
  tc "<p>* Not Bullet</p>\n", "!* Not Bullet"
553
552
  # Following char is not a blank (space or line feed)
554
- tc "<p>Hello \u00a0 world</p>\n", "Hello ~ world\n"
553
+ #tc "<p>Hello \u00a0 world</p>\n", "Hello ~ world\n"
554
+ tc "<p>Hello &nbsp; world</p>\n", "Hello ~ world\n"
555
555
  tc "<p>Hello ! world</p>\n", "Hello ! world\n"
556
556
  tc "<p>Hello ! world</p>\n", "Hello ! world\n"
557
557
  tc "<p>Hello ! world</p>\n", "Hello !\nworld\n"
@@ -939,16 +939,14 @@ eos
939
939
  tc "<h3>h1<a class=\"editheading\" href=\"?edit=1\">edit</a></h3>", "=== h1 ==", edit_heading: true
940
940
  end
941
941
  it 'should not html' do
942
- #tc "<p>{{{! &lt;a&gt;&lt;/a&gt; }}}</p>\n", "{{{!\n<a></a>\n}}}\n"
943
- tc '<a></a>', "{{{!\n<a></a>\n}}}\n", raw_html: true
944
- tc '<a></a>', "{{{!\n<a></a>\n}}}\n", raw_html: true
945
- tc "<form meth=\"POST\" action=\"http://www.example.com\"><input type=\"hidden\" value=\"VAL\"></form>",
946
- "{{{!\n<form meth=\"POST\" action=\"http://www.example.com\"><input type=\"hidden\" value=\"VAL\"/></form>\n}}}\n", raw_html: true
947
- tc 'alert(444);', "{{{!\n<script>alert(444);</script>\n}}}\n", raw_html: true
942
+ tc "<p>&lt;b&gt;&lt;/b&gt;</p>\n", "<b></b>\n"
943
+ tc "<p>&lt;div&gt;&lt;script&gt;alert(666)&lt;/script&gt;&lt;/div&gt;</p>\n", "<div><script>alert(666)</script></div>\n"
948
944
  end
949
945
  it 'should entity' do
950
- tc "<p>\u00a0</p>\n", "&nbsp;"
951
- tc "<p>„text“</p>\n", "&bdquo;text&ldquo;"
946
+ #tc "<p>\u00a0</p>\n", "&nbsp;"
947
+ #tc "<p>„text“</p>\n", "&bdquo;text&ldquo;"
948
+ tc "<p>&nbsp;</p>\n", "&nbsp;"
949
+ tc "<p>&bdquo;text&ldquo;</p>\n", "&bdquo;text&ldquo;"
952
950
  end
953
951
  it 'should plugin' do
954
952
  tc "<p>AHOJTE!</p>\n", "{{!print AHOJTE}}"
@@ -979,30 +977,29 @@ eos
979
977
  tc "<p>,TRUE</p>\n", "{{!yset data|[1,2]}},{{!ifdef data.1|TRUE|FALSE}}"
980
978
  tc "<p>,TRUE</p>\n", "{{!yset data|{a: 1, b: 2} }},{{!ifdef data.a|TRUE|FALSE}}"
981
979
  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
980
+ end
981
+
982
+ it 'should parse html' do
983
+ tc "<p>alert(666)</p>\n", "<script>alert(666)</script>", raw_html: true
984
+ tc "<p><b>T</b>E</p>\n", "<p><b>T</b>E</p>", raw_html: true
985
+ tc "<p><span>Span</span></p>\n", "<span>Span</span>\n", raw_html: true
986
+ tc "<p><strong><span>Span</span></strong></p>\n", "**<span>Span</span>**\n", raw_html: true
987
+ tc "<div class=\"ahoj\">Div</div>\n", "<div class=\"ahoj\">Div</div>\n", raw_html: true
988
+ tc "<p><strong>ahoj</strong></p>\n<div class=\"ahoj\">Div</div>\n", "**ahoj<div class=\"ahoj\">Div</div>\n", raw_html: true
989
+ tc "<p><span>Span</span><span>Span</span></p>\n", "<span>Span</span><span>Span</span>\n", raw_html: true
990
+ tc "<p><em><b>boldoitali</b></em>cE</p>\n", "<p>''<b>boldoitali''c</b>E</p>", raw_html: true
991
+ tc "<p><b>blabla</b></p>\n<p>endE</p>\n", "<p><b>bla</html>bla</p>end</b>E</p>", raw_html: true
992
+ tc "<p>baf</p>\n", "\n\n\nbaf\n\n\n", raw_html: true
993
+ tc "<div class=\"ahoj\">Div</div>\n<p>baf</p>\n", "<div class=\"ahoj\">Div</div>\nbaf\n", raw_html: true
994
+
995
+ tc "<p><b>BOLD</b></p>\n", "<b>BOLD</b>\n", raw_html: true
996
+ tc "<p><br/></p>\n", "<br/>\n", raw_html: true
997
+ tc "<p><br/></p>\n", "<br></br>\n", raw_html: true
998
+ tc "<p><b class=\"bclass\">BOLD</b></p>\n", "<b class=\"bclass\">BOLD</b>\n", raw_html: true
999
+ tc "<p><b class=\"bclass\">BOLD</b></p>\n", "<b bad=\"bad\" class=\"bclass\">BOLD</b>\n", raw_html: true
1000
+ tc "<p><b class=\"bclass\">BOLD</b></p>\n", "<b bad=\"bad\" class=\"bclass\">BOLD</b>\n", raw_html: true
1001
+ end
1002
+
1006
1003
  end
1007
1004
  end
1008
1005
  # vim: tw=0
data/test/tree_test.rb CHANGED
@@ -8,26 +8,28 @@ end
8
8
  describe TracWiki::Parser do
9
9
  it 'should work' do
10
10
  t = TracWiki::Tree.new
11
- t.tag_beg(:html)
12
- t.tag_beg(:body, {hus:'JAN', mistr: nil})
13
- t.tag(:div, {ahoj: "ahoj", bhoj: "BHOJ"})
11
+ t.tag_beg(:div, {:class => 'html'})
12
+ t.tag_beg(:div, {id:'JAN', class: nil})
13
+ t.tag(:div, {:class => "ahoj", id: "BHOJ"})
14
14
  t.tag(:br)
15
15
  t.add("bye")
16
16
  t.add_spc
17
17
  t.add("bye ")
18
18
  t.add_spc
19
19
  t.add("bye")
20
- t.tag_end(:body)
21
- t.tag_end(:html)
20
+ t.tag_end(:div)
21
+ t.tag_end(:div)
22
22
  t.add('\bye')
23
23
  t.add_raw('&gt;')
24
24
  t.add_raw('&nbsp;')
25
25
  t.add_raw('&bdquo;')
26
26
 
27
- res = "<html><body hus=\"JAN\"><div ahoj=\"ahoj\" bhoj=\"BHOJ\"/>\n<br/>bye bye bye</body></html>\\bye"
27
+ res = "<div class=\"html\"><div id=\"JAN\"><div class=\"ahoj\" id=\"BHOJ\"></div>\n<br/>bye bye bye</div>\n</div>\n\\bye"
28
28
  res += "&gt;"
29
- res += "\u00a0"
30
- res += "„"
29
+ #res += "\u00a0"
30
+ #res += "„"
31
+ res += '&nbsp;'
32
+ res += '&bdquo;'
31
33
 
32
34
  #print "\n#{t.to_html}\n#{res}"
33
35
  t.to_html.should.equal res
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.20
4
+ version: 0.2.21
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: 2014-01-06 00:00:00.000000000 Z
12
+ date: 2014-01-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bacon