wikicloth 0.1.6 → 0.2.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/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
|
-
|}
|