wikicloth 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -1
- data/lib/wikicloth/calc.citrus +133 -0
- data/lib/wikicloth/core_ext.rb +12 -0
- data/lib/wikicloth/math.rb +155 -0
- data/lib/wikicloth/parser.rb +7 -7
- data/lib/wikicloth/section.rb +5 -1
- data/lib/wikicloth/wiki_buffer/template.rb +32 -0
- data/lib/wikicloth/wiki_buffer/var.rb +77 -9
- data/lib/wikicloth/wiki_link_handler.rb +25 -9
- data/lib/wikicloth.rb +13 -19
- metadata +21 -4
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'rake'
|
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
require 'rake/gempackagetask'
|
5
|
+
require 'init'
|
5
6
|
|
6
7
|
desc 'Default: run unit tests.'
|
7
8
|
task :default => :test
|
@@ -25,7 +26,7 @@ end
|
|
25
26
|
|
26
27
|
spec = Gem::Specification.new do |s|
|
27
28
|
s.name = "wikicloth"
|
28
|
-
s.version =
|
29
|
+
s.version = WikiCloth::VERSION
|
29
30
|
s.author = "David Ricciardi"
|
30
31
|
s.email = "nricciar@gmail.com"
|
31
32
|
s.homepage = "http://github.com/nricciar/wikicloth"
|
@@ -41,6 +42,7 @@ spec = Gem::Specification.new do |s|
|
|
41
42
|
s.extra_rdoc_files = ["README","MIT-LICENSE"]
|
42
43
|
s.description = %q{mediawiki parser}
|
43
44
|
s.add_dependency 'builder'
|
45
|
+
s.add_dependency 'expression_parser'
|
44
46
|
end
|
45
47
|
Rake::GemPackageTask.new(spec) do |pkg|
|
46
48
|
pkg.need_tar = true
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# A grammar for mathematical formulas that apply basic mathematical operations
|
2
|
+
# to all numbers, respecting operator precedence and grouping of expressions
|
3
|
+
# while ignoring whitespace.
|
4
|
+
#
|
5
|
+
# An identical grammar that is written using pure Ruby can be found in calc.rb.
|
6
|
+
grammar Calc
|
7
|
+
|
8
|
+
## Hierarchy
|
9
|
+
|
10
|
+
rule term
|
11
|
+
additive | factor
|
12
|
+
end
|
13
|
+
|
14
|
+
rule additive
|
15
|
+
(factor additive_operator term) {
|
16
|
+
def value
|
17
|
+
additive_operator.apply(factor.value, term.value)
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
rule factor
|
23
|
+
multiplicative | prefix
|
24
|
+
end
|
25
|
+
|
26
|
+
rule multiplicative
|
27
|
+
(prefix multiplicative_operator factor) {
|
28
|
+
def value
|
29
|
+
multiplicative_operator.apply(prefix.value, factor.value)
|
30
|
+
end
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
rule prefix
|
35
|
+
prefixed | exponent
|
36
|
+
end
|
37
|
+
|
38
|
+
rule prefixed
|
39
|
+
(unary_operator prefix) {
|
40
|
+
def value
|
41
|
+
unary_operator.apply(prefix.value)
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
rule exponent
|
47
|
+
exponential | primary
|
48
|
+
end
|
49
|
+
|
50
|
+
rule exponential
|
51
|
+
(primary exponential_operator exponent) {
|
52
|
+
def value
|
53
|
+
exponential_operator.apply(primary.value, exponent.value)
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
rule primary
|
59
|
+
group | number
|
60
|
+
end
|
61
|
+
|
62
|
+
rule group
|
63
|
+
(lparen term rparen) {
|
64
|
+
def value
|
65
|
+
term.value
|
66
|
+
end
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
## Syntax
|
71
|
+
|
72
|
+
rule number
|
73
|
+
float | integer
|
74
|
+
end
|
75
|
+
|
76
|
+
rule float
|
77
|
+
(digits '.' digits space) {
|
78
|
+
def value
|
79
|
+
text.strip.to_f
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
rule integer
|
85
|
+
(digits space) {
|
86
|
+
def value
|
87
|
+
text.strip.to_i
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
rule digits
|
93
|
+
[0-9]+ ('_' [0-9]+)*
|
94
|
+
end
|
95
|
+
|
96
|
+
rule additive_operator
|
97
|
+
(('+' | '-') space) {
|
98
|
+
def apply(n1, n2)
|
99
|
+
n1.send(text.strip, n2)
|
100
|
+
end
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
rule multiplicative_operator
|
105
|
+
(('*' | '/' | '%') space) {
|
106
|
+
def apply(n1, n2)
|
107
|
+
n1.send(text.strip, n2)
|
108
|
+
end
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
rule exponential_operator
|
113
|
+
('**' space) {
|
114
|
+
def apply(n1, n2)
|
115
|
+
n1 ** n2
|
116
|
+
end
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
rule unary_operator
|
121
|
+
(('~' | '+' | '-') space) {
|
122
|
+
def apply(n)
|
123
|
+
op = text.strip
|
124
|
+
# Unary + and - require an @.
|
125
|
+
n.send(op == '~' ? op : '%s@' % op)
|
126
|
+
end
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
rule lparen '(' space end
|
131
|
+
rule rparen ')' space end
|
132
|
+
rule space [ \t\n\r]* end
|
133
|
+
end
|
data/lib/wikicloth/core_ext.rb
CHANGED
@@ -19,6 +19,14 @@ class Object
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
module Math
|
23
|
+
def self.eval(expression)
|
24
|
+
allowed_characters = Regexp.escape('+-*/.() ')
|
25
|
+
safe_expression = expression.match(/[\d#{allowed_characters}]*/).to_s
|
26
|
+
Kernel.eval(safe_expression)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
22
30
|
module ExtendedString
|
23
31
|
|
24
32
|
def blank?
|
@@ -37,6 +45,10 @@ module ExtendedString
|
|
37
45
|
to_s
|
38
46
|
end
|
39
47
|
|
48
|
+
def last(n)
|
49
|
+
self[-n,n]
|
50
|
+
end
|
51
|
+
|
40
52
|
def dump()
|
41
53
|
ret = to_s
|
42
54
|
delete!(to_s)
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# The following code taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation
|
2
|
+
module WikiCloth
|
3
|
+
|
4
|
+
class Token
|
5
|
+
Plus = 0
|
6
|
+
Minus = 1
|
7
|
+
Multiply = 2
|
8
|
+
Divide = 3
|
9
|
+
|
10
|
+
Number = 4
|
11
|
+
|
12
|
+
LParen = 5
|
13
|
+
RParen = 6
|
14
|
+
|
15
|
+
End = 7
|
16
|
+
|
17
|
+
attr_accessor :kind
|
18
|
+
attr_accessor :value
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@kind = nil
|
22
|
+
@value = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def unknown?
|
26
|
+
@kind.nil?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Lexer
|
31
|
+
def initialize(input)
|
32
|
+
@input = input
|
33
|
+
@return_previous_token = false
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_next_token
|
37
|
+
if @return_previous_token
|
38
|
+
@return_previous_token = false
|
39
|
+
return @previous_token
|
40
|
+
end
|
41
|
+
|
42
|
+
token = Token.new
|
43
|
+
|
44
|
+
@input.lstrip!
|
45
|
+
|
46
|
+
case @input
|
47
|
+
when /\A\+/ then
|
48
|
+
token.kind = Token::Plus
|
49
|
+
when /\A-/ then
|
50
|
+
token.kind = Token::Minus
|
51
|
+
when /\A\*/ then
|
52
|
+
token.kind = Token::Multiply
|
53
|
+
when /\A\// then
|
54
|
+
token.kind = Token::Divide
|
55
|
+
when /\A\d+(\.\d+)?/
|
56
|
+
token.kind = Token::Number
|
57
|
+
token.value = $&.to_f
|
58
|
+
when /\A\(/
|
59
|
+
token.kind = Token::LParen
|
60
|
+
when /\A\)/
|
61
|
+
token.kind = Token::RParen
|
62
|
+
when ''
|
63
|
+
token.kind = Token::End
|
64
|
+
end
|
65
|
+
|
66
|
+
raise 'Unknown token' if token.unknown?
|
67
|
+
@input = $'
|
68
|
+
|
69
|
+
@previous_token = token
|
70
|
+
token
|
71
|
+
end
|
72
|
+
|
73
|
+
def revert
|
74
|
+
@return_previous_token = true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class MathParser
|
79
|
+
def parse(input)
|
80
|
+
@lexer = Lexer.new(input)
|
81
|
+
|
82
|
+
expression_value = expression
|
83
|
+
|
84
|
+
token = @lexer.get_next_token
|
85
|
+
if token.kind == Token::End
|
86
|
+
expression_value
|
87
|
+
else
|
88
|
+
raise 'End expected'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
def expression
|
94
|
+
component1 = factor
|
95
|
+
|
96
|
+
additive_operators = [Token::Plus, Token::Minus]
|
97
|
+
|
98
|
+
token = @lexer.get_next_token
|
99
|
+
while additive_operators.include?(token.kind)
|
100
|
+
component2 = factor
|
101
|
+
|
102
|
+
if token.kind == Token::Plus
|
103
|
+
component1 += component2
|
104
|
+
else
|
105
|
+
component1 -= component2
|
106
|
+
end
|
107
|
+
|
108
|
+
token = @lexer.get_next_token
|
109
|
+
end
|
110
|
+
@lexer.revert
|
111
|
+
|
112
|
+
component1
|
113
|
+
end
|
114
|
+
|
115
|
+
def factor
|
116
|
+
factor1 = number
|
117
|
+
|
118
|
+
multiplicative_operators = [Token::Multiply, Token::Divide]
|
119
|
+
|
120
|
+
token = @lexer.get_next_token
|
121
|
+
while multiplicative_operators.include?(token.kind)
|
122
|
+
factor2 = number
|
123
|
+
|
124
|
+
if token.kind == Token::Multiply
|
125
|
+
factor1 *= factor2
|
126
|
+
else
|
127
|
+
factor1 /= factor2
|
128
|
+
end
|
129
|
+
|
130
|
+
token = @lexer.get_next_token
|
131
|
+
end
|
132
|
+
@lexer.revert
|
133
|
+
|
134
|
+
factor1
|
135
|
+
end
|
136
|
+
|
137
|
+
def number
|
138
|
+
token = @lexer.get_next_token
|
139
|
+
|
140
|
+
if token.kind == Token::LParen
|
141
|
+
value = expression
|
142
|
+
|
143
|
+
expected_rparen = @lexer.get_next_token
|
144
|
+
raise 'Unbalanced parenthesis' unless expected_rparen.kind == Token::RParen
|
145
|
+
elsif token.kind == Token::Number
|
146
|
+
value = token.value
|
147
|
+
else
|
148
|
+
raise 'Not a number'
|
149
|
+
end
|
150
|
+
|
151
|
+
value
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
data/lib/wikicloth/parser.rb
CHANGED
@@ -46,6 +46,12 @@ module WikiCloth
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def template(&block)
|
50
|
+
self.send :define_method, 'template' do |template|
|
51
|
+
self.instance_exec(template,&block)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
49
55
|
def link_for_resource(&block)
|
50
56
|
self.send :define_method, 'link_for_resource' do |prefix,resource,options|
|
51
57
|
options ||= []
|
@@ -59,12 +65,6 @@ module WikiCloth
|
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
|
-
def template(&block)
|
63
|
-
self.send :define_method, 'template' do |template|
|
64
|
-
self.instance_exec(template,&block)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
68
|
def link_for(&block)
|
69
69
|
self.send :define_method, 'link_for' do |page,text|
|
70
70
|
self.instance_exec(page,text,&block)
|
@@ -80,7 +80,7 @@ module WikiCloth
|
|
80
80
|
|
81
81
|
# Replace a section, along with any sub-section in the document
|
82
82
|
def put_section(id,data)
|
83
|
-
data = @wikicloth.sections.first.wikitext({ :replace => { id => data } })
|
83
|
+
data = @wikicloth.sections.first.wikitext({ :replace => { id => data.last(1) == "\n" ? data : "#{data}\n" } })
|
84
84
|
@wikicloth = WikiCloth.new(:data => data, :link_handler => self, :params => @params)
|
85
85
|
end
|
86
86
|
|
data/lib/wikicloth/section.rb
CHANGED
@@ -20,6 +20,10 @@ module WikiCloth
|
|
20
20
|
@auto_toc = val
|
21
21
|
end
|
22
22
|
|
23
|
+
def template=(val)
|
24
|
+
@template = val
|
25
|
+
end
|
26
|
+
|
23
27
|
def title=(val)
|
24
28
|
if val =~ /^([=]{1,6})\s*(.*?)\s*(\1)/
|
25
29
|
@depth = $1.length
|
@@ -71,7 +75,7 @@ module WikiCloth
|
|
71
75
|
"\" title=\"Edit section: #{self.title}\">edit</a>]</span>") +
|
72
76
|
" <span id=\"#{self.id}\" class=\"mw-headline\">#{self.title}</span></h#{self.depth}>"
|
73
77
|
end
|
74
|
-
ret += self
|
78
|
+
ret += @template ? self.gsub(/\{\{\{\s*([A-Za-z0-9]+)\s*\}\}\}/,'\1') : self
|
75
79
|
ret += "__TOC__" if @auto_toc
|
76
80
|
ret += @children.collect { |c| c.render(options) } .join
|
77
81
|
ret
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
|
3
|
+
class WikiBuffer::Template < WikiBuffer
|
4
|
+
|
5
|
+
def initialize(data="",options={})
|
6
|
+
super(data,options)
|
7
|
+
@in_quotes = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"WICKED COOL"
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
def new_char()
|
16
|
+
case
|
17
|
+
# End of a template, variable, or function
|
18
|
+
when current_char == '}' && previous_char == '}'
|
19
|
+
puts "TEMP: #{self.data} ----"
|
20
|
+
self.data = ""
|
21
|
+
return false
|
22
|
+
|
23
|
+
else
|
24
|
+
self.data += current_char
|
25
|
+
end
|
26
|
+
|
27
|
+
return true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'expression_parser'
|
2
|
+
|
1
3
|
module WikiCloth
|
2
4
|
|
3
5
|
class WikiBuffer::Var < WikiBuffer
|
@@ -18,17 +20,83 @@ class WikiBuffer::Var < WikiBuffer
|
|
18
20
|
|
19
21
|
def to_s
|
20
22
|
if self.is_function?
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
# ret += " [#{data}]"
|
25
|
-
ret = @options[:link_handler].function(function_name, params.collect { |p| p.strip })
|
23
|
+
ret = default_functions(function_name,params.collect { |p| p.strip })
|
24
|
+
ret ||= @options[:link_handler].function(function_name, params.collect { |p| p.strip })
|
25
|
+
ret.to_s
|
26
26
|
else
|
27
27
|
ret = @options[:link_handler].include_resource("#{params[0]}".strip,params[1..-1])
|
28
|
+
# template params
|
29
|
+
ret = ret.to_s.gsub(/\{\{\{\s*([A-Za-z0-9]+)+(|\|+([^}]+))\s*\}\}\}/) { |match| get_param($1.strip,$3.to_s.strip) }
|
30
|
+
# put template at beginning of buffer
|
31
|
+
self.data = ret
|
32
|
+
""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_param(name,default=nil)
|
37
|
+
ret = nil
|
38
|
+
# numbered params
|
39
|
+
if name =~ /^[0-9]+$/
|
40
|
+
ret = self.params[name.to_i].instance_of?(Hash) ? self.params[name.to_i][:value] : self.params[name.to_i]
|
41
|
+
end
|
42
|
+
# named params
|
43
|
+
self.params.each do |param|
|
44
|
+
ret = param[:value] if param[:name] == name
|
45
|
+
end
|
46
|
+
ret.nil? ? default : ret
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_functions(name,params)
|
50
|
+
case name
|
51
|
+
when "#if"
|
52
|
+
params.first.blank? ? params[2] : params[1]
|
53
|
+
when "#switch"
|
54
|
+
params.length.times do |i|
|
55
|
+
temp = params[i].split("=")
|
56
|
+
return temp[1].strip if temp[0].strip == params[0] && i != 0
|
57
|
+
end
|
58
|
+
return ""
|
59
|
+
when "#expr"
|
60
|
+
begin
|
61
|
+
ExpressionParser::Parser.new.parse(params.first)
|
62
|
+
rescue RuntimeError
|
63
|
+
'Expression error: ' + $!
|
64
|
+
end
|
65
|
+
when "#ifeq"
|
66
|
+
if params[0] =~ /^[0-9A-Fa-f]+$/ && params[1] =~ /^[0-9A-Fa-f]+$/
|
67
|
+
params[0].to_i == params[1].to_i ? params[2] : params[3]
|
68
|
+
else
|
69
|
+
params[0] == params[1] ? params[2] : params[3]
|
70
|
+
end
|
71
|
+
when "#len"
|
72
|
+
params.first.length
|
73
|
+
when "#sub"
|
74
|
+
params.first[params[1].to_i,params[2].to_i]
|
75
|
+
when "#pad"
|
76
|
+
case params[3]
|
77
|
+
when "right"
|
78
|
+
params[0].ljust(params[1].to_i,params[2])
|
79
|
+
when "center"
|
80
|
+
params[0].center(params[1].to_i,params[2])
|
81
|
+
else
|
82
|
+
params[0].rjust(params[1].to_i,params[2])
|
83
|
+
end
|
84
|
+
when "#iferror"
|
85
|
+
params.first =~ /error/ ? params[1] : params[2]
|
86
|
+
when "#capture"
|
87
|
+
@options[:params][params.first] = params[1]
|
88
|
+
""
|
89
|
+
when "lc"
|
90
|
+
params.first.downcase
|
91
|
+
when "uc"
|
92
|
+
params.first.upcase
|
93
|
+
when "ucfirst"
|
94
|
+
params.first.capitalize
|
95
|
+
when "lcfirst"
|
96
|
+
params.first[0,1].downcase + params.first[1,-1]
|
97
|
+
when "plural"
|
98
|
+
params.first.to_i > 1 ? params[1] : params[2]
|
28
99
|
end
|
29
|
-
# ret ||= "<!-- TEMPLATE[#{params[0]}] NOT FOUND -->"
|
30
|
-
ret ||= ""
|
31
|
-
ret
|
32
100
|
end
|
33
101
|
|
34
102
|
def is_function?
|
@@ -54,7 +122,7 @@ class WikiBuffer::Var < WikiBuffer
|
|
54
122
|
|
55
123
|
# Dealing with variable names within functions
|
56
124
|
# and variables
|
57
|
-
when current_char == '=' && @in_quotes == false
|
125
|
+
when current_char == '=' && @in_quotes == false && !is_function?
|
58
126
|
self.current_param = self.data
|
59
127
|
self.data = ""
|
60
128
|
self.name_current_param()
|
@@ -18,10 +18,7 @@ class WikiLinkHandler
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def function(name, params)
|
21
|
-
|
22
|
-
when "#if"
|
23
|
-
params.first.blank? ? params[2] : params[1]
|
24
|
-
end
|
21
|
+
nil
|
25
22
|
end
|
26
23
|
|
27
24
|
def toc_children(children)
|
@@ -44,10 +41,6 @@ class WikiLinkHandler
|
|
44
41
|
"#{ret}</ul></td></tr></table>"
|
45
42
|
end
|
46
43
|
|
47
|
-
def template(template, args)
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
|
51
44
|
def external_links
|
52
45
|
@external_links ||= []
|
53
46
|
end
|
@@ -94,7 +87,30 @@ class WikiLinkHandler
|
|
94
87
|
end
|
95
88
|
|
96
89
|
def include_resource(resource, options=[])
|
97
|
-
|
90
|
+
if self.params.has_key?(resource)
|
91
|
+
self.params[resource]
|
92
|
+
else
|
93
|
+
# FIXME: hack to keep template loops from raising havoc
|
94
|
+
@include_count ||= 0
|
95
|
+
@include_count += 1
|
96
|
+
raise "Page reached maximum number of includes [1000] (possible template loop?)" if @include_count > 100
|
97
|
+
|
98
|
+
ret = template(resource)
|
99
|
+
unless ret.nil?
|
100
|
+
@included_templates ||= {}
|
101
|
+
@included_templates[resource] ||= 0
|
102
|
+
@included_templates[resource] += 1
|
103
|
+
end
|
104
|
+
ret
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def included_templates
|
109
|
+
@included_templates ||= {}
|
110
|
+
end
|
111
|
+
|
112
|
+
def template(template)
|
113
|
+
nil
|
98
114
|
end
|
99
115
|
|
100
116
|
def link_for_resource(prefix, resource, options=[])
|
data/lib/wikicloth.rb
CHANGED
@@ -8,6 +8,8 @@ String.send(:include, ExtendedString)
|
|
8
8
|
|
9
9
|
module WikiCloth
|
10
10
|
|
11
|
+
VERSION = "0.5.0"
|
12
|
+
|
11
13
|
class WikiCloth
|
12
14
|
|
13
15
|
def initialize(opt={})
|
@@ -19,6 +21,8 @@ module WikiCloth
|
|
19
21
|
depth = 1
|
20
22
|
count = 0
|
21
23
|
root = [self.sections]
|
24
|
+
|
25
|
+
# parse wiki document into sections
|
22
26
|
data.each_line do |line|
|
23
27
|
if line =~ /^([=]{1,6})\s*(.*?)\s*(\1)/
|
24
28
|
root << root.last[-1].children if $1.length > depth
|
@@ -30,7 +34,15 @@ module WikiCloth
|
|
30
34
|
root.last[-1] << line
|
31
35
|
end
|
32
36
|
end
|
37
|
+
|
38
|
+
# if we find template variables assume document is
|
39
|
+
# a template
|
40
|
+
self.sections.first.template = true if data =~ /\{\{\{\s*([A-Za-z0-9]+)\s*\}\}\}/
|
41
|
+
|
42
|
+
# If there are more than four sections enable automatic
|
43
|
+
# table of contents
|
33
44
|
self.sections.first.auto_toc = true unless count < 4 || data =~ /__(NO|)TOC__/
|
45
|
+
|
34
46
|
self.params = p
|
35
47
|
end
|
36
48
|
|
@@ -40,11 +52,11 @@ module WikiCloth
|
|
40
52
|
|
41
53
|
def render(opt={})
|
42
54
|
noedit = false
|
55
|
+
self.params.merge!({ 'WIKI_VERSION' => ::WikiCloth::VERSION })
|
43
56
|
self.options = { :output => :html, :link_handler => self.link_handler, :params => self.params, :sections => self.sections }.merge(opt)
|
44
57
|
self.options[:link_handler].params = options[:params]
|
45
58
|
data = self.sections.first.render(self.options)
|
46
59
|
data.gsub!(/<!--(.|\s)*?-->/,"")
|
47
|
-
data.gsub!(/\{\{(.*?)(\|(.*?))?\}\}/){ |match| expand_templates($1,$3,["."]) }
|
48
60
|
buffer = WikiBuffer.new("",options)
|
49
61
|
data.each_char { |c| buffer.add_char(c) }
|
50
62
|
buffer.to_s
|
@@ -63,24 +75,6 @@ module WikiCloth
|
|
63
75
|
end
|
64
76
|
|
65
77
|
protected
|
66
|
-
def expand_templates(template, args, stack)
|
67
|
-
template.strip!
|
68
|
-
article = link_handler.template(template, args)
|
69
|
-
|
70
|
-
if article.nil?
|
71
|
-
data = "{{#{template}}}"
|
72
|
-
else
|
73
|
-
unless stack.include?(template)
|
74
|
-
data = article
|
75
|
-
else
|
76
|
-
data = "WARNING: TEMPLATE LOOP"
|
77
|
-
end
|
78
|
-
data = data.gsub(/\{\{(.*?)(?:\|(.*?))?\}\}?/){ |match| expand_templates($1, $2, stack + [template])}
|
79
|
-
end
|
80
|
-
|
81
|
-
data
|
82
|
-
end
|
83
|
-
|
84
78
|
def sections=(val)
|
85
79
|
@sections = val
|
86
80
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wikicloth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Ricciardi
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-20 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,20 @@ dependencies:
|
|
32
32
|
version: "0"
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: expression_parser
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
35
49
|
description: mediawiki parser
|
36
50
|
email: nricciar@gmail.com
|
37
51
|
executables: []
|
@@ -43,10 +57,13 @@ extra_rdoc_files:
|
|
43
57
|
- MIT-LICENSE
|
44
58
|
files:
|
45
59
|
- lib/wikicloth.rb
|
60
|
+
- lib/wikicloth/calc.citrus
|
61
|
+
- lib/wikicloth/math.rb
|
46
62
|
- lib/wikicloth/core_ext.rb
|
47
63
|
- lib/wikicloth/wiki_buffer/html_element.rb
|
48
64
|
- lib/wikicloth/wiki_buffer/var.rb
|
49
65
|
- lib/wikicloth/wiki_buffer/table.rb
|
66
|
+
- lib/wikicloth/wiki_buffer/template.rb
|
50
67
|
- lib/wikicloth/wiki_buffer/link.rb
|
51
68
|
- lib/wikicloth/parser.rb
|
52
69
|
- lib/wikicloth/section.rb
|