trac-wiki 0.2.24 → 0.3.10
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/.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
|
|