wikicloth 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +14 -20
- data/Rakefile +2 -1
- data/lib/wikicloth.rb +45 -76
- data/lib/wikicloth/core_ext.rb +21 -0
- data/lib/wikicloth/parser.rb +39 -10
- data/lib/wikicloth/section.rb +82 -0
- data/lib/wikicloth/wiki_buffer/html_element.rb +4 -3
- data/lib/wikicloth/wiki_buffer/table.rb +31 -9
- data/lib/wikicloth/wiki_buffer/var.rb +7 -6
- data/lib/wikicloth/wiki_link_handler.rb +23 -21
- data/run_tests.rb +20 -14
- data/sample_documents/random.wiki +2 -2
- metadata +33 -20
- data/sample_documents/versioning.wiki +0 -76
data/README
CHANGED
@@ -14,6 +14,7 @@ Supports
|
|
14
14
|
o bold ('''), italic ('') or both (''''')
|
15
15
|
o Horizontal rule (----)
|
16
16
|
o Tables
|
17
|
+
o Table of Contents [__NOTOC__, __FORCETOC__, __TOC__]
|
17
18
|
* <code>,<nowiki>,<pre> (disable wiki markup)
|
18
19
|
o space at the beginning of a line (<pre>)
|
19
20
|
* <ref> and <references/> support
|
@@ -24,54 +25,47 @@ Install
|
|
24
25
|
|
25
26
|
git clone git://github.com/nricciar/wikicloth.git
|
26
27
|
cd wikicloth/
|
27
|
-
gem
|
28
|
-
sudo gem install wikicloth-0.
|
28
|
+
rake gem
|
29
|
+
sudo gem install pkg/wikicloth-0.2.0.gem
|
29
30
|
|
30
31
|
Usage
|
31
32
|
---------------------------------------------------
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
@wiki = WikiCloth.new({
|
34
|
+
@wiki = WikiCloth::Parser.new({
|
36
35
|
:data => "<nowiki>{{test}}</nowiki> ''Hello {{test}}!''\n",
|
37
36
|
:params => { "test" => "World" } })
|
38
37
|
@wiki.to_html => "<p>{{test}} <i>Hello World!</i></p>"
|
39
38
|
|
40
39
|
|
41
|
-
|
40
|
+
Advanced Usage
|
42
41
|
---------------------------------------------------
|
43
42
|
|
44
|
-
|
45
|
-
an [[internal link]]. If you need even more control, the link_for can also be
|
46
|
-
used to return raw html.
|
43
|
+
Most features of WikiCloth can be overriden as needed...
|
47
44
|
|
48
|
-
class
|
45
|
+
class WikiParser < WikiCloth::Parser
|
49
46
|
|
50
|
-
|
47
|
+
url_for do |page|
|
51
48
|
"javascript:alert('You clicked on: #{page}');"
|
52
49
|
end
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
link_attributes_for do |page|
|
52
|
+
{ :href => url_for(page) }
|
56
53
|
end
|
57
54
|
|
58
|
-
|
55
|
+
include_resource do |resource,options|
|
59
56
|
case resource
|
60
57
|
when "date"
|
61
58
|
Time.now.to_s
|
62
59
|
else
|
63
|
-
|
64
|
-
super(resource,options)
|
60
|
+
params[resource] unless params[resource].nil?
|
65
61
|
end
|
66
62
|
end
|
67
63
|
|
68
64
|
end
|
69
65
|
|
70
|
-
|
71
|
-
@wiki = WikiCloth::WikiCloth.new({
|
66
|
+
@wiki = WikiParser.new({
|
72
67
|
:params => { "PAGENAME" => "Testing123" },
|
73
|
-
:
|
74
|
-
:data => "Hello World From {{ PAGENAME }} on {{ date }}\n"
|
68
|
+
:data => "[[ Hello World ]] From {{ PAGENAME }} on {{ date }}\n"
|
75
69
|
})
|
76
70
|
|
77
71
|
@wiki.to_html =>
|
data/Rakefile
CHANGED
@@ -25,7 +25,7 @@ end
|
|
25
25
|
|
26
26
|
spec = Gem::Specification.new do |s|
|
27
27
|
s.name = "wikicloth"
|
28
|
-
s.version = %q{0.
|
28
|
+
s.version = %q{0.2.0}
|
29
29
|
s.author = "David Ricciardi"
|
30
30
|
s.email = "nricciar@gmail.com"
|
31
31
|
s.homepage = "http://github.com/nricciar/wikicloth"
|
@@ -40,6 +40,7 @@ spec = Gem::Specification.new do |s|
|
|
40
40
|
s.has_rdoc = false
|
41
41
|
s.extra_rdoc_files = ["README","MIT-LICENSE"]
|
42
42
|
s.description = %q{mediawiki parser}
|
43
|
+
s.add_dependency 'builder'
|
43
44
|
end
|
44
45
|
Rake::GemPackageTask.new(spec) do |pkg|
|
45
46
|
pkg.need_tar = true
|
data/lib/wikicloth.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require 'jcode'
|
1
|
+
require 'jcode' if RUBY_VERSION < '1.9'
|
2
2
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wikicloth", "core_ext")
|
3
3
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wikicloth", "wiki_buffer")
|
4
4
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wikicloth", "wiki_link_handler")
|
5
5
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wikicloth", "parser")
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "wikicloth", "section")
|
6
7
|
String.send(:include, ExtendedString)
|
7
8
|
|
8
9
|
module WikiCloth
|
@@ -15,84 +16,37 @@ module WikiCloth
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def load(data,p={})
|
18
|
-
|
19
|
-
|
20
|
-
self.sections
|
21
|
-
data
|
22
|
-
data.gsub!(/<!--(.|\s)*?-->/,"")
|
23
|
-
data.gsub!(/^[^\s]*\{\{(.*?)\}\}/){ |match| expand_templates($1,["."]) }
|
24
|
-
self.html = data
|
25
|
-
end
|
26
|
-
|
27
|
-
def sections=(val)
|
28
|
-
@sections = val
|
29
|
-
end
|
30
|
-
|
31
|
-
def sections
|
32
|
-
@sections
|
33
|
-
end
|
34
|
-
|
35
|
-
def get_sections(data)
|
36
|
-
last_head = "1"
|
37
|
-
noedit = false
|
38
|
-
sections = [{ :title => "", :content => "", :id => "1", :heading => "" }]
|
39
|
-
|
40
|
-
for line in data
|
19
|
+
depth = 1
|
20
|
+
count = 0
|
21
|
+
root = [self.sections]
|
22
|
+
data.each_line do |line|
|
41
23
|
if line =~ /^([=]{1,6})\s*(.*?)\s*(\1)/
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
if last_head.nil?
|
48
|
-
last_head = "#{section_depth}"
|
49
|
-
else
|
50
|
-
tmp = last_head.split(".")
|
51
|
-
if tmp.last.to_i < section_depth
|
52
|
-
last_head = "#{tmp[0..-1].join(".")}.#{section_depth}"
|
53
|
-
elsif tmp.last.to_i == section_depth
|
54
|
-
last_head = "#{tmp[0..-1].join(".")}"
|
55
|
-
else
|
56
|
-
last_head = "#{tmp[0..-2].join(".")}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
sections.last[:id] = get_id_for(last_head)
|
60
|
-
sections.last[:heading] = "<h#{section_depth}>" + (noedit == true ? "" :
|
61
|
-
"<span class=\"editsection\">[<a href=\"" + self.link_handler.section_link(sections.last[:id]) +
|
62
|
-
"\" title=\"Edit section: #{section_title}\">edit</a>]</span>") +
|
63
|
-
" <span id=\"#{sections.last[:id]}\" class=\"mw-headline\">#{section_title}</span></h#{section_depth}>"
|
64
|
-
elsif line =~ /__NOEDITSECTION__/
|
65
|
-
noedit = true
|
24
|
+
root << root.last[-1].children if $1.length > depth
|
25
|
+
root.pop if $1.length < depth
|
26
|
+
depth = $1.length
|
27
|
+
root.last << Section.new(line, get_id_for($2.gsub(/\s+/,'_')))
|
28
|
+
count += 1
|
66
29
|
else
|
67
|
-
|
30
|
+
root.last[-1] << line
|
68
31
|
end
|
69
32
|
end
|
70
|
-
sections
|
33
|
+
self.sections.first.auto_toc = true unless count < 4 || data =~ /__(NO|)TOC__/
|
34
|
+
self.params = p
|
71
35
|
end
|
72
36
|
|
73
|
-
def
|
74
|
-
|
75
|
-
article = link_handler.template(template)
|
76
|
-
|
77
|
-
if article.nil?
|
78
|
-
data = "{{template}}"
|
79
|
-
else
|
80
|
-
unless stack.include?(template)
|
81
|
-
data = article
|
82
|
-
else
|
83
|
-
data = "WARNING: TEMPLATE LOOP"
|
84
|
-
end
|
85
|
-
data = data.gsub(/^[^\s]*\{\{(.*?)\}\}/){ |match| expand_templates($1,stack + [template])}
|
86
|
-
end
|
87
|
-
|
88
|
-
data
|
37
|
+
def sections
|
38
|
+
@sections ||= [Section.new]
|
89
39
|
end
|
90
40
|
|
91
41
|
def render(opt={})
|
42
|
+
noedit = false
|
92
43
|
self.options = { :output => :html, :link_handler => self.link_handler, :params => self.params, :sections => self.sections }.merge(opt)
|
93
44
|
self.options[:link_handler].params = options[:params]
|
45
|
+
data = self.sections.first.render(self.options)
|
46
|
+
data.gsub!(/<!--(.|\s)*?-->/,"")
|
47
|
+
data.gsub!(/\{\{(.*?)(\|(.*?))?\}\}/){ |match| expand_templates($1,$3,["."]) }
|
94
48
|
buffer = WikiBuffer.new("",options)
|
95
|
-
|
49
|
+
data.each_char { |c| buffer.add_char(c) }
|
96
50
|
buffer.to_s
|
97
51
|
end
|
98
52
|
|
@@ -104,20 +58,39 @@ module WikiCloth
|
|
104
58
|
self.options[:link_handler] ||= WikiLinkHandler.new
|
105
59
|
end
|
106
60
|
|
107
|
-
def html
|
108
|
-
@page_data + (@page_data[-1,1] == "\n" ? "" : "\n")
|
109
|
-
end
|
110
|
-
|
111
61
|
def params
|
112
62
|
@page_params ||= {}
|
113
63
|
end
|
114
64
|
|
115
65
|
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
|
+
def sections=(val)
|
85
|
+
@sections = val
|
86
|
+
end
|
87
|
+
|
116
88
|
def get_id_for(val)
|
89
|
+
val.gsub!(/[^A-Za-z0-9_]+/,'')
|
117
90
|
@idmap ||= {}
|
118
91
|
@idmap[val] ||= 0
|
119
92
|
@idmap[val] += 1
|
120
|
-
"#{val}-#{@idmap[val]}"
|
93
|
+
@idmap[val] == 1 ? val : "#{val}-#{@idmap[val]}"
|
121
94
|
end
|
122
95
|
|
123
96
|
def options=(val)
|
@@ -128,10 +101,6 @@ module WikiCloth
|
|
128
101
|
@options ||= {}
|
129
102
|
end
|
130
103
|
|
131
|
-
def html=(val)
|
132
|
-
@page_data = val
|
133
|
-
end
|
134
|
-
|
135
104
|
def params=(val)
|
136
105
|
@page_params = val
|
137
106
|
end
|
data/lib/wikicloth/core_ext.rb
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
class Object
|
2
|
+
module InstanceExecHelper; end
|
3
|
+
include InstanceExecHelper
|
4
|
+
def instance_exec(*args, &block)
|
5
|
+
begin
|
6
|
+
old_critical, Thread.critical = Thread.critical, true
|
7
|
+
n = 0
|
8
|
+
n += 1 while respond_to?(mname="__instance_exec#{n}")
|
9
|
+
InstanceExecHelper.module_eval{ define_method(mname, &block) }
|
10
|
+
ensure
|
11
|
+
Thread.critical = old_critical
|
12
|
+
end
|
13
|
+
begin
|
14
|
+
ret = send(mname, *args)
|
15
|
+
ensure
|
16
|
+
InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
|
17
|
+
end
|
18
|
+
ret
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
1
22
|
module ExtendedString
|
2
23
|
|
3
24
|
def blank?
|
data/lib/wikicloth/parser.rb
CHANGED
@@ -6,7 +6,7 @@ module WikiCloth
|
|
6
6
|
opt.each { |k,v|
|
7
7
|
if v.instance_of?(Proc)
|
8
8
|
self.class.send :define_method, k.to_sym do |*args|
|
9
|
-
|
9
|
+
self.instance_exec(args,&v)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
}
|
@@ -17,65 +17,94 @@ module WikiCloth
|
|
17
17
|
class << self
|
18
18
|
def url_for(&block)
|
19
19
|
self.send :define_method, 'url_for' do |url|
|
20
|
-
|
20
|
+
self.instance_exec(url, &block)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def toc(&block)
|
25
25
|
self.send :define_method, 'toc' do |sections|
|
26
|
-
|
26
|
+
self.instance_exec(sections, &block)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def function(&block)
|
31
|
+
self.send :define_method, 'function' do |name, params|
|
32
|
+
self.instance_exec(name, params, &block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
30
36
|
def external_link(&block)
|
31
37
|
self.send :define_method, 'external_link' do |url,text|
|
32
|
-
|
38
|
+
self.instance_exec(url,text,&block)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
42
|
def include_resource(&block)
|
37
43
|
self.send :define_method, 'include_resource' do |resource,options|
|
38
44
|
options ||= []
|
39
|
-
|
45
|
+
self.instance_exec(resource,options,&block)
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
43
49
|
def link_for_resource(&block)
|
44
50
|
self.send :define_method, 'link_for_resource' do |prefix,resource,options|
|
45
51
|
options ||= []
|
46
|
-
|
52
|
+
self.instance_exec(prefix,resource,options,&block)
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
56
|
def section_link(&block)
|
51
57
|
self.send :define_method, 'section_link' do |section|
|
52
|
-
|
58
|
+
self.instance_exec(section,&block)
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
56
62
|
def template(&block)
|
57
63
|
self.send :define_method, 'template' do |template|
|
58
|
-
|
64
|
+
self.instance_exec(template,&block)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
68
|
def link_for(&block)
|
63
69
|
self.send :define_method, 'link_for' do |page,text|
|
64
|
-
|
70
|
+
self.instance_exec(page,text,&block)
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
68
74
|
def link_attributes_for(&block)
|
69
75
|
self.send :define_method, 'link_attributes_for' do |page|
|
70
|
-
|
76
|
+
self.instance_exec(page,&block)
|
71
77
|
end
|
72
78
|
end
|
73
79
|
end
|
74
80
|
|
81
|
+
# Replace a section, along with any sub-section in the document
|
82
|
+
def put_section(id,data)
|
83
|
+
data = @wikicloth.sections.first.wikitext({ :replace => { id => data } })
|
84
|
+
@wikicloth = WikiCloth.new(:data => data, :link_handler => self, :params => @params)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get the section, along with any sub-section of the document
|
88
|
+
def get_section(id)
|
89
|
+
@wikicloth.sections.first.get_section(id)
|
90
|
+
end
|
91
|
+
|
92
|
+
def sections
|
93
|
+
@wikicloth.sections
|
94
|
+
end
|
95
|
+
|
75
96
|
def to_html
|
76
97
|
@wikicloth.to_html
|
77
98
|
end
|
78
99
|
|
100
|
+
def to_wiki
|
101
|
+
to_wikitext
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_wikitext
|
105
|
+
@wikicloth.sections.first.wikitext()
|
106
|
+
end
|
107
|
+
|
79
108
|
end
|
80
109
|
|
81
110
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
|
3
|
+
class Section < String
|
4
|
+
|
5
|
+
def initialize(title=nil, id=nil)
|
6
|
+
self.title = title
|
7
|
+
@children = []
|
8
|
+
@id = id
|
9
|
+
end
|
10
|
+
|
11
|
+
def children
|
12
|
+
@children
|
13
|
+
end
|
14
|
+
|
15
|
+
def id
|
16
|
+
@id
|
17
|
+
end
|
18
|
+
|
19
|
+
def auto_toc=(val)
|
20
|
+
@auto_toc = val
|
21
|
+
end
|
22
|
+
|
23
|
+
def title=(val)
|
24
|
+
if val =~ /^([=]{1,6})\s*(.*?)\s*(\1)/
|
25
|
+
@depth = $1.length
|
26
|
+
@clean_title = $2
|
27
|
+
@title = val
|
28
|
+
else
|
29
|
+
@depth = 1
|
30
|
+
@clean_title = val
|
31
|
+
@title = val
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def title
|
36
|
+
@clean_title
|
37
|
+
end
|
38
|
+
|
39
|
+
def depth
|
40
|
+
@depth ||= 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_section(id)
|
44
|
+
return self.wikitext() if self.id == id
|
45
|
+
@children.each do |child|
|
46
|
+
ret = child.get_section(id)
|
47
|
+
return ret unless ret.nil?
|
48
|
+
end
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def wikitext(opt={})
|
53
|
+
options = { :replace => {} }.merge(opt)
|
54
|
+
|
55
|
+
if options[:replace][self.id].nil?
|
56
|
+
ret = "#{@title}#{self}"
|
57
|
+
ret += @children.collect { |c| c.wikitext(options) }.join
|
58
|
+
ret
|
59
|
+
else
|
60
|
+
options[:replace][self.id]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def render(opt={})
|
65
|
+
options = { :noedit => opt[:link_handler].nil? ? true : false }.merge(opt)
|
66
|
+
if self.title.nil?
|
67
|
+
ret = ""
|
68
|
+
else
|
69
|
+
ret = "<h#{self.depth}>" + (options[:noedit] == true ? "" :
|
70
|
+
"<span class=\"editsection\">[<a href=\"" + options[:link_handler].section_link(self.id) +
|
71
|
+
"\" title=\"Edit section: #{self.title}\">edit</a>]</span>") +
|
72
|
+
" <span id=\"#{self.id}\" class=\"mw-headline\">#{self.title}</span></h#{self.depth}>"
|
73
|
+
end
|
74
|
+
ret += self
|
75
|
+
ret += "__TOC__" if @auto_toc
|
76
|
+
ret += @children.collect { |c| c.render(options) } .join
|
77
|
+
ret
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -5,12 +5,13 @@ module WikiCloth
|
|
5
5
|
|
6
6
|
class WikiBuffer::HTMLElement < WikiBuffer
|
7
7
|
|
8
|
-
ALLOWED_ELEMENTS = ['a','b','i','div','span','sup','sub','strike','s','u','font','big','ref','tt','del',
|
8
|
+
ALLOWED_ELEMENTS = ['a','b','i','img','div','span','sup','sub','strike','s','u','font','big','ref','tt','del',
|
9
9
|
'small','blockquote','strong','pre','code','references','ol','li','ul','dd','dt','dl','center',
|
10
10
|
'h1','h2','h3','h4','h5','h6','p','table','tr','td','th','tbody','thead','tfoot']
|
11
|
-
ALLOWED_ATTRIBUTES = ['id','name','style','class','href','start','value','colspan'
|
11
|
+
ALLOWED_ATTRIBUTES = ['src','id','name','style','class','href','start','value','colspan','align','boder',
|
12
|
+
'cellpadding','cellspacing']
|
12
13
|
ESCAPED_TAGS = [ 'nowiki', 'pre', 'code' ]
|
13
|
-
SHORT_TAGS = [ 'meta','br','hr'
|
14
|
+
SHORT_TAGS = [ 'meta','br','hr']
|
14
15
|
NO_NEED_TO_CLOSE = ['li','p'] + SHORT_TAGS
|
15
16
|
|
16
17
|
def initialize(d="",options={},check=nil)
|
@@ -9,7 +9,6 @@ class WikiBuffer::Table < WikiBuffer
|
|
9
9
|
@start_row = false
|
10
10
|
@start_caption = false
|
11
11
|
@in_quotes = false
|
12
|
-
@attribute_name = nil
|
13
12
|
end
|
14
13
|
|
15
14
|
def table_caption
|
@@ -35,7 +34,8 @@ class WikiBuffer::Table < WikiBuffer
|
|
35
34
|
unless row.empty?
|
36
35
|
ret += "<tr" + (params[row_count].nil? || params[row_count].blank? ? "" : " #{params[row_count].strip}") + ">"
|
37
36
|
for cell in row
|
38
|
-
cell_attributes = cell[:style].blank? ? "" :
|
37
|
+
cell_attributes = cell[:style].blank? ? "" : parse_attributes(cell[:style].strip).collect { |k,v| "#{k}=\"#{v}\"" }.join(" ")
|
38
|
+
cell_attributes = cell_attributes.blank? ? "" : " #{cell_attributes}"
|
39
39
|
ret += "<#{cell[:type]}#{cell_attributes}> #{cell[:value].strip}\n</#{cell[:type]}>"
|
40
40
|
end
|
41
41
|
ret += "</tr>"
|
@@ -45,6 +45,35 @@ class WikiBuffer::Table < WikiBuffer
|
|
45
45
|
end
|
46
46
|
|
47
47
|
protected
|
48
|
+
def parse_attributes(data)
|
49
|
+
attribute_name = nil
|
50
|
+
in_quotes = false
|
51
|
+
quote_type = nil
|
52
|
+
ret = {}
|
53
|
+
d = ""
|
54
|
+
prev_char = nil
|
55
|
+
|
56
|
+
for char in data.each_char
|
57
|
+
case
|
58
|
+
when char == "=" && attribute_name.nil? && in_quotes == false
|
59
|
+
attribute_name = d.strip
|
60
|
+
d = ""
|
61
|
+
when (char == '"' || char == "'") && in_quotes == false && !attribute_name.nil?
|
62
|
+
in_quotes = true
|
63
|
+
quote_type = char
|
64
|
+
when char == quote_type && in_quotes == true && prev_char != '\\'
|
65
|
+
ret[attribute_name] = d if WikiBuffer::HTMLElement::ALLOWED_ATTRIBUTES.include?(attribute_name)
|
66
|
+
attribute_name = nil
|
67
|
+
in_quotes = false
|
68
|
+
d = ""
|
69
|
+
else
|
70
|
+
prev_char = char
|
71
|
+
d += char
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ret
|
75
|
+
end
|
76
|
+
|
48
77
|
def rows=(val)
|
49
78
|
@rows = val
|
50
79
|
end
|
@@ -87,10 +116,6 @@ class WikiBuffer::Table < WikiBuffer
|
|
87
116
|
end
|
88
117
|
|
89
118
|
case
|
90
|
-
when @check_cell_data == 1 && current_char == "="
|
91
|
-
@attribute_name = self.data.chop!
|
92
|
-
self.data = ""
|
93
|
-
|
94
119
|
# Next table cell in row (TD)
|
95
120
|
when current_char == "|" && (previous_char == "\n" || previous_char == "|") && @in_quotes == false
|
96
121
|
self.data.chop!
|
@@ -129,9 +154,6 @@ class WikiBuffer::Table < WikiBuffer
|
|
129
154
|
when current_char == '"' && previous_char != '\\'
|
130
155
|
@in_quotes = !@in_quotes
|
131
156
|
self.data += '"'
|
132
|
-
if @attribute_name && @in_quotes == false
|
133
|
-
puts "ATTR #{@attribute_name} = #{self.data}"
|
134
|
-
end
|
135
157
|
|
136
158
|
# Table params
|
137
159
|
when current_char == "\n" && @start_table == true && @in_quotes == false
|
@@ -18,14 +18,16 @@ class WikiBuffer::Var < WikiBuffer
|
|
18
18
|
|
19
19
|
def to_s
|
20
20
|
if self.is_function?
|
21
|
-
ret = "#{buffer_type}"
|
22
|
-
ret += " function #{function_name}"
|
23
|
-
ret += "(#{params.inspect})"
|
24
|
-
ret += " [#{data}]"
|
21
|
+
# ret = "#{buffer_type}"
|
22
|
+
# ret += " function #{function_name}"
|
23
|
+
# ret += "(#{params.inspect})"
|
24
|
+
# ret += " [#{data}]"
|
25
|
+
ret = @options[:link_handler].function(function_name, params.collect { |p| p.strip })
|
25
26
|
else
|
26
27
|
ret = @options[:link_handler].include_resource("#{params[0]}".strip,params[1..-1])
|
27
28
|
end
|
28
|
-
ret ||= "<!-- TEMPLATE[#{params[0]}] NOT FOUND -->"
|
29
|
+
# ret ||= "<!-- TEMPLATE[#{params[0]}] NOT FOUND -->"
|
30
|
+
ret ||= ""
|
29
31
|
ret
|
30
32
|
end
|
31
33
|
|
@@ -49,7 +51,6 @@ class WikiBuffer::Var < WikiBuffer
|
|
49
51
|
when current_char == ':' && @in_quotes == false && self.params.size <= 1
|
50
52
|
self.function_name = self.data
|
51
53
|
self.data = ""
|
52
|
-
puts "[found var function (#{function_name})"
|
53
54
|
|
54
55
|
# Dealing with variable names within functions
|
55
56
|
# and variables
|
@@ -17,32 +17,34 @@ class WikiLinkHandler
|
|
17
17
|
@params ||= {}
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
20
|
+
def function(name, params)
|
21
|
+
case name
|
22
|
+
when "#if"
|
23
|
+
params.first.blank? ? params[2] : params[1]
|
24
|
+
end
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def toc_children(children)
|
28
|
+
ret = "<ul>"
|
29
|
+
for child in children
|
30
|
+
ret += "<li><a href=\"##{child.id}\">#{child.title}</a>"
|
31
|
+
ret += toc_children(child.children) unless child.children.empty?
|
32
|
+
ret += "</li>"
|
33
|
+
end
|
34
|
+
"#{ret}</ul>"
|
35
|
+
end
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
nest_depth -= 1
|
36
|
-
end
|
37
|
-
ret += "<li><a href=\"##{section[:id]}\">#{section[:title]}</a></li>"
|
38
|
-
prev_sid = sid
|
37
|
+
def toc(sections)
|
38
|
+
ret = "<table id=\"toc\" class=\"toc\" summary=\"Contents\"><tr><td><div style=\"font-weight:bold\">Table of Contents</div><ul>"
|
39
|
+
for section in sections[0].children
|
40
|
+
ret += "<li><a href=\"##{section.id}\">#{section.title}</a>"
|
41
|
+
ret += toc_children(section.children) unless section.children.empty?
|
42
|
+
ret += "</li>"
|
39
43
|
end
|
40
|
-
ret
|
41
|
-
nest_depth.times { ret += "</ul>" }
|
42
|
-
ret
|
44
|
+
"#{ret}</ul></td></tr></table>"
|
43
45
|
end
|
44
46
|
|
45
|
-
def template(template)
|
47
|
+
def template(template, args)
|
46
48
|
nil
|
47
49
|
end
|
48
50
|
|
data/run_tests.rb
CHANGED
@@ -1,30 +1,34 @@
|
|
1
1
|
require 'init'
|
2
2
|
include WikiCloth
|
3
3
|
|
4
|
-
class
|
5
|
-
|
4
|
+
class WikiParser < WikiCloth::Parser
|
5
|
+
|
6
|
+
include_resource do |resource,options|
|
6
7
|
case resource
|
7
8
|
when "date"
|
8
9
|
Time.now.to_s
|
9
10
|
else
|
10
|
-
|
11
|
-
super(resource,options)
|
11
|
+
params[resource].nil? ? "" : params[resource]
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
|
+
url_for do |page|
|
15
16
|
"javascript:alert('You clicked on: #{page}');"
|
16
17
|
end
|
17
|
-
|
18
|
-
|
18
|
+
|
19
|
+
link_attributes_for do |page|
|
20
|
+
{ :href => url_for(page) }
|
19
21
|
end
|
22
|
+
|
20
23
|
end
|
21
|
-
|
24
|
+
|
25
|
+
@wiki = WikiCloth::Parser.new({
|
22
26
|
:data => "\n {{test}}\n\n<nowiki>{{test}}</nowiki> ''Hello {{test}}!''\n",
|
23
27
|
:params => { "test" => "World" } })
|
24
28
|
puts @wiki.to_html
|
25
|
-
|
29
|
+
|
30
|
+
@wiki = WikiParser.new({
|
26
31
|
:params => { "PAGENAME" => "Testing123" },
|
27
|
-
:link_handler => CustomLinkHandler.new,
|
28
32
|
:data => "\n[[Hello World]] From {{ PAGENAME }} on {{ date }}\n"
|
29
33
|
})
|
30
34
|
puts @wiki.to_html
|
@@ -35,14 +39,16 @@ Dir.glob("sample_documents/*.wiki").each do |x|
|
|
35
39
|
out_name = "#{x}.html"
|
36
40
|
data = File.open(x) { |x| x.read }
|
37
41
|
|
38
|
-
tmp = WikiCloth::
|
39
|
-
|
40
|
-
|
42
|
+
tmp = WikiCloth::Parser.new({
|
43
|
+
:data => data,
|
44
|
+
:params => { "PAGENAME" => "HelloWorld" }
|
45
|
+
})
|
46
|
+
out = tmp.to_html
|
41
47
|
out = "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><link rel=\"stylesheet\" href=\"default.css\" type=\"text/css\" /></head><body>#{out}</body></html>"
|
42
48
|
|
43
49
|
File.open(out_name, "w") { |x| x.write(out) }
|
44
50
|
end_time = Time.now
|
45
|
-
puts "#{out_name}: Completed (#{end_time - start_time} sec) | External Links: #{tmp.
|
51
|
+
puts "#{out_name}: Completed (#{end_time - start_time} sec) | External Links: #{tmp.external_links.size} -- References: #{tmp.references.size}"
|
46
52
|
|
47
53
|
end
|
48
54
|
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Ricciardi
|
@@ -15,10 +15,23 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-15 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: builder
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
22
35
|
description: mediawiki parser
|
23
36
|
email: nricciar@gmail.com
|
24
37
|
executables: []
|
@@ -29,33 +42,33 @@ extra_rdoc_files:
|
|
29
42
|
- README
|
30
43
|
- MIT-LICENSE
|
31
44
|
files:
|
45
|
+
- lib/wikicloth.rb
|
32
46
|
- lib/wikicloth/core_ext.rb
|
33
|
-
- lib/wikicloth/parser.rb
|
34
47
|
- lib/wikicloth/wiki_buffer/html_element.rb
|
35
|
-
- lib/wikicloth/wiki_buffer/link.rb
|
36
|
-
- lib/wikicloth/wiki_buffer/table.rb
|
37
48
|
- lib/wikicloth/wiki_buffer/var.rb
|
38
|
-
- lib/wikicloth/wiki_buffer.rb
|
49
|
+
- lib/wikicloth/wiki_buffer/table.rb
|
50
|
+
- lib/wikicloth/wiki_buffer/link.rb
|
51
|
+
- lib/wikicloth/parser.rb
|
52
|
+
- lib/wikicloth/section.rb
|
39
53
|
- lib/wikicloth/wiki_link_handler.rb
|
40
|
-
- lib/wikicloth.rb
|
54
|
+
- lib/wikicloth/wiki_buffer.rb
|
41
55
|
- tasks/wikicloth_tasks.rake
|
42
|
-
- sample_documents/air_force_one.wiki
|
43
|
-
- sample_documents/cheatsheet.wiki
|
44
|
-
- sample_documents/elements.wiki
|
45
56
|
- sample_documents/george_washington.wiki
|
46
57
|
- sample_documents/images.wiki
|
58
|
+
- sample_documents/wiki_tables.wiki
|
47
59
|
- sample_documents/lists.wiki
|
48
|
-
- sample_documents/
|
49
|
-
- sample_documents/random.wiki
|
60
|
+
- sample_documents/elements.wiki
|
50
61
|
- sample_documents/tv.wiki
|
51
|
-
- sample_documents/
|
52
|
-
- sample_documents/
|
62
|
+
- sample_documents/random.wiki
|
63
|
+
- sample_documents/air_force_one.wiki
|
64
|
+
- sample_documents/cheatsheet.wiki
|
65
|
+
- sample_documents/pipe_trick.wiki
|
53
66
|
- init.rb
|
54
67
|
- uninstall.rb
|
55
68
|
- Rakefile
|
56
69
|
- install.rb
|
57
|
-
- test/test_helper.rb
|
58
70
|
- test/wiki_cloth_test.rb
|
71
|
+
- test/test_helper.rb
|
59
72
|
- run_tests.rb
|
60
73
|
- README
|
61
74
|
- MIT-LICENSE
|
@@ -94,6 +107,6 @@ signing_key:
|
|
94
107
|
specification_version: 3
|
95
108
|
summary: An implementation of the mediawiki markup in ruby
|
96
109
|
test_files:
|
97
|
-
- test/test_helper.rb
|
98
110
|
- test/wiki_cloth_test.rb
|
111
|
+
- test/test_helper.rb
|
99
112
|
- run_tests.rb
|
@@ -1,76 +0,0 @@
|
|
1
|
-
{| style='width: 35em; margin: 1em auto; border-spacing: 0; text-align: center'
|
2
|
-
|-
|
3
|
-
| colspan='4' |
|
4
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0.2em; border-bottom: 3px solid #999; background: #eeeeee' | 0
|
5
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0' | .
|
6
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0.2em; border-bottom: 3px solid #9df; background: #eef5ff' | 0
|
7
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0' | .
|
8
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0.2em; border-bottom: 3px solid #db8; background: #fff5ee' | 17
|
9
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0' | .
|
10
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0.2em; border-bottom: 3px solid #bd8; background: #f5ffee' | 0
|
11
|
-
| colspan='1' width='1%' style='font-size: 200%; padding: 0' | .
|
12
|
-
| colspan='2' width='1%' style='font-size: 200%; padding: 0.2em; border-bottom: 3px solid #999; background: #eeeeee' | 246
|
13
|
-
| colspan='4' |
|
14
|
-
|-
|
15
|
-
| style='height: 1em' |
|
16
|
-
| style='border-bottom: 1px solid #999' |
|
17
|
-
| style='width: 1em; border-bottom: 1px solid #999' |
|
18
|
-
| style='width: 15em' style='border-bottom: 1px solid #999' |
|
19
|
-
| width='1%' style='border-right: 1px solid #999; border-bottom: 1px solid #999' |
|
20
|
-
| width='1%' style='border-left: 1px solid #999' |
|
21
|
-
| width='1%' style='border-bottom: 1px solid #9df' |
|
22
|
-
| width='1%' style='border-bottom: 1px solid #9df' |
|
23
|
-
| width='1%' style='border-right: 1px solid #9df; border-bottom: 1px solid #9df' |
|
24
|
-
| width='1%' style='border-left: 1px solid #9df' |
|
25
|
-
||
|
26
|
-
||
|
27
|
-
| width='1%' style='border-right: 1px solid #db8' |
|
28
|
-
| width='1%' style='border-left: 1px solid #db8' |
|
29
|
-
||
|
30
|
-
||
|
31
|
-
| width='1%' style='border-right: 1px solid #bd8' |
|
32
|
-
| width='1%' style='border-left: 1px solid #bd8; border-bottom: 1px solid #bd8' |
|
33
|
-
| width='1%' style='border-bottom: 1px solid #bd8' |
|
34
|
-
| style='border-right: 1px solid #999' |
|
35
|
-
| width='1%' style='border-bottom: 1px solid #999; border-left: 1px solid #999' |
|
36
|
-
| style='width: 3em; border-bottom: 1px solid #999'|
|
37
|
-
| style='width: 3em; border-bottom: 1px solid #999' |
|
38
|
-
| style='border-bottom: 1px solid #999' |
|
39
|
-
| style='height: 1em' |
|
40
|
-
|-
|
41
|
-
| style='height: 1em; border-right: 1px solid #999' |
|
42
|
-
| style='border-left: 1px solid #999; border-top: 1px solid #999' |
|
43
|
-
| style='border-top: 1px solid #999' |
|
44
|
-
| style='border-top: 1px solid #999' |
|
45
|
-
| style='border-top: 1px solid #999' |
|
46
|
-
| style='border-right: 1px solid #9df' |
|
47
|
-
| style='border-left: 1px solid #9df; border-top: 1px solid #9df' |
|
48
|
-
| style='border-top: 1px solid #9df' |
|
49
|
-
| width='1%' style='border-top: 1px solid #9df' |
|
50
|
-
| width='1%' |
|
51
|
-
||
|
52
|
-
||
|
53
|
-
| width='1%' style='border-right: 1px solid #db8' |
|
54
|
-
| width='1%' style='border-left: 1px solid #db8' |
|
55
|
-
||
|
56
|
-
||
|
57
|
-
||
|
58
|
-
| width='1%' style='border-top: 1px solid #bd8' |
|
59
|
-
| width='1%' style='border-right: 1px solid #bd8; border-top: 1px solid #bd8' |
|
60
|
-
| width='1%' style='border-left: 1px solid #bd8' |
|
61
|
-
| width='1%' style='border-top: 1px solid #999' |
|
62
|
-
| style='border-top: 1px solid #999' |
|
63
|
-
| style='border-top: 1px solid #999' |
|
64
|
-
| style='border-right: 1px solid #999; border-top: 1px solid #999' |
|
65
|
-
| width='40' style='border-left: 1px solid #999' |
|
66
|
-
|-
|
67
|
-
| colspan='2' style='padding: 0.25em; border: 2px solid #999; background: #eeeeee' | Major version number.
|
68
|
-
| colspan='1' | <div style='width: 1.5em'></div>
|
69
|
-
| colspan='5' style='padding: 0.25em; border: 2px solid #9df; background: #eef5ff' | Level of magma (0-6/7), new major version when it reaches 7.
|
70
|
-
| colspan='1' | <div style='width: 0.5em'></div>
|
71
|
-
| colspan='8' style='padding: 0.25em; border: 2px solid #db8; background: #fff5ee' | Minor feature version.
|
72
|
-
| colspan='1' | <div style='width: 0.5em'></div>
|
73
|
-
| colspan='4' style='padding: 0.25em; border: 2px solid #bd8; background: #f5ffee' | Bug/security fixes on current "major.magma.minor" version combo.
|
74
|
-
| colspan='1' | <div style='width: 1.5em'></div>
|
75
|
-
| colspan='2' style='padding: 0.25em; border: 2px solid #999; background: #eeeeee' | Number of expletives uttered during development.
|
76
|
-
|}
|