app/models/wiki_content.rb in Pimki-1.3.092 vs app/models/wiki_content.rb in Pimki-1.4.092

- old
+ new

@@ -1,120 +1,132 @@ -require 'cgi' -require 'chunks/engines' -require 'chunks/category' -require 'chunks/include' -require 'chunks/todo' -require 'chunks/wiki' -require 'chunks/literal' -require 'chunks/uri' -require 'chunks/nowiki' -require 'chunks/wiki_symbols' - -# Wiki content is just a string that can process itself with a chain of -# actions. The actions can modify wiki content so that certain parts of -# it are protected from being rendered by later actions. -# -# When wiki content is rendered, it can be interrogated to find out -# which chunks were rendered. This means things like categories, wiki -# links, can be determined. -# -# Exactly how wiki content is rendered is determined by a number of -# settings that are optionally passed in to a constructor. The current -# options are: -# * :engine -# => The structural markup engine to use (Textile, Markdown, RDoc) -# * :engine_opts -# => A list of options to pass to the markup engines (safe modes, etc) -# * :pre_engine_actions -# => A list of render actions or chunks to be processed before the -# markup engine is applied. By default this is: -# Category, Include, URIChunk, WikiChunk::Link -# * :post_engine_actions -# => A list of render actions or chunks to apply after the markup -# engine. By default these are: -# Literal::Pre, Literal::Tags, WikiChunk::Word -# ToDo items -# * :mode -# => How should the content be rendered? For normal display (:display), -# publishing (:publish) or export (:export)? -# -# AUTHOR: Mark Reid <mark @ threewordslong . com> -# CREATED: 15th May 2004 -# UPDATED: 22nd May 2004 -class WikiContent < String - - # Moved URIChunk from pre-engine to post-engine, as it clashed with the textile - # markup of "link":URL. - PRE_ENGINE_ACTIONS = [ NoWiki, Category, Include, Literal::Pre, WikiSymbol, - WikiChunk::Link, WikiChunk::BlikiLink ] - POST_ENGINE_ACTIONS = [ Literal::Tags, WikiChunk::Word, URIChunk, Todo ] - - - DEFAULT_OPTS = { - :pre_engine_actions => PRE_ENGINE_ACTIONS, - :post_engine_actions => POST_ENGINE_ACTIONS, - :engine => Engines::Textile, - :engine_opts => [], - :mode => [:display] - } - - if RedCloth::VERSION >= '3.0.0' - # RedCloth v3 changes the default behaviour from not folding lines. - DEFAULT_OPTS[:engine_opts] = [:hard_breaks] - end - - attr_reader :web, :options, :rendered - - # Create a new wiki content string from the given one. - # The options are explained at the top of this file. - def initialize(revision, options = {}) - @revision = revision - @web = @revision.page.web - - # Deep copy of DEFAULT_OPTS to ensure that changes to PRE/POST_ENGINE_ACTIONS stay local - @options = Marshal.load(Marshal.dump(DEFAULT_OPTS)).update(options) - @options[:engine] = Engines::MAP[@web.markup] || Engines::Textile - @options[:engine_opts] += (@web.safe_mode ? [:filter_html, :filter_styles] : []) - - @options[:post_engine_actions].delete(WikiChunk::Word) if @web.brackets_only - - super(@revision.content) - - begin - render!(@options[:pre_engine_actions] + [@options[:engine]] + @options[:post_engine_actions]) - rescue => e - @rendered = "<strong>#{e.message}</strong><br/><br/>#{e.backtrace.join('<br/>')}" - end - end - - # Call @web.page_link using current options. - def page_link(name, text) - @web.make_link(name, text, @options) - end - - # Find all the chunks of the given types - def find_chunks(chunk_type) - rendered.select { |chunk| chunk.kind_of?(chunk_type) } - end - - # Render this content using the specified actions. - def render!(chunk_types) - @chunks = [] - chunk_types.each { |chunk_type| self.apply_type!(chunk_type) } - - # unmasking order is reversed to allow chuncks that encapsulate other chunks, - # e.g. a ToDo item with a WikiWork link. - @rendered = @chunks.reverse.map { |chunk| chunk.unmask(self) }.compact - (@chunks - @rendered).each { |chunk| chunk.revert(self) } - end - - # Find all the chunks of the given type in this content - # Each time the type's pattern is matched, create a new - # chunk for it, and replace the occurance of the chunk - # in this content with its mask. - def apply_type!(chunk_type) - self.gsub!( chunk_type.pattern ) do |match| - @chunks << chunk_type.new($~, @revision) - @chunks.last.mask(self) - end - end +require 'cgi' +require 'chunks/engines' +require 'chunks/category' +require 'chunks/include' +require 'chunks/todo' +require 'chunks/wiki' +require 'chunks/literal' +require 'chunks/uri' +require 'chunks/nowiki' +require 'chunks/wiki_symbols' + +# Wiki content is just a string that can process itself with a chain of +# actions. The actions can modify wiki content so that certain parts of +# it are protected from being rendered by later actions. +# +# When wiki content is rendered, it can be interrogated to find out +# which chunks were rendered. This means things like categories, wiki +# links, can be determined. +# +# Exactly how wiki content is rendered is determined by a number of +# settings that are optionally passed in to a constructor. The current +# options are: +# * :engine +# => The structural markup engine to use (Textile, Markdown, RDoc) +# * :engine_opts +# => A list of options to pass to the markup engines (safe modes, etc) +# * :pre_engine_actions +# => A list of render actions or chunks to be processed before the +# markup engine is applied. By default this is: +# Category, Include, URIChunk, WikiChunk::Link +# * :post_engine_actions +# => A list of render actions or chunks to apply after the markup +# engine. By default these are: +# Literal::Pre, Literal::Tags, WikiChunk::Word +# ToDo items +# * :mode +# => How should the content be rendered? For normal display (:display), +# publishing (:publish) or export (:export)? +# +# AUTHOR: Mark Reid <mark @ threewordslong . com> +# CREATED: 15th May 2004 +# UPDATED: 22nd May 2004 +class WikiContent < String + + # Moved URIChunk from pre-engine to post-engine, as it clashed with the textile + # markup of "link":URL. + PRE_ENGINE_ACTIONS = [ NoWiki, Category, Include, Literal::Pre, WikiSymbol, + WikiChunk::Link, WikiChunk::BlikiLink ] + POST_ENGINE_ACTIONS = [ Literal::Tags, WikiChunk::Word, URIChunk, Todo ] + + + DEFAULT_OPTS = { + :pre_engine_actions => PRE_ENGINE_ACTIONS, + :post_engine_actions => POST_ENGINE_ACTIONS, + :engine => Engines::Textile, + :engine_opts => [], + :mode => [:display] + } + + attr_reader :web, :options, :rendered + + # Create a new wiki content string from the given one. + # The options are explained at the top of this file. + def initialize(revision, options = {}) + @revision = revision + @web = @revision.page.web + + # Deep copy of DEFAULT_OPTS to ensure that changes to PRE/POST_ENGINE_ACTIONS stay local + @options = Marshal.load(Marshal.dump(DEFAULT_OPTS)).update(options) + @options[:engine] = Engines::MAP[@web.markup] || Engines::Textile + + @options[:engine_opts] = [] + case @options[:engine] + when Engines::Textile + if RedCloth::VERSION >= '3.0.0' + # RedCloth v3 changes the default behaviour from not folding lines. + DEFAULT_OPTS[:engine_opts] = [:hard_breaks] + end + @options[:engine_opts] += (@web.safe_mode ? [:filter_html, :filter_styles] : []) + + when Engines::BlueMarkdown, Engines::RedMarkdown + @options[:engine_opts] += (@web.safe_mode ? [:filter_html, :filter_styles] : []) + + when Engines::RDoc + nil + + end + + + @options[:post_engine_actions].delete(WikiChunk::Word) if @web.brackets_only + + super(@revision.content) + + begin + render!(@options[:pre_engine_actions] + [@options[:engine]] + @options[:post_engine_actions]) + rescue => e + @rendered = "<strong>#{e.message}</strong><br/><br/>#{e.backtrace.join('<br/>')}" + end + end + + # Call @web.page_link using current options. + def page_link(name, text) + @web.make_link(name, text, @options) + end + + # Find all the chunks of the given types + def find_chunks(chunk_type) + rendered.select { |chunk| chunk.kind_of?(chunk_type) } + end + + # Render this content using the specified actions. + def render!(chunk_types) + @chunks = [] + chunk_types.each { |chunk_type| self.apply_type!(chunk_type) } + + # unmasking order is reversed to allow chuncks that encapsulate other chunks, + # e.g. a ToDo item with a WikiWork link. + @rendered = @chunks.reverse.map { |chunk| chunk.unmask(self) }.compact + (@chunks - @rendered).each { |chunk| chunk.revert(self) } + end + + # Find all the chunks of the given type in this content + # Each time the type's pattern is matched, create a new + # chunk for it, and replace the occurance of the chunk + # in this content with its mask. + def apply_type!(chunk_type) + self.gsub!( chunk_type.pattern ) do |match| + @chunks << chunk_type.new($~, @revision) + @chunks.last.mask(self) + end + end end \ No newline at end of file