wikicloth 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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| "&nbsp;" * m.length } # replace all spaces at beginning of line with &nbsp;
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('<','&lt;').gsub('>','&gt;')
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
@@ -2,16 +2,16 @@ module WikiCloth
2
2
 
3
3
  class Parser < WikiLinkHandler
4
4
 
5
- def initialize(opt={})
6
- opt.each { |k,v|
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
- @params = opt[:params] || {}
14
- @wikicloth = WikiCloth.new(:data => opt[:data], :link_handler => self, :params => @params)
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
@@ -72,12 +72,8 @@ module WikiCloth
72
72
  if self.title.nil?
73
73
  ret = ""
74
74
  else
75
- ret = "<h#{self.depth}>" + (options[:noedit] == true ? "" :
76
- "<span class=\"editsection\">&#91;<a href=\"" + options[:link_handler].section_link(self.id) +
77
- "\" title=\"Edit section: #{self.title}\">edit</a>&#93;</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
@@ -1,3 +1,3 @@
1
1
  module WikiCloth
2
- VERSION = "0.7.1" unless defined?(::WikiCloth::VERSION)
2
+ VERSION = "0.8.0" unless defined?(::WikiCloth::VERSION)
3
3
  end
@@ -63,7 +63,7 @@ class WikiBuffer
63
63
  @buffer_type
64
64
  end
65
65
 
66
- def to_s
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.to_s
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.to_s
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.blank?
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
- # Magic Words
182
- self.data.gsub!(/__([A-Z]+)__/) { |r|
183
- case $1
184
- when "TOC"
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
- # Bold, Italic
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>" : "") + "<h#{$1.length}>#{$2}</h#{$1.length}>"
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 += current_char
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\">&#91;<a href=\"" + @options[:link_handler].section_link(id) +
263
+ "\" title=\"#{I18n.t('edit section', :name => title)}\">#{I18n.t('edit')}</a>&#93;</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
- depth = 0
297
- peices = ""
392
+ last = ""
298
393
 
299
- @list_data.each do |l|
300
- if l =~ /^([#\*:;]+)\s*(.*)$/
301
- peices = $1
302
- content = $2
303
- if peices.length > depth
304
- while peices.length > depth
305
- ret += "<#{list_tag_for(peices[depth,1])}><#{list_inner_tag_for(peices[depth,1])}>"
306
- depth += 1
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
- elsif peices.length == depth
309
- ret += "</#{list_inner_tag_for(peices[depth-1,1])}><#{list_inner_tag_for(peices[depth-1,1])}>"
310
- else
311
- while peices.length < depth
312
- depth -= 1
313
- ret += "</#{list_inner_tag_for(peices[depth-1,1])}></#{list_tag_for(peices[depth-1,1])}><#{list_inner_tag_for(peices[depth-1,1])}>"
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
- ret += "#{content}"
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
- while depth > 0
320
- depth -= 1
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 }