trac-wiki 0.2.24 → 0.3.10
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +1 -9
- data/README +92 -11
- data/lib/trac-wiki/env.rb +92 -63
- data/lib/trac-wiki/parser.rb +248 -254
- data/lib/trac-wiki/tree.rb +22 -27
- data/lib/trac-wiki/version.rb +1 -1
- data/lib/trac-wiki.rb +4 -4
- data/test/parser_test.rb +112 -33
- metadata +2 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,26 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
trac-wiki (0.2.
|
4
|
+
trac-wiki (0.2.24)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
bacon (1.2.0)
|
10
|
-
iconv (1.0.3)
|
11
|
-
mini_portile (0.5.2)
|
12
|
-
nokogiri (1.6.1)
|
13
|
-
mini_portile (~> 0.5.0)
|
14
10
|
rake (10.0.4)
|
15
|
-
sanitize (2.0.6)
|
16
|
-
nokogiri (>= 1.4.4)
|
17
11
|
|
18
12
|
PLATFORMS
|
19
13
|
ruby
|
20
14
|
|
21
15
|
DEPENDENCIES
|
22
16
|
bacon
|
23
|
-
iconv
|
24
17
|
rake
|
25
|
-
sanitize
|
26
18
|
trac-wiki!
|
data/README
CHANGED
@@ -8,17 +8,102 @@ Project page on github:
|
|
8
8
|
|
9
9
|
== INSTALLATION ==
|
10
10
|
|
11
|
-
|
12
|
-
gem install trac-wiki
|
13
|
-
}}}
|
11
|
+
gem install trac-wiki
|
14
12
|
|
15
13
|
== SYNOPSIS ==
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
require 'trac-wiki'
|
16
|
+
html = TracWiki.render('== TracWiki text ==')
|
17
|
+
# or
|
18
|
+
html = TracWiki.render('== TracWiki text ==', options)
|
21
19
|
|
20
|
+
|
21
|
+
parser = TracWiki.parser(options)
|
22
|
+
|
23
|
+
parser.to_html(text1)
|
24
|
+
parser.to_html(text2)
|
25
|
+
|
26
|
+
|
27
|
+
== Options ==
|
28
|
+
|
29
|
+
* `allowed_schemes`
|
30
|
+
Allowed url schemes
|
31
|
+
Examples: http https ftp ftps
|
32
|
+
|
33
|
+
* `base`
|
34
|
+
base URL (or URI), for link and images
|
35
|
+
|
36
|
+
* `no_escape`
|
37
|
+
Disable url escaping for local links
|
38
|
+
Escaping: [[/Test]] --> %2FTest
|
39
|
+
No escaping: [[/Test]] --> Test
|
40
|
+
|
41
|
+
|
42
|
+
* `no_link`
|
43
|
+
Disable url escaping for local links
|
44
|
+
`[[whatwerver]]` stays `[[whatwerver]]`
|
45
|
+
|
46
|
+
* `math`
|
47
|
+
math syntax extension:
|
48
|
+
$e^x$ for inline math,
|
49
|
+
$$ e^x $$ for display math
|
50
|
+
|
51
|
+
* `allow_html`
|
52
|
+
allow some <b> <form> <html>
|
53
|
+
html will be sanitized
|
54
|
+
|
55
|
+
* `edit_heading`
|
56
|
+
add '<a class='editheading' href="?edit=N>edit</a>'
|
57
|
+
to each heading
|
58
|
+
|
59
|
+
* `merge`
|
60
|
+
understand merge tags (see diff3(1))
|
61
|
+
>>>>>>> mine
|
62
|
+
||||||| orig
|
63
|
+
=======
|
64
|
+
<<<<<<< yours
|
65
|
+
convert to <div class="merge merge-mine">mine</div>
|
66
|
+
|
67
|
+
* `id_from_heading`
|
68
|
+
every heading had id, generated from heading text
|
69
|
+
|
70
|
+
* `id_translit`
|
71
|
+
when `id_from_heading`, non ascii char are transliterated to ascii (Těžiště -> Teziste)
|
72
|
+
|
73
|
+
* `template_handler`
|
74
|
+
template_handler(macroname) -> template_text
|
75
|
+
when macros enabled and {{myCoolMacro}} ocured,
|
76
|
+
result fo `template_handler('myCoolMacro') inserted
|
77
|
+
|
78
|
+
* `macros`
|
79
|
+
enable macros|templates (in mediawiki style).
|
80
|
+
macros are in form `{{macro_name | arg1 | arg2 }}`
|
81
|
+
|
82
|
+
* `macro_commands`
|
83
|
+
like template but more powerfull
|
84
|
+
do no use.
|
85
|
+
|
86
|
+
== Other parser attributes and functions ==
|
87
|
+
|
88
|
+
* `parser.headings`
|
89
|
+
structure where headings are stored (after parse)
|
90
|
+
list of hasheses with `level` and `title`, `sline`
|
91
|
+
[ { leven: 1, # <h1>
|
92
|
+
sline: 3, # line where head starts
|
93
|
+
eline: 4, # line before next heading starts
|
94
|
+
aname: 'anchor-to-this-heading',
|
95
|
+
title: 'heading title'
|
96
|
+
},
|
97
|
+
...
|
98
|
+
]
|
99
|
+
|
100
|
+
* `parser.was_math?`
|
101
|
+
if math (inline or dispayed) was parsed.
|
102
|
+
|
103
|
+
* `parser.make_toc_html`
|
104
|
+
create html toc from previously parsed text
|
105
|
+
|
106
|
+
* `parser.add_macro_command(name, &block)`
|
22
107
|
== BUGS ==
|
23
108
|
|
24
109
|
If you found a bug, please report it at the TracWiki project's tracker
|
@@ -29,10 +114,6 @@ http://github.com/vitstradal/trac-wiki/issues
|
|
29
114
|
== AUTHORS ==
|
30
115
|
|
31
116
|
* Vitas Stradal
|
32
|
-
Based on Creole:
|
33
|
-
|
34
|
-
* Lars Christensen (larsch)
|
35
|
-
* Daniel Mendler (minad)
|
36
117
|
|
37
118
|
== LICENSE ==
|
38
119
|
|
data/lib/trac-wiki/env.rb
CHANGED
@@ -7,16 +7,19 @@ module TracWiki
|
|
7
7
|
@env = env
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# r: expanded-macro, rest-of-str, lines, offset-in-line
|
11
|
+
def parse_macro_all(macro_name, str, macro_name_size = nil)
|
12
|
+
str_size = str.size
|
13
|
+
args, rest, lines, offset = parse_balanced(str)
|
14
|
+
atput('maclen', str_size - rest.size + macro_name_size) if ! macro_name_size.nil?
|
12
15
|
if macro_name =~ /\A!/
|
13
16
|
# {{!cmd}}
|
14
|
-
mac_out
|
17
|
+
mac_out = parse_macro_cmd(macro_name, args)
|
15
18
|
else
|
16
19
|
# {{$cmd}}, {{template}}, ...
|
17
|
-
mac_out
|
20
|
+
mac_out = parse_macro_vartempl(macro_name, args)
|
18
21
|
end
|
19
|
-
return mac_out || '', rest, lines
|
22
|
+
return mac_out || '', rest, lines, offset
|
20
23
|
end
|
21
24
|
|
22
25
|
# read to args to }} (while balancing {{ and }})
|
@@ -24,57 +27,74 @@ module TracWiki
|
|
24
27
|
# mac_out -- string to }} (macros inside expanded)
|
25
28
|
# rest -- str aftrer }}
|
26
29
|
# lines -- howmany \n eaten from str (from begining to }})
|
27
|
-
def parse_macro_vartempl(macro_name,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# FIXME: MACRO_REX
|
32
|
-
# prefix }}... {{macro_name
|
33
|
-
while str =~ TracWiki::Parser::MACRO_END_REX
|
34
|
-
prefix, bracket, sub_macro_name, str = $1, $2, $3, $'
|
35
|
-
arg << prefix
|
36
|
-
lines += prefix.count("\n")
|
37
|
-
if bracket == '}}'
|
38
|
-
#print "prefix: #{prefix}\n"
|
39
|
-
return do_macro_var($1, arg), str, lines if macro_name =~ /^\$(.*)/
|
40
|
-
return do_macro_templ(macro_name, arg), str, lines
|
41
|
-
end
|
42
|
-
|
43
|
-
# we need to go deeper!
|
44
|
-
mac_out, str, l = parse_macro_all(sub_macro_name, str)
|
45
|
-
arg << mac_out
|
46
|
-
lines += l
|
47
|
-
end
|
48
|
-
print "Error parsing macro(#{macro_name}) near '#{str}'(#{str_orig}) (arg:#{arg}, lines=#{lines})\n"
|
49
|
-
raise "Error parsing macro near '#{str}' (arg:#{arg}, lines=#{lines})"
|
30
|
+
def parse_macro_vartempl(macro_name, args)
|
31
|
+
args.map! { |arg| expand(arg) }
|
32
|
+
return do_macro_var($1, args) if macro_name =~ /^\$(.*)/
|
33
|
+
return do_macro_templ(macro_name, args)
|
50
34
|
end
|
51
35
|
|
36
|
+
# # parse to next }} (with balanced {{..}})
|
37
|
+
# # output will be parsed tree: [ "string", [ "string", ... ], "string", [..],[..] ]
|
38
|
+
# def parse_macro_tree(macro_name, str)
|
39
|
+
# return do_macro_cmd(macro_name, []), $', 0 if str =~ /\A}}/
|
40
|
+
# #print "_parse_macro_cmd: #{macro_name}, str#{str}\n"
|
41
|
+
# lines = 0
|
42
|
+
# tree = []
|
43
|
+
# cur = tree
|
44
|
+
# stack = []
|
45
|
+
# while str =~ /{{|}}/
|
46
|
+
# prefix, match, str = $`, $&, $'
|
47
|
+
# cur.push(prefix) if prefix.size > 0
|
48
|
+
# lines += prefix.count("\n")
|
49
|
+
# if match == '{{'
|
50
|
+
# stack.push(cur)
|
51
|
+
# cur.push([])
|
52
|
+
# cur = cur[-1]
|
53
|
+
# elsif match == '}}'
|
54
|
+
# return tree, str, lines if cur == tree
|
55
|
+
# cur = stack.pop
|
56
|
+
# else
|
57
|
+
# raise "never happen"
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
# raise "eol in parsing macro params"
|
61
|
+
# end
|
62
|
+
|
63
|
+
|
52
64
|
# parse to next }} (with balanced {{..}})
|
53
65
|
# like parse_macro_vartempl but not expand content
|
54
66
|
# r: [expansion, rest_of_str, count_of_consumed_lines]
|
55
|
-
def parse_macro_cmd(macro_name,
|
67
|
+
def parse_macro_cmd(macro_name, args)
|
68
|
+
return do_macro_cmd(macro_name, args)
|
69
|
+
end
|
70
|
+
|
71
|
+
# r: [args], rest-of-str, num-of-lines, offset-last-line
|
72
|
+
def parse_balanced(str)
|
56
73
|
str.sub!(/\A\s*\|?/, '')
|
57
|
-
|
58
|
-
|
74
|
+
offset = $&.size
|
75
|
+
return [], $', 0, 2 if str =~ /\A}}/
|
76
|
+
#print "_parse_macro_cmd: #{macro_name}, str#{str}\n"
|
59
77
|
dep = 0
|
60
78
|
lines = 0
|
61
79
|
args = ['']
|
62
|
-
while str =~ /{{|}}|\|/
|
80
|
+
while str =~ /{{|}}|\n|\|/
|
63
81
|
prefix, match, str = $`, $&, $'
|
82
|
+
offset += prefix.size + match.size
|
83
|
+
#raise "offset is nil" if offset.nil?
|
64
84
|
args[-1] += prefix
|
65
|
-
lines += prefix.count("\n")
|
66
85
|
if match == '{{'
|
67
86
|
dep += 1
|
68
|
-
args[-1] += $&
|
69
87
|
elsif match == '}}'
|
70
88
|
dep -= 1
|
71
|
-
return
|
72
|
-
|
89
|
+
return args, str, lines, offset if dep < 0
|
90
|
+
elsif match == "\n"
|
91
|
+
lines += 1
|
92
|
+
offset = 0
|
73
93
|
elsif match == '|' && dep == 0
|
74
94
|
args.push('')
|
75
|
-
|
76
|
-
args[-1] += $&
|
95
|
+
next
|
77
96
|
end
|
97
|
+
args[-1] += $&
|
78
98
|
end
|
79
99
|
raise "eol in parsing macro params"
|
80
100
|
end
|
@@ -83,17 +103,17 @@ module TracWiki
|
|
83
103
|
# r: result of {{!cmd}}
|
84
104
|
def do_macro_cmd(macro_name, args)
|
85
105
|
return '|' if macro_name == '!'
|
86
|
-
if @parser.
|
87
|
-
@env[
|
88
|
-
@env[
|
106
|
+
if @parser.macro_commands.key?(macro_name)
|
107
|
+
@env[:cmd_args] = args
|
108
|
+
@env[:cmd_arg0] = macro_name
|
89
109
|
#print "mac: #{macro_name} env:" ; pp (@env)
|
90
|
-
ret = @parser.
|
110
|
+
ret = @parser.macro_commands[macro_name].call(self)
|
91
111
|
return ret
|
92
112
|
end
|
93
113
|
"UCMD(#{macro_name}|#{@env['arg']})"
|
94
114
|
end
|
95
115
|
def arg(idx)
|
96
|
-
@env[
|
116
|
+
@env[:cmd_args][idx] || ''
|
97
117
|
end
|
98
118
|
|
99
119
|
def prepare_y
|
@@ -116,11 +136,13 @@ module TracWiki
|
|
116
136
|
#pp @env
|
117
137
|
return @env[key] || default if key.is_a? Symbol
|
118
138
|
prepare_y if key =~ /^y\./
|
139
|
+
key = "argv.#{key}" if key =~ /^\d+$/
|
140
|
+
#print "key: #{key}\n"
|
119
141
|
cur = @env
|
120
142
|
key.split(/\./).each do |subkey|
|
121
143
|
subkey = at($1, '') if subkey =~ /\A\$(.*)/
|
122
144
|
#print "at:subkey: #{subkey}\n"
|
123
|
-
if
|
145
|
+
if cur.is_a? Hash
|
124
146
|
cur = cur[subkey]
|
125
147
|
elsif cur.is_a? Array
|
126
148
|
cur = cur[subkey.to_i]
|
@@ -174,15 +196,15 @@ module TracWiki
|
|
174
196
|
# expand macro `macro_name` with `args`
|
175
197
|
# afer expansion all {{macros}} will be expanded recursively
|
176
198
|
# r: expanded string
|
177
|
-
def do_macro_templ(macro_name,
|
199
|
+
def do_macro_templ(macro_name, args)
|
178
200
|
return "!{{toc}}" if macro_name == 'toc'
|
179
|
-
return
|
201
|
+
return args.join('|').strip if macro_name == '#echo'
|
180
202
|
return '' if macro_name == '#'
|
181
203
|
|
182
|
-
env = do_macro_arg_to_env(
|
204
|
+
env = do_macro_arg_to_env(args)
|
183
205
|
|
184
206
|
#print "templ:#{macro_name}env:"
|
185
|
-
#pp(
|
207
|
+
#pp(args)
|
186
208
|
|
187
209
|
if ! @parser.template_handler.nil?
|
188
210
|
str = @parser.template_handler.call(macro_name, env)
|
@@ -200,38 +222,44 @@ module TracWiki
|
|
200
222
|
return str
|
201
223
|
end
|
202
224
|
end
|
203
|
-
#print "UMACRO(#{macro_name}|#{
|
204
|
-
"UMACRO(#{macro_name}|#{
|
225
|
+
#print "UMACRO(#{macro_name}|#{args})\n"
|
226
|
+
"UMACRO(#{macro_name}|#{args.join('|')})"
|
205
227
|
end
|
206
228
|
|
207
|
-
def do_macro_arg_to_env(
|
208
|
-
|
209
|
-
env
|
229
|
+
def do_macro_arg_to_env(args)
|
230
|
+
env = {}
|
231
|
+
@env.each do |k,v|
|
232
|
+
env[k] = v if k != :depth && k != 'arg' && k!='argv'
|
233
|
+
end
|
234
|
+
env[:depth] = (@env[:depth]||0)+1
|
235
|
+
env['arg'] = args.join('|')
|
236
|
+
env['argv'] = {}
|
237
|
+
|
210
238
|
idx = 1
|
211
|
-
|
212
|
-
|
213
|
-
if val =~ /\A\s*(\w+)\s*=\s*(.*)/m
|
239
|
+
args.each do |arg|
|
240
|
+
if arg =~ /\A\s*(\w+)\s*=\s*(.*)/m
|
214
241
|
env[$1] = $2
|
215
242
|
else
|
216
|
-
env[idx.to_s] =
|
243
|
+
env['argv'][idx.to_s] = arg
|
217
244
|
idx+=1
|
218
245
|
end
|
219
246
|
end
|
220
247
|
return Env.new(@parser, env)
|
221
248
|
end
|
222
249
|
|
223
|
-
def do_macro_var(var_name,
|
250
|
+
def do_macro_var(var_name, args)
|
224
251
|
#print "var(#{var_name})env:"
|
225
252
|
#pp(@env)
|
226
253
|
ret = at(var_name, nil)
|
227
254
|
return ret if !ret.nil?
|
228
|
-
return
|
229
|
-
|
255
|
+
return args.join('|') if args.size > 0
|
256
|
+
return ''
|
257
|
+
"UVAR(#{var_name}|#{@env['arg']})"
|
230
258
|
end
|
231
259
|
|
232
260
|
# template expand
|
233
261
|
def expand_arg(idx)
|
234
|
-
expand(@env[
|
262
|
+
expand(@env[:cmd_args][idx])
|
235
263
|
end
|
236
264
|
|
237
265
|
def pp_env
|
@@ -244,14 +272,15 @@ module TracWiki
|
|
244
272
|
prefix, macro_name2, str = $1, $2, $'
|
245
273
|
ret << prefix
|
246
274
|
# FIXME if macro_name2 =~ /^!/
|
247
|
-
mac_out, str, lines = parse_macro_all(macro_name2, str)
|
275
|
+
mac_out, str, lines, offset = parse_macro_all(macro_name2, str, nil)
|
248
276
|
ret << mac_out
|
249
277
|
#print "Too long macro expadion" if ret.size > 1_000_000
|
250
278
|
raise TooLongException if ret.size > 1_000_000
|
251
279
|
end
|
252
280
|
#print "text: #{text.nil?}\n"
|
253
281
|
#print "ret: #{ret.nil?}\n"
|
254
|
-
|
282
|
+
ret += str
|
283
|
+
return ret.gsub(/\\\r?\n\s*/, '')
|
255
284
|
end
|
256
285
|
end
|
257
286
|
|