wikicloth 0.2.0 → 0.5.0
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/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
|