Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 193
- Log:
First stage commit of Typo 4.1, modified for the ROOL site.
Includes all local modifications but a final pass needs to be
made to delete any files left over from earlier Typo versions
that shouldn't be here anymore. See the 'tags' section of the
repository for a clean Typo 4.1 tree.Note that symlinks to shared files in the RISC OS Open theme
directory have been deliberately included this time around; I
decided that on balance it was better to leave them in as
placeholders, since unlike symlinks in app/views/shared, the
Typo theme structure is not a standard Rails concept.
- Author:
- rool
- Date:
- Wed Apr 04 18:51:02 +0100 2007
- Size:
- 6698 Bytes
1 | module Haml |
2 | # This class is used only internally. It holds the buffer of XHTML that |
3 | # is eventually output by Haml::Engine's to_html method. It's called |
4 | # from within the precompiled code, and helps reduce the amount of |
5 | # processing done within instance_eval'd code. |
6 | class Buffer |
7 | include Haml::Helpers |
8 | |
9 | # Set the maximum length for a line to be considered a one-liner. |
10 | # Lines <= the maximum will be rendered on one line, |
11 | # i.e. <tt><p>Hello world</p></tt> |
12 | ONE_LINER_LENGTH = 50 |
13 | |
14 | # The string that holds the compiled XHTML. This is aliased as |
15 | # _erbout for compatibility with ERB-specific code. |
16 | attr_accessor :buffer |
17 | |
18 | # The number of tabs that are added or subtracted from the |
19 | # tabulation proscribed by the precompiled template. |
20 | attr_accessor :tabulation |
21 | |
22 | # Creates a new buffer. |
23 | def initialize(options = {}) |
24 | @options = options |
25 | @quote_escape = options[:attr_wrapper] == '"' ? """ : "'" |
26 | @other_quote_char = options[:attr_wrapper] == '"' ? "'" : '"' |
27 | @buffer = "" |
28 | @one_liner_pending = false |
29 | @tabulation = 0 |
30 | end |
31 | |
32 | # Renders +text+ with the proper tabulation. This also deals with |
33 | # making a possible one-line tag one line or not. |
34 | def push_text(text, tabulation, flattened = false) |
35 | if flattened |
36 | # In this case, tabulation is the number of spaces, rather |
37 | # than the number of tabs. |
38 | @buffer << "#{' ' * tabulation}#{flatten(text + "\n")}" |
39 | @one_liner_pending = true |
40 | elsif @one_liner_pending && one_liner?(text) |
41 | @buffer << text |
42 | else |
43 | if @one_liner_pending |
44 | @buffer << "\n" |
45 | @one_liner_pending = false |
46 | end |
47 | @buffer << "#{tabs(tabulation)}#{text}\n" |
48 | end |
49 | end |
50 | |
51 | # Properly formats the output of a script that was run in the |
52 | # instance_eval. |
53 | def push_script(result, tabulation, flattened) |
54 | if flattened |
55 | result = find_and_flatten(result) |
56 | end |
57 | unless result.nil? |
58 | result = result.to_s |
59 | while result[-1] == 10 # \n |
60 | # String#chomp is slow |
61 | result = result[0...-1] |
62 | end |
63 | |
64 | result = result.gsub("\n", "\n#{tabs(tabulation)}") |
65 | push_text result, tabulation |
66 | end |
67 | nil |
68 | end |
69 | |
70 | # Takes the various information about the opening tag for an |
71 | # element, formats it, and adds it to the buffer. |
72 | def open_tag(name, tabulation, atomic, try_one_line, class_id, attributes_hash, obj_ref, flattened) |
73 | attributes = {} |
74 | attributes.merge!(parse_object_ref(obj_ref)) if obj_ref |
75 | attributes.merge!(parse_class_and_id(class_id)) unless class_id.nil? || class_id.empty? |
76 | attributes.merge!(attributes_hash) if attributes_hash |
77 | |
78 | @one_liner_pending = false |
79 | if atomic |
80 | str = " />\n" |
81 | elsif try_one_line |
82 | @one_liner_pending = true |
83 | str = ">" |
84 | elsif flattened |
85 | str = ">
" |
86 | else |
87 | str = ">\n" |
88 | end |
89 | @buffer << "#{tabs(tabulation)}<#{name}#{build_attributes(attributes)}#{str}" |
90 | end |
91 | |
92 | # Creates a closing tag with the given name. |
93 | def close_tag(name, tabulation) |
94 | if @one_liner_pending |
95 | @buffer << "</#{name}>\n" |
96 | @one_liner_pending = false |
97 | else |
98 | push_text("</#{name}>", tabulation) |
99 | end |
100 | end |
101 | |
102 | # Opens an XHTML comment. |
103 | def open_comment(try_one_line, conditional, tabulation) |
104 | conditional << ">" if conditional |
105 | @buffer << "#{tabs(tabulation)}<!--#{conditional.to_s} " |
106 | if try_one_line |
107 | @one_liner_pending = true |
108 | else |
109 | @buffer << "\n" |
110 | end |
111 | end |
112 | |
113 | # Closes an XHTML comment. |
114 | def close_comment(has_conditional, tabulation) |
115 | close_tag = has_conditional ? "<![endif]-->" : "-->" |
116 | if @one_liner_pending |
117 | @buffer << " #{close_tag}\n" |
118 | @one_liner_pending = false |
119 | else |
120 | push_text(close_tag, tabulation) |
121 | end |
122 | end |
123 | |
124 | # Stops parsing a flat section. |
125 | def stop_flat |
126 | buffer.concat("\n") |
127 | @one_liner_pending = false |
128 | end |
129 | |
130 | private |
131 | |
132 | # Gets <tt>count</tt> tabs. Mostly for internal use. |
133 | def tabs(count) |
134 | ' ' * (count + @tabulation) |
135 | end |
136 | |
137 | # Iterates through the classes and ids supplied through <tt>.</tt> |
138 | # and <tt>#</tt> syntax, and returns a hash with them as attributes, |
139 | # that can then be merged with another attributes hash. |
140 | def parse_class_and_id(list) |
141 | attributes = {} |
142 | list.scan(/([#.])([-_a-zA-Z0-9]+)/) do |type, property| |
143 | case type |
144 | when '.' |
145 | if attributes[:class] |
146 | attributes[:class] += " " |
147 | else |
148 | attributes[:class] = "" |
149 | end |
150 | attributes[:class] += property |
151 | when '#' |
152 | attributes[:id] = property |
153 | end |
154 | end |
155 | attributes |
156 | end |
157 | |
158 | # Takes an array of objects and uses the class and id of the first |
159 | # one to create an attributes hash. |
160 | def parse_object_ref(ref) |
161 | ref = ref[0] |
162 | # Let's make sure the value isn't nil. If it is, return the default Hash. |
163 | return {} if ref.nil? |
164 | class_name = ref.class.to_s.underscore |
165 | {:id => "#{class_name}_#{ref.id}", :class => class_name} |
166 | end |
167 | |
168 | # Takes a hash and builds a list of XHTML attributes from it, returning |
169 | # the result. |
170 | def build_attributes(attributes = {}) |
171 | result = attributes.collect do |a,v| |
172 | unless v.nil? |
173 | v = v.to_s |
174 | attr_wrapper = @options[:attr_wrapper] |
175 | if v.include? attr_wrapper |
176 | if v.include? @other_quote_char |
177 | v = v.gsub(attr_wrapper, @quote_escape) |
178 | else |
179 | attr_wrapper = @other_quote_char |
180 | end |
181 | end |
182 | " #{a}=#{attr_wrapper}#{v}#{attr_wrapper}" |
183 | end |
184 | end |
185 | result.sort.join |
186 | end |
187 | |
188 | # Returns whether or not the given value is short enough to be rendered |
189 | # on one line. |
190 | def one_liner?(value) |
191 | value.length <= ONE_LINER_LENGTH && value.scan(/\n/).empty? |
192 | end |
193 | |
194 | # Isolates the whitespace-sensitive tags in the string and uses Haml::Helpers#flatten |
195 | # to convert any endlines inside them into html entities. |
196 | def find_and_flatten(input) |
197 | input = input.to_s |
198 | input.scan(/<(textarea|code|pre)[^>]*>(.*?)<\/\1>/im) do |tag, contents| |
199 | input = input.gsub(contents, Haml::Helpers.flatten(contents)) |
200 | end |
201 | input |
202 | end |
203 | end |
204 | end |
205 | |
206 | class String # :nodoc |
207 | alias_method :old_comp, :<=> |
208 | def <=>(other) |
209 | if other.is_a? NilClass |
210 | -1 |
211 | else |
212 | old_comp(other) |
213 | end |
214 | end |
215 | end |
216 | |
217 | class NilClass # :nodoc: |
218 | include Comparable |
219 | |
220 | def <=>(other) |
221 | other.nil? ? 0 : 1 |
222 | end |
223 | end |
224 |