wikicloth 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +3 -3
- data/Rakefile +19 -11
- data/lang/de.yml +24 -0
- data/lang/en.yml +35 -0
- data/lib/wikicloth.rb +47 -26
- data/lib/wikicloth/core_ext.rb +4 -0
- data/lib/wikicloth/extension.rb +60 -0
- data/lib/wikicloth/extensions/lua.rb +82 -0
- data/lib/wikicloth/extensions/lua/COPYING +18 -0
- data/lib/wikicloth/extensions/lua/luawrapper.lua +245 -0
- data/lib/wikicloth/extensions/math.rb +39 -0
- data/lib/wikicloth/extensions/poem.rb +15 -0
- data/lib/wikicloth/extensions/references.rb +48 -0
- data/lib/wikicloth/extensions/source.rb +46 -0
- data/lib/wikicloth/i18n.rb +108 -0
- data/lib/wikicloth/namespaces.rb +62 -0
- data/lib/wikicloth/parser.rb +21 -15
- data/lib/wikicloth/section.rb +1 -5
- data/lib/wikicloth/version.rb +1 -1
- data/lib/wikicloth/wiki_buffer.rb +151 -39
- data/lib/wikicloth/wiki_buffer/html_element.rb +24 -59
- data/lib/wikicloth/wiki_buffer/link.rb +3 -2
- data/lib/wikicloth/wiki_buffer/table.rb +2 -2
- data/lib/wikicloth/wiki_buffer/var.rb +80 -28
- data/lib/wikicloth/wiki_link_handler.rb +22 -29
- data/sample_documents/lua.wiki +58 -0
- data/test/locales.yml +264 -0
- data/test/test_helper.rb +1 -0
- data/test/wiki_cloth_test.rb +142 -27
- data/wikicloth.gemspec +2 -1
- metadata +34 -8
- data/lib/wikicloth/lexer.rb +0 -105
- data/lib/wikicloth/token.rb +0 -41
@@ -0,0 +1,39 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
class MathExtension < Extension
|
3
|
+
|
4
|
+
# <math>latex markup</math>
|
5
|
+
#
|
6
|
+
element 'math', :skip_html => true, :run_globals => false do |buffer|
|
7
|
+
|
8
|
+
blahtex_path = @options[:blahtex_path] || '/usr/bin/blahtex'
|
9
|
+
blahtex_png_path = @options[:blahtex_png_path] || '/tmp'
|
10
|
+
blahtex_options = @options[:blahtex_options] || '--texvc-compatible-commands --mathml-version-1-fonts --disallow-plane-1 --spacing strict'
|
11
|
+
|
12
|
+
if File.exists?(blahtex_path) && @options[:math_formatter] != :google
|
13
|
+
begin
|
14
|
+
# pass tex markup to blahtex
|
15
|
+
response = `echo '#{buffer.element_content}' | #{blahtex_path} #{blahtex_options} --png --mathml --png-directory #{blahtex_png_path}`
|
16
|
+
xml_response = REXML::Document.new(response).root
|
17
|
+
|
18
|
+
if @options[:blahtex_html_prefix]
|
19
|
+
# render as embedded image
|
20
|
+
file_md5 = xml_response.elements["png/md5"].text
|
21
|
+
"<img src=\"#{File.join(@options[:blahtex_html_prefix],"#{file_md5}.png")}\" />"
|
22
|
+
else
|
23
|
+
# render as mathml
|
24
|
+
html = xml_response.elements["mathml/markup"].text
|
25
|
+
"<math xmlns=\"http://www.w3.org/1998/Math/MathML\">#{xml_response.elements["mathml/markup"].children.to_s}</math>"
|
26
|
+
end
|
27
|
+
rescue => err
|
28
|
+
# blahtex error
|
29
|
+
"<span class=\"error\">#{I18n.t("unable to parse mathml", :error => err)}</span>"
|
30
|
+
end
|
31
|
+
else
|
32
|
+
# if blahtex does not exist fallback to google charts api
|
33
|
+
encoded_string = URI.escape(buffer.element_content, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
34
|
+
"<img src=\"https://chart.googleapis.com/chart?cht=tx&chl=#{encoded_string}\" />"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
class PoemExtension < Extension
|
3
|
+
|
4
|
+
# <poem>poem content (to preserve spacing)</poem>
|
5
|
+
#
|
6
|
+
element 'poem' do |buffer|
|
7
|
+
buffer.element_content.gsub!(/\A\n/,"") # remove new line at beginning of string
|
8
|
+
buffer.element_content.gsub!(/\n\z/,"") # remove new line at end of string
|
9
|
+
buffer.element_content.gsub!(/^\s+/) { |m| " " * m.length } # replace all spaces at beginning of line with
|
10
|
+
buffer.element_content.gsub!(/\n/,'<br />') # replace all new lines with <br />
|
11
|
+
"<div class=\"poem\">#{buffer.element_content}</div>"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
class ReferencesExtension < Extension
|
3
|
+
|
4
|
+
# <ref>reference content</ref>
|
5
|
+
# <ref name="named">reference content</ref>
|
6
|
+
# <ref name="named" />
|
7
|
+
# <ref group="group_name">reference content</ref>
|
8
|
+
#
|
9
|
+
element 'ref' do |buffer|
|
10
|
+
# find our named reference reference if it exists
|
11
|
+
named_ref = buffer.get_attribute_by_name("name")
|
12
|
+
ref = @options[:link_handler].find_reference_by_name(named_ref) unless named_ref.nil?
|
13
|
+
|
14
|
+
# reference either not "named" or first time in document
|
15
|
+
if ref.nil?
|
16
|
+
@options[:link_handler].references << { :name => named_ref, :value => buffer.element_content, :count => 0, :group => buffer.get_attribute_by_name("group") }
|
17
|
+
ref = @options[:link_handler].references.last
|
18
|
+
end
|
19
|
+
|
20
|
+
ref_id = (named_ref.nil? ? "" : "#{named_ref}_") + "#{@options[:link_handler].reference_index(ref)}-#{ref[:count]}"
|
21
|
+
cite_anchor = "#cite_note-" + (named_ref.nil? ? "" : "#{named_ref}_") + @options[:link_handler].reference_index(ref).to_s
|
22
|
+
group_label = buffer.get_attribute_by_name("group") ? "#{buffer.get_attribute_by_name("group")} " : ""
|
23
|
+
ref_link = "<a href=\"#{cite_anchor}\">#{@options[:link_handler].reference_index(ref)}</a>"
|
24
|
+
ref[:count] += 1
|
25
|
+
|
26
|
+
"<sup class=\"reference\" id=\"cite_ref-#{ref_id}\">[#{group_label}#{ref_link}]</sup>"
|
27
|
+
end
|
28
|
+
|
29
|
+
# <references />
|
30
|
+
# <references group="group_name" />
|
31
|
+
#
|
32
|
+
element 'references' do |buffer|
|
33
|
+
ref_count = 0
|
34
|
+
group_match = buffer.get_attribute_by_name("group")
|
35
|
+
refs = @options[:link_handler].references.collect { |r|
|
36
|
+
next if r[:group] != group_match
|
37
|
+
ref_count += 1
|
38
|
+
ref_name = (r[:name].nil? ? "" : r[:name].to_slug + "_")
|
39
|
+
ret = "<li id=\"cite_note-#{ref_name}#{ref_count}\"><b>"
|
40
|
+
1.upto(r[:count]) { |x| ret += "<a href=\"#cite_ref-#{ref_name}#{ref_count}-#{x-1}\">" +
|
41
|
+
(r[:count] == 1 ? "^" : (x-1).to_s(26).tr('0-9a-p', 'a-z')) + "</a> " }
|
42
|
+
ret += "</b> #{r[:value]}</li>"
|
43
|
+
}.to_s
|
44
|
+
"<ol>#{refs}</ol>"
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
class LuaExtension < Extension
|
3
|
+
|
4
|
+
VALID_LANGUAGES = [ 'as','applescript','arm','asp','asm','awk','bat','bibtex','bbcode','bison','lua',
|
5
|
+
'bms','boo','c','c++','cc','cpp','cxx','h','hh','hpp','hxx','clojure','cbl','cob','cobol','cfc','cfm',
|
6
|
+
'coldfusion','csharp','cs','css','d','diff','patch','erlang','erl','hrl','go','hs','haskell','html',
|
7
|
+
'htm','xml','xhtml','httpd','js','javascript','matlab','m','perl','cgi','pl','plex','plx','pm','php',
|
8
|
+
'php3','php4','php5','php6','python','py','ruby','rb' ]
|
9
|
+
|
10
|
+
# <source lang="language">source code</source>
|
11
|
+
#
|
12
|
+
element 'source', :skip_html => true, :run_globals => false do |buffer|
|
13
|
+
|
14
|
+
highlight_path = @options[:highlight_path] || '/usr/bin/highlight'
|
15
|
+
highlight_options = @options[:highlight_options] || '--inline-css'
|
16
|
+
|
17
|
+
name = buffer.element_name
|
18
|
+
content = buffer.element_content
|
19
|
+
content = $1 if content =~ /^\s*\n(.*)$/m
|
20
|
+
error = nil
|
21
|
+
|
22
|
+
if File.exists?(highlight_path)
|
23
|
+
begin
|
24
|
+
raise I18n.t("lang attribute is required") unless buffer.element_attributes.has_key?('lang')
|
25
|
+
raise I18n.t("unknown lang", :lang => buffer.element_attributes['lang'].downcase) unless LuaExtension::VALID_LANGUAGES.include?(buffer.element_attributes['lang'].downcase)
|
26
|
+
IO.popen("#{highlight_path} #{highlight_options} -f --syntax #{buffer.element_attributes['lang'].downcase}", "r+") do |io|
|
27
|
+
io.puts content
|
28
|
+
io.close_write
|
29
|
+
content = io.read
|
30
|
+
end
|
31
|
+
rescue => err
|
32
|
+
error = "<span class=\"error\">#{err.message}</span>"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
content = content.gsub('<','<').gsub('>','>')
|
36
|
+
end
|
37
|
+
|
38
|
+
if error.nil?
|
39
|
+
"<pre>#{content}</pre>"
|
40
|
+
else
|
41
|
+
error
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module I18n
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def default_locale
|
7
|
+
:en
|
8
|
+
end
|
9
|
+
|
10
|
+
def locale
|
11
|
+
@@locale ||= default_locale
|
12
|
+
end
|
13
|
+
|
14
|
+
def locale=(val)
|
15
|
+
@@locale = val
|
16
|
+
end
|
17
|
+
|
18
|
+
def t(*args)
|
19
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
+
key = args.shift
|
21
|
+
|
22
|
+
load_translations
|
23
|
+
use_locale = @@translations[locale].nil? || @@translations[locale].empty? ? default_locale : locale
|
24
|
+
|
25
|
+
if @@translations[use_locale].has_key?(key)
|
26
|
+
add_vars(@@translations[use_locale][key], options)
|
27
|
+
elsif use_locale != default_locale && @@translations[default_locale].has_key?(key)
|
28
|
+
add_vars(@@translations[default_locale][key], options)
|
29
|
+
else
|
30
|
+
"translation missing: #{locale}, #{key}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def available_locales
|
35
|
+
load_translations
|
36
|
+
@@available_locales
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_path
|
40
|
+
@@load_paths ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_path=(val)
|
44
|
+
@@load_paths = val
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_translations
|
48
|
+
return if initialized?
|
49
|
+
|
50
|
+
@@available_locales = []
|
51
|
+
@@translations = {}
|
52
|
+
load_path.each do |path|
|
53
|
+
Dir[path].each do |file|
|
54
|
+
begin
|
55
|
+
data = YAML::load(File.read(file))
|
56
|
+
data.each do |key,value|
|
57
|
+
@@available_locales << key.to_sym unless @@available_locales.include?(key.to_sym)
|
58
|
+
@@translations[key.to_sym] ||= {}
|
59
|
+
import_values(key.to_sym,value)
|
60
|
+
end
|
61
|
+
rescue ArgumentError => err
|
62
|
+
puts "error in #{file}: #{err.message}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
initialized!
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialized?
|
71
|
+
@@initialized ||= false
|
72
|
+
end
|
73
|
+
|
74
|
+
def initialized!
|
75
|
+
@@initialized = true
|
76
|
+
end
|
77
|
+
|
78
|
+
# Executes block with given I18n.locale set.
|
79
|
+
def with_locale(tmp_locale = nil)
|
80
|
+
if tmp_locale
|
81
|
+
current_locale = self.locale
|
82
|
+
self.locale = tmp_locale
|
83
|
+
end
|
84
|
+
yield
|
85
|
+
ensure
|
86
|
+
self.locale = current_locale if tmp_locale
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def import_values(key,values,prefix=[])
|
91
|
+
values.each do |k,value|
|
92
|
+
if value.is_a?(Hash)
|
93
|
+
import_values(key,value,prefix+[k])
|
94
|
+
else
|
95
|
+
@@translations[key.to_sym][(prefix+[k]).join(".")] = value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_vars(string, options)
|
101
|
+
options.each do |key,value|
|
102
|
+
string.gsub!(/(%\{#{key}\})/, value.to_s)
|
103
|
+
end
|
104
|
+
string
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module WikiCloth
|
2
|
+
|
3
|
+
class WikiNamespaces
|
4
|
+
class << self
|
5
|
+
|
6
|
+
NAMESPACE_TYPES = [:file,:category,:template,:special,:language,:help,:talk,:media]
|
7
|
+
|
8
|
+
def language_namespace_names
|
9
|
+
I18n.available_locales.collect { |l| l.to_s.gsub(/[_]+/,'-') }
|
10
|
+
end
|
11
|
+
|
12
|
+
def language_name(ns, locale=nil)
|
13
|
+
return nil unless language_namespace_names.include?(ns)
|
14
|
+
locale ||= I18n.locale
|
15
|
+
I18n.with_locale(locale) do
|
16
|
+
I18n.t("languages.#{ns}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def localise_ns(name, locale=nil)
|
21
|
+
locale ||= I18n.locale
|
22
|
+
ns_type = namespace_type(name)
|
23
|
+
unless ns_type.nil? || ns_type == :language
|
24
|
+
I18n.with_locale(locale) do
|
25
|
+
I18n.t("namespaces.#{ns_type.to_s}").split(",").first
|
26
|
+
end
|
27
|
+
else
|
28
|
+
name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def namespace_type(name)
|
33
|
+
return :language if language_namespace_names.include?(name)
|
34
|
+
NAMESPACE_TYPES.each { |ns| return ns if send("#{ns}_namespace_names").include?(name.downcase) }
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method, *args)
|
39
|
+
if method.to_s =~ /^([a-z]+)_namespace_names$/
|
40
|
+
@@ns_cache ||= {}
|
41
|
+
@@ns_cache[$1] ||= get_namespace_names_for($1)
|
42
|
+
elsif method.to_s =~ /^([a-z]+)_namespace\?$/
|
43
|
+
namespace_type(args.first) == $1.to_sym ? true : false
|
44
|
+
else
|
45
|
+
super(method, *args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_namespace_names_for(name)
|
50
|
+
ret = []
|
51
|
+
I18n.available_locales.each do |locale|
|
52
|
+
I18n.with_locale(locale) do
|
53
|
+
I18n.t("namespaces.#{name}").split(",").each { |ns| ret << ns.downcase unless ret.include?(ns.downcase) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
ret
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/wikicloth/parser.rb
CHANGED
@@ -2,16 +2,16 @@ module WikiCloth
|
|
2
2
|
|
3
3
|
class Parser < WikiLinkHandler
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
5
|
+
def initialize(options={})
|
6
|
+
options.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
|
}
|
13
|
-
@
|
14
|
-
@wikicloth = WikiCloth.new(
|
13
|
+
@options = { :link_handler => self, :params => {} }.merge(options)
|
14
|
+
@wikicloth = WikiCloth.new(@options)
|
15
15
|
end
|
16
16
|
|
17
17
|
class << self
|
@@ -22,8 +22,8 @@ module WikiCloth
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def toc(&block)
|
25
|
-
self.send :define_method, 'toc' do |sections|
|
26
|
-
self.instance_exec(sections, &block)
|
25
|
+
self.send :define_method, 'toc' do |sections, numbered|
|
26
|
+
self.instance_exec(sections, numbered, &block)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -76,12 +76,26 @@ module WikiCloth
|
|
76
76
|
self.instance_exec(page,&block)
|
77
77
|
end
|
78
78
|
end
|
79
|
+
|
80
|
+
def cache(&block)
|
81
|
+
self.send :define_method, 'cache' do |item|
|
82
|
+
self.instance_exec(item,&block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_missing(method, *args)
|
88
|
+
if @wikicloth.respond_to?(method)
|
89
|
+
@wikicloth.send(method, *args)
|
90
|
+
else
|
91
|
+
super(method, *args)
|
92
|
+
end
|
79
93
|
end
|
80
94
|
|
81
95
|
# Replace a section, along with any sub-section in the document
|
82
96
|
def put_section(id,data)
|
83
97
|
data = @wikicloth.sections.collect { |s| s.wikitext({ :replace => { id => data.last(1) == "\n" ? data : "#{data}\n" } }) }.join
|
84
|
-
@wikicloth = WikiCloth.new(:data => data, :link_handler => self, :params => @params)
|
98
|
+
@wikicloth = WikiCloth.new(:data => data, :link_handler => self, :params => @options[:params])
|
85
99
|
end
|
86
100
|
|
87
101
|
# Get the section, along with any sub-section of the document
|
@@ -89,14 +103,6 @@ module WikiCloth
|
|
89
103
|
@wikicloth.sections.collect { |s| s.get_section(id) }.join
|
90
104
|
end
|
91
105
|
|
92
|
-
def sections
|
93
|
-
@wikicloth.sections
|
94
|
-
end
|
95
|
-
|
96
|
-
def to_html(opts = {})
|
97
|
-
@wikicloth.to_html(opts)
|
98
|
-
end
|
99
|
-
|
100
106
|
def to_wiki
|
101
107
|
to_wikitext
|
102
108
|
end
|
data/lib/wikicloth/section.rb
CHANGED
@@ -72,12 +72,8 @@ module WikiCloth
|
|
72
72
|
if self.title.nil?
|
73
73
|
ret = ""
|
74
74
|
else
|
75
|
-
ret = "
|
76
|
-
"<span class=\"editsection\">[<a href=\"" + options[:link_handler].section_link(self.id) +
|
77
|
-
"\" title=\"Edit section: #{self.title}\">edit</a>]</span> ") +
|
78
|
-
"<span id=\"#{self.id}\" class=\"mw-headline\"><a name=\"#{self.id}\">#{self.title}</a></span></h#{self.depth}>\n"
|
75
|
+
ret = "\n#{@title}\n"
|
79
76
|
end
|
80
|
-
#ret += @template ? self.gsub(/\{\{\{\s*([A-Za-z0-9]+)\s*\}\}\}/,'\1') : self
|
81
77
|
ret += self
|
82
78
|
ret += "__TOC__" if @auto_toc
|
83
79
|
ret += @children.collect { |c| c.render(options) } .join
|
data/lib/wikicloth/version.rb
CHANGED
@@ -63,7 +63,7 @@ class WikiBuffer
|
|
63
63
|
@buffer_type
|
64
64
|
end
|
65
65
|
|
66
|
-
def
|
66
|
+
def to_html
|
67
67
|
self.params.join("\n") + (@list_data.empty? ? "" : render_list_data()) + (@paragraph_open ? "</p>" : "")
|
68
68
|
end
|
69
69
|
|
@@ -138,7 +138,7 @@ class WikiBuffer
|
|
138
138
|
while @buffers.size > 1
|
139
139
|
@buffers[-1].eof()
|
140
140
|
tmp = @buffers.pop
|
141
|
-
@buffers[-1].data += tmp.
|
141
|
+
@buffers[-1].data += tmp.send("to_#{@options[:output]}")
|
142
142
|
unless tmp.data.blank?
|
143
143
|
tmp.data.each_char { |x| self.add_char(x) }
|
144
144
|
end
|
@@ -158,9 +158,9 @@ class WikiBuffer
|
|
158
158
|
return self.new_char()
|
159
159
|
when @buffers[-1].add_char(c) == false && self.class == WikiBuffer
|
160
160
|
tmp = @buffers.pop
|
161
|
-
@buffers[-1].data += tmp.
|
161
|
+
@buffers[-1].data += tmp.send("to_#{@options[:output]}")
|
162
162
|
# any data left in the buffer we feed into the parent
|
163
|
-
unless tmp.data.
|
163
|
+
unless tmp.data.nil?
|
164
164
|
tmp.data.each_char { |x| self.add_char(x) }
|
165
165
|
end
|
166
166
|
end
|
@@ -178,11 +178,15 @@ class WikiBuffer
|
|
178
178
|
self.data.gsub!(/_([^_]+)_/,"<u>\\1</u>")
|
179
179
|
end
|
180
180
|
|
181
|
-
#
|
182
|
-
self.data.gsub!(/__([
|
183
|
-
case $1
|
184
|
-
when "
|
181
|
+
# Behavior Switches
|
182
|
+
self.data.gsub!(/__([\w]+)__/) { |r|
|
183
|
+
case behavior_switch_key_name($1)
|
184
|
+
when "behavior_switches.toc"
|
185
185
|
@options[:link_handler].toc(@options[:sections], @options[:toc_numbered])
|
186
|
+
when "behavior_switches.noeditsection"
|
187
|
+
@options[:noedit] = true
|
188
|
+
when "behavior_switches.editsection"
|
189
|
+
@options[:noedit] = false
|
186
190
|
else
|
187
191
|
""
|
188
192
|
end
|
@@ -191,14 +195,7 @@ class WikiBuffer
|
|
191
195
|
# Horizontal Rule
|
192
196
|
self.data.gsub!(/^([-]{4,})/) { |r| "<hr />" }
|
193
197
|
|
194
|
-
|
195
|
-
self.data.gsub!(/([\']{2,5})(.*?)(\1)/) { |r|
|
196
|
-
tmp = "<i>#{$2}</i>" if $1.length == 2
|
197
|
-
tmp = "<b>#{$2}</b>" if $1.length == 3
|
198
|
-
tmp = "<b>'#{$2}'</b>" if $1.length == 4
|
199
|
-
tmp = "<b><i>#{$2}</i></b>" if $1.length == 5
|
200
|
-
tmp
|
201
|
-
}
|
198
|
+
render_bold_italic()
|
202
199
|
|
203
200
|
# Lists
|
204
201
|
tmp = ''
|
@@ -218,7 +215,7 @@ class WikiBuffer
|
|
218
215
|
is_heading = false
|
219
216
|
self.data.gsub!(/^([=]{1,6})\s*(.*?)\s*(\1)/) { |r|
|
220
217
|
is_heading = true
|
221
|
-
(@paragraph_open ? "</p>" : "") +
|
218
|
+
(@paragraph_open ? "</p>" : "") + gen_heading($1.length,$2)
|
222
219
|
}
|
223
220
|
|
224
221
|
# Paragraphs
|
@@ -238,11 +235,43 @@ class WikiBuffer
|
|
238
235
|
self.params << self.data.auto_link
|
239
236
|
self.data = ""
|
240
237
|
else
|
241
|
-
self.data
|
238
|
+
self.data << current_char
|
242
239
|
end
|
243
240
|
return true
|
244
241
|
end
|
245
242
|
|
243
|
+
def behavior_switch_key_name(name)
|
244
|
+
keys = [:toc,:notoc,:forcetoc,:noeditsection,:editsection]
|
245
|
+
locales = [@options[:locale],I18n.default_locale]
|
246
|
+
values = {}
|
247
|
+
|
248
|
+
locales.each do |locale|
|
249
|
+
I18n.with_locale(locale) do
|
250
|
+
keys.each do |key|
|
251
|
+
values[I18n.t("behavior_switches.#{key.to_s}")] = "behavior_switches.#{key.to_s}"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
values[name]
|
257
|
+
end
|
258
|
+
|
259
|
+
def gen_heading(hnum,title)
|
260
|
+
id = get_id_for(title.gsub(/\s+/,'_'))
|
261
|
+
"<h#{hnum}>" + (@options[:noedit] == true ? "" :
|
262
|
+
"<span class=\"editsection\">[<a href=\"" + @options[:link_handler].section_link(id) +
|
263
|
+
"\" title=\"#{I18n.t('edit section', :name => title)}\">#{I18n.t('edit')}</a>]</span> ") +
|
264
|
+
"<span class=\"mw-headline\" id=\"#{id}\"><a name=\"#{id}\">#{title}</a></span></h#{hnum}>\n"
|
265
|
+
end
|
266
|
+
|
267
|
+
def get_id_for(val)
|
268
|
+
val.gsub!(/[^A-Za-z0-9_]+/,'')
|
269
|
+
@idmap ||= {}
|
270
|
+
@idmap[val] ||= 0
|
271
|
+
@idmap[val] += 1
|
272
|
+
@idmap[val] == 1 ? val : "#{val}-#{@idmap[val]}"
|
273
|
+
end
|
274
|
+
|
246
275
|
def name_current_param()
|
247
276
|
params[-1] = { :value => "", :name => params[-1] } unless params[-1].kind_of?(Hash) || params[-1].nil?
|
248
277
|
end
|
@@ -291,35 +320,116 @@ class WikiBuffer
|
|
291
320
|
@current_line ||= ""
|
292
321
|
end
|
293
322
|
|
323
|
+
BOLD_ITALIC_MAP = {
|
324
|
+
0 => {
|
325
|
+
:bold => [10, "<b>"],
|
326
|
+
:italic => [20, "<i>"],
|
327
|
+
:bold_italic => [40, "<i><b>"],
|
328
|
+
:four => [10, "'<b>"],
|
329
|
+
:finish => [0, ""]
|
330
|
+
},
|
331
|
+
10 => {
|
332
|
+
:bold => [0, "</b>"],
|
333
|
+
:italic => [30, "<i>"],
|
334
|
+
:bold_italic => [20, "</b><i>"],
|
335
|
+
:four => [0, "'</b>"],
|
336
|
+
:finish => [0, "</b>"]
|
337
|
+
},
|
338
|
+
20 => {
|
339
|
+
:bold => [40, "<b>"],
|
340
|
+
:italic => [0, "</i>"],
|
341
|
+
:bold_italic => [10, "</i><b>"],
|
342
|
+
:four => [40, "'<b>"],
|
343
|
+
:finish => [0, "</i>"]
|
344
|
+
},
|
345
|
+
30 => {
|
346
|
+
:bold => [20, "</i></b><i>"],
|
347
|
+
:italic => [10, "</i>"],
|
348
|
+
:bold_italic => [0, "</i></b>"],
|
349
|
+
:four => [20, "'</i></b><i>"],
|
350
|
+
:finish => [0, "</i></b>"]
|
351
|
+
},
|
352
|
+
40 => {
|
353
|
+
:bold => [20, "</b>"],
|
354
|
+
:italic => [10, "</b></i><b>"],
|
355
|
+
:bold_italic => [0, "</b></i>"],
|
356
|
+
:four => [20, "'</b>"],
|
357
|
+
:finish => [0, "</b></i>"]
|
358
|
+
},
|
359
|
+
}
|
360
|
+
|
361
|
+
def render_bold_italic()
|
362
|
+
|
363
|
+
commands = []
|
364
|
+
self.data.scan(/([\']{2,5})/) do
|
365
|
+
commands << {
|
366
|
+
:len => $1.length,
|
367
|
+
:type => [nil, nil, :italic, :bold, :four, :bold_italic][$1.length],
|
368
|
+
:pos => $~.offset(0).first
|
369
|
+
}
|
370
|
+
end
|
371
|
+
commands << {:type => :finish}
|
372
|
+
|
373
|
+
state = 0
|
374
|
+
commands.each do |c|
|
375
|
+
trans = BOLD_ITALIC_MAP[state][c[:type]]
|
376
|
+
c[:output] = trans.last
|
377
|
+
state = trans.first
|
378
|
+
end
|
379
|
+
|
380
|
+
index = 0
|
381
|
+
self.data.gsub!(/([\']{2,5})/) do
|
382
|
+
output = commands[index][:output]
|
383
|
+
index += 1
|
384
|
+
output
|
385
|
+
end
|
386
|
+
self.data << commands.last[:output]
|
387
|
+
end
|
388
|
+
|
294
389
|
def render_list_data()
|
390
|
+
|
295
391
|
ret = ""
|
296
|
-
|
297
|
-
peices = ""
|
392
|
+
last = ""
|
298
393
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
394
|
+
process_line = Proc.new do |pieces, content|
|
395
|
+
|
396
|
+
common = 0
|
397
|
+
(0..last.length - 1).each do |i|
|
398
|
+
if last[i] == pieces[i]
|
399
|
+
common += 1
|
400
|
+
else
|
401
|
+
break
|
307
402
|
end
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
403
|
+
end
|
404
|
+
|
405
|
+
close = last[common..-1].reverse
|
406
|
+
open = pieces[common..-1]
|
407
|
+
|
408
|
+
close.each_char do |e|
|
409
|
+
ret << "</#{list_inner_tag_for(e)}></#{list_tag_for(e)}>"
|
410
|
+
end
|
411
|
+
if open == '' && pieces != ''
|
412
|
+
if last != ''
|
413
|
+
ret << "</#{list_inner_tag_for(pieces[-1,1])}>"
|
314
414
|
end
|
415
|
+
ret << "<#{list_inner_tag_for(pieces[-1,1])}>"
|
416
|
+
end
|
417
|
+
open.each_char do |e|
|
418
|
+
ret << "<#{list_tag_for(e)}><#{list_inner_tag_for(e)}>"
|
315
419
|
end
|
316
|
-
|
420
|
+
|
421
|
+
ret << content
|
422
|
+
|
423
|
+
last = pieces.clone
|
424
|
+
end
|
425
|
+
|
426
|
+
(@list_data + ['']).each do |l|
|
427
|
+
if l =~ /^([#\*:;]+)\s*(.*)$/
|
428
|
+
process_line.call($1, $2)
|
317
429
|
end
|
318
430
|
end
|
319
|
-
|
320
|
-
|
321
|
-
ret += "</#{list_inner_tag_for(peices[depth,1])}></#{list_tag_for(peices[depth,1])}>"
|
322
|
-
end
|
431
|
+
process_line.call('', '')
|
432
|
+
|
323
433
|
@list_data = []
|
324
434
|
ret + "\n"
|
325
435
|
end
|
@@ -350,3 +460,5 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "wiki_buffer", "html
|
|
350
460
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wiki_buffer", "table")
|
351
461
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wiki_buffer", "var")
|
352
462
|
require File.join(File.expand_path(File.dirname(__FILE__)), "wiki_buffer", "link")
|
463
|
+
# load all extensions
|
464
|
+
Dir[File.join(File.expand_path(File.dirname(__FILE__)), "extensions/*.rb")].each { |r| require r }
|