From 429e6734173c8317dd1945696a802e9a936cdd13 Mon Sep 17 00:00:00 2001 From: murphy Date: Sat, 5 Nov 2005 02:14:23 +0000 Subject: New helper module scheme, step 1 --- lib/coderay/encoders/html/html_output.rb | 188 +++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 lib/coderay/encoders/html/html_output.rb (limited to 'lib/coderay/encoders/html/html_output.rb') diff --git a/lib/coderay/encoders/html/html_output.rb b/lib/coderay/encoders/html/html_output.rb new file mode 100644 index 0000000..f17965d --- /dev/null +++ b/lib/coderay/encoders/html/html_output.rb @@ -0,0 +1,188 @@ +module CodeRay + module Encoders + + class HTML + + # This module is included in the output String from thew HTML Encoder. + # + # It provides methods like wrap, div, page etc. + # + # Remember to use #clone instead of #dup to keep the modules the object was + # extended with. + # + # TODO: more doc. + module Output + + require 'coderay/encoders/helpers/html_numerization.rb' + + attr_accessor :wrapped_in + + class << self + + # This makes Output look like a class. + # + # Example: + # + # a = Output.new 'Code' + # a.wrap! :page + def new string, element = nil + output = string.clone.extend self + output.wrapped_in = element + output + end + + # Raises an exception if an object that doesn't respond to to_str is extended by Output, + # to prevent users from misuse. Use Module#remove_method to disable. + def extended o + warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str + end + + def stylesheet in_tag = false + ss = CSS::DEFAULT_STYLESHEET + ss = <<-CSS if in_tag + + CSS + ss + end + + def page_template_for_css css = :default + css = stylesheet if css == :default + PAGE.apply 'CSS', css + end + + # Define a new wrapper. This is meta programming. + def wrapper *wrappers + wrappers.each do |wrapper| + define_method wrapper do |*args| + wrap wrapper, *args + end + define_method "#{wrapper}!".to_sym do |*args| + wrap! wrapper, *args + end + end + end + end + + wrapper :div, :span, :page + + def wrapped_in? element + wrapped_in == element + end + + def wrap_in template + clone.wrap_in! template + end + + def wrap_in! template + Template.wrap! self, template, 'CONTENT' + self + end + + def wrap! element, *args + return self if not element or element == wrapped_in + case element + when :div + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! DIV + when :span + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! SPAN + when :page + wrap! :div if wrapped_in? nil + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div + wrap_in! Output.page_template_for_css + when nil + return self + else + raise "Unknown value %p for :wrap" % element + end + @wrapped_in = element + self + end + + def wrap *args + clone.wrap!(*args) + end + + def stylesheet in_tag = false + Output.stylesheet in_tag + end + + class Template < String + + def self.wrap! str, template, target + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if template =~ target + str[0,0] = $` + str << $' + else + raise "Template target <%%%p%%> not found" % target + end + end + + def apply target, replacement + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if self =~ target + Template.new($` + replacement + $') + else + raise "Template target <%%%p%%> not found" % target + end + end + + module Simple + def ` str #` + Template.new str + end + end + end + + extend Template::Simple + +#-- don't include the templates in docu + + SPAN = `<%CONTENT%>` + + DIV = <<-`DIV` +
+
<%CONTENT%>
+
+ DIV + + TABLE = <<-`TABLE` + + + +
<%LINE_NUMBERS%>
<%CONTENT%>
+ TABLE + # title="double click to expand" + + LIST = <<-`LIST` +
    <%CONTENT%>
+ LIST + + PAGE = <<-`PAGE` + + + + + CodeRay HTML Encoder Example + + + + +<%CONTENT%> + + + PAGE + + end + + end + +end +end -- cgit v1.2.1