To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / vendor / gems / coderay-0.9.7 / lib / coderay / encoders / html / output.rb @ 442:753f1380d6bc

History | View | Annotate | Download (5.15 KB)

1
module CodeRay
2
module Encoders
3

    
4
  class HTML
5

    
6
    # This module is included in the output String from thew HTML Encoder.
7
    #
8
    # It provides methods like wrap, div, page etc.
9
    #
10
    # Remember to use #clone instead of #dup to keep the modules the object was
11
    # extended with.
12
    #
13
    # TODO: more doc.
14
    module Output
15

    
16
      require 'coderay/encoders/html/numerization.rb'
17

    
18
      attr_accessor :css
19

    
20
      class << self
21

    
22
        # This makes Output look like a class.
23
        #
24
        # Example:
25
        #
26
        #  a = Output.new '<span class="co">Code</span>'
27
        #  a.wrap! :page
28
        def new string, css = CSS.new, element = nil
29
          output = string.clone.extend self
30
          output.wrapped_in = element
31
          output.css = css
32
          output
33
        end
34

    
35
        # Raises an exception if an object that doesn't respond to to_str is extended by Output,
36
        # to prevent users from misuse. Use Module#remove_method to disable.
37
        def extended o
38
          warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
39
        end
40

    
41
        def make_stylesheet css, in_tag = false
42
          sheet = css.stylesheet
43
          sheet = <<-CSS if in_tag
44
<style type="text/css">
45
#{sheet}
46
</style>
47
          CSS
48
          sheet
49
        end
50

    
51
        def page_template_for_css css
52
          sheet = make_stylesheet css
53
          PAGE.apply 'CSS', sheet
54
        end
55

    
56
        # Define a new wrapper. This is meta programming.
57
        def wrapper *wrappers
58
          wrappers.each do |wrapper|
59
            define_method wrapper do |*args|
60
              wrap wrapper, *args
61
            end
62
            define_method "#{wrapper}!".to_sym do |*args|
63
              wrap! wrapper, *args
64
            end
65
          end
66
        end
67

    
68
      end
69

    
70
      wrapper :div, :span, :page
71

    
72
      def wrapped_in? element
73
        wrapped_in == element
74
      end
75

    
76
      def wrapped_in
77
        @wrapped_in ||= nil
78
      end
79
      attr_writer :wrapped_in
80

    
81
      def wrap_in template
82
        clone.wrap_in! template
83
      end
84

    
85
      def wrap_in! template
86
        Template.wrap! self, template, 'CONTENT'
87
        self
88
      end
89
      
90
      def apply_title! title
91
        self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
92
        self
93
      end
94

    
95
      def wrap! element, *args
96
        return self if not element or element == wrapped_in
97
        case element
98
        when :div
99
          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
100
          wrap_in! DIV
101
        when :span
102
          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
103
          wrap_in! SPAN
104
        when :page
105
          wrap! :div if wrapped_in? nil
106
          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
107
          wrap_in! Output.page_template_for_css(@css)
108
          if args.first.is_a?(Hash) && title = args.first[:title]
109
            apply_title! title
110
          end
111
          self
112
        when nil
113
          return self
114
        else
115
          raise "Unknown value %p for :wrap" % element
116
        end
117
        @wrapped_in = element
118
        self
119
      end
120

    
121
      def wrap *args
122
        clone.wrap!(*args)
123
      end
124

    
125
      def stylesheet in_tag = false
126
        Output.make_stylesheet @css, in_tag
127
      end
128

    
129
      class Template < String
130

    
131
        def self.wrap! str, template, target
132
          target = Regexp.new(Regexp.escape("<%#{target}%>"))
133
          if template =~ target
134
            str[0,0] = $`
135
            str << $'
136
          else
137
            raise "Template target <%%%p%%> not found" % target
138
          end
139
        end
140

    
141
        def apply target, replacement
142
          target = Regexp.new(Regexp.escape("<%#{target}%>"))
143
          if self =~ target
144
            Template.new($` + replacement + $')
145
          else
146
            raise "Template target <%%%p%%> not found" % target
147
          end
148
        end
149

    
150
        module Simple
151
          def ` str  #` <-- for stupid editors
152
            Template.new str
153
          end
154
        end
155
      end
156

    
157
      extend Template::Simple
158

    
159
#-- don't include the templates in docu
160

    
161
      SPAN = `<span class="CodeRay"><%CONTENT%></span>`
162

    
163
      DIV = <<-`DIV`
164
<div class="CodeRay">
165
  <div class="code"><pre><%CONTENT%></pre></div>
166
</div>
167
      DIV
168

    
169
      TABLE = <<-`TABLE`
170
<table class="CodeRay"><tr>
171
  <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
172
  <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
173
</tr></table>
174
      TABLE
175
      # title="double click to expand"
176

    
177
      LIST = <<-`LIST`
178
<ol class="CodeRay">
179
<%CONTENT%>
180
</ol>
181
      LIST
182

    
183
      PAGE = <<-`PAGE`
184
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
185
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
186
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="de">
187
<head>
188
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
189
  <title></title>
190
  <style type="text/css">
191
<%CSS%>
192
  </style>
193
</head>
194
<body style="background-color: white;">
195

196
<%CONTENT%>
197
</body>
198
</html>
199
      PAGE
200

    
201
    end
202

    
203
  end
204

    
205
end
206
end