Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 15
- Log:
Attempt to update Typo to a Typo SVN HEAD release from around the
time the prototype installation was set up on the RISC OS Open Limited
web site. Timestamps place this at 04-Jul so a revision from 05-Jul or
earlier was pulled and copied over the 2.6.0 tarball stable code.
- Author:
- adh
- Date:
- Sat Jul 22 23:27:35 +0100 2006
- Size:
- 9185 Bytes
1 | # -------------------------------------------------------------------------- |
2 | # Portions of this code were taken from the "poignant.rb" script created |
3 | # by whytheluckystiff, which generates "Why's (Poignant) Guide to Ruby". |
4 | # The original script may be obtained from the poignant CVS repository, |
5 | # at http://poignant.rubyforge.org. |
6 | # |
7 | # This script is distributed under the by-sa/1.0 Creative Commons license. |
8 | # -------------------------------------------------------------------------- |
9 | |
10 | require 'erb' |
11 | require 'fileutils' |
12 | require 'yaml' |
13 | require 'redcloth' |
14 | require 'syntax/convertors/html' |
15 | |
16 | module Syntax |
17 | module Manual |
18 | |
19 | class Manual |
20 | attr_accessor :product, :meta, :chapters, :tutorials, :examples, :recent_updates |
21 | |
22 | def Manual.load( file_name ) |
23 | File.open( file_name ) { |file| YAML.load( file ) } |
24 | end |
25 | end |
26 | |
27 | class Meta |
28 | attr_accessor :copyright, :author, :email |
29 | end |
30 | |
31 | class Product |
32 | attr_accessor :name, :tagline, :version, :logo, :urls, :project |
33 | end |
34 | |
35 | class Sidebar |
36 | attr_accessor :title, :content |
37 | end |
38 | |
39 | class Chapter |
40 | attr_accessor :index, :title, :sections |
41 | |
42 | def initialize( index, title, sections ) |
43 | @index = index |
44 | @title = title |
45 | |
46 | section_index = 0 |
47 | @sections = ( sections || [] ).collect do |section| |
48 | section_index += 1 |
49 | if section.respond_to? :keys |
50 | Section.new( section_index, section.keys.first, section.values.first ) |
51 | else |
52 | section_index -= 1 |
53 | Section.new( section_index, nil, section ) |
54 | end |
55 | end |
56 | end |
57 | |
58 | def page_title |
59 | "Chapter #{index}: #{title}" |
60 | end |
61 | end |
62 | |
63 | class Tutorial |
64 | attr_accessor :index, :title, :brief, :intro, :steps, :summary |
65 | |
66 | def initialize( index, title, brief, intro, steps, summary ) |
67 | @index = index |
68 | @title = title |
69 | @brief = RedCloth.new( brief ) |
70 | @intro = RedCloth.new( intro ) if intro |
71 | @summary = RedCloth.new( summary ) if summary |
72 | @steps = steps.map { |step| RedCloth.new( step ) } |
73 | end |
74 | |
75 | def page_title |
76 | "Tutorial #{index}: #{title}" |
77 | end |
78 | end |
79 | |
80 | class Example |
81 | attr_accessor :index, :title, :brief, :intro, :design, :implementation, :summary |
82 | |
83 | def initialize( index, title, brief, intro, design, implementation, summary ) |
84 | @index = index |
85 | @title = title |
86 | @brief = RedCloth.new( brief ) |
87 | @intro = RedCloth.new( intro ) |
88 | @design = RedCloth.new( design ) |
89 | @implementation = RedCloth.new( implementation ) |
90 | @summary = RedCloth.new( summary ) |
91 | end |
92 | |
93 | def page_title |
94 | "Example #{index}: #{title}" |
95 | end |
96 | end |
97 | |
98 | class Section |
99 | attr_accessor :index, :title, :content |
100 | |
101 | def initialize( index, title, content ) |
102 | @index = index |
103 | @title = RedCloth.new( title ).to_html.gsub( %r{</?p>}, "" ) if title |
104 | @content = FigureContainer.new( content || "" ) |
105 | end |
106 | end |
107 | |
108 | class FigureContainer |
109 | def initialize( content ) |
110 | @content = content |
111 | @html = nil |
112 | end |
113 | |
114 | def to_html |
115 | return @html if @html |
116 | extract_figures |
117 | convert_to_html |
118 | replace_figures |
119 | @html |
120 | end |
121 | |
122 | private |
123 | |
124 | Figure = Struct.new( :opts, :body ) |
125 | |
126 | def extract_figures |
127 | @figures = [] |
128 | @content.gsub!( /^\{\{\{(.*?)?\n(.*?)\n\}\}\}$/m ) do |
129 | body = $2.strip |
130 | opts = Hash[*$1.strip.split(/,/).map{|p| p.split(/=/)}.flatten] |
131 | @figures << Figure.new( opts, body ) |
132 | "====#{@figures.length-1}====" |
133 | end |
134 | end |
135 | |
136 | def convert_to_html |
137 | @html = ( @content.length < 1 ? "" : |
138 | RedCloth.new( @content ).to_html ) |
139 | end |
140 | |
141 | def replace_figures |
142 | @html.gsub!( /<p>====(.*?)====<\/p>/ ) do |
143 | figure = @figures[$1.to_i] |
144 | lang = figure.opts["lang"] |
145 | caption = figure.opts["caption"] || "Figure" |
146 | caption << " [#{lang}]" if lang |
147 | |
148 | body = figure.body |
149 | |
150 | if lang |
151 | convertor = Syntax::Convertors::HTML.for_syntax( lang ) |
152 | |
153 | body = "<link rel='stylesheet' type='text/css' " + |
154 | "href='stylesheets/#{lang}.css' />" + |
155 | "<div class='#{lang}'>" + |
156 | convertor.convert( body ) + |
157 | "</div>" |
158 | end |
159 | |
160 | if figure.opts["number"] && eval(figure.opts["number"]) |
161 | line = 1 |
162 | numbers = "" |
163 | body.each_line { numbers << "#{line}<br />"; line += 1 } |
164 | body = "<table border='0' cellpadding='0' cellspacing='0'>" + |
165 | "<tr><td class='lineno'>#{numbers}</td>" + |
166 | "<td width='100%'>#{body}</td></tr></table>" |
167 | end |
168 | |
169 | "<div class='figure'>\n" + |
170 | "<span class='caption'>#{caption}</span>\n" + |
171 | "<div class='body'>#{body}</div>" + |
172 | "</div>" |
173 | end |
174 | end |
175 | end |
176 | |
177 | YAML.add_private_type( 'file' ) { |type_id, value| File.read( value ) rescue "" } |
178 | YAML.add_private_type( 'eval' ) { |type_id, value| eval( value ) } |
179 | |
180 | YAML.add_domain_type( 'jamisbuck.org,2004', 'manual' ) do |taguri, val| |
181 | index = 0 |
182 | |
183 | val['chapters'].collect! do |chapter| |
184 | index += 1 |
185 | Chapter.new( index, chapter.keys.first, chapter.values.first ) |
186 | end |
187 | |
188 | index = 0 |
189 | ( val['tutorials'] ||= [] ).collect! do |tutorial| |
190 | index += 1 |
191 | content = tutorial.values.first |
192 | Tutorial.new( index, tutorial.keys.first, content['brief'], content['intro'], |
193 | content['steps'], content['summary'] ) |
194 | end |
195 | |
196 | index = 0 |
197 | ( val['examples'] ||= [] ).collect! do |example| |
198 | index += 1 |
199 | content = example.values.first |
200 | Example.new( index, example.keys.first, content['brief'], content['intro'], content['design'], |
201 | content['implementation'], content['summary'] ) |
202 | end |
203 | |
204 | YAML.object_maker( Manual, val ) |
205 | end |
206 | |
207 | YAML.add_domain_type( 'jamisbuck.org,2004', 'meta' ) do |taguri, val| |
208 | YAML.object_maker( Meta, val ) |
209 | end |
210 | |
211 | YAML.add_domain_type( 'jamisbuck.org,2004', 'product' ) do |taguri, val| |
212 | version = val["version"] |
213 | if version.respond_to?( :type_id ) |
214 | if version.type_id == "version" |
215 | if version.value =~ %r{(.*)/(.*)} |
216 | require_file, constant = $1, $2 |
217 | else |
218 | constant = version.value |
219 | end |
220 | |
221 | require require_file if require_file |
222 | val["version"] = eval(constant) |
223 | else |
224 | raise "Unexpected type: #{val.type_id}" |
225 | end |
226 | end |
227 | YAML.object_maker( Product, val ) |
228 | end |
229 | |
230 | YAML.add_domain_type( 'jamisbuck.org,2004', 'sidebar' ) do |taguri, val| |
231 | YAML.object_maker( Sidebar, |
232 | 'title' => val.keys.first, |
233 | 'content'=> RedCloth.new( val.values.first ) ) |
234 | end |
235 | |
236 | end |
237 | end |
238 | |
239 | if __FILE__ == $0 |
240 | |
241 | def log_action( action ) |
242 | $stderr.puts action |
243 | end |
244 | |
245 | unless ( output_path = ARGV[0] ) |
246 | $stderr.puts "Usage: #{$0} [/path/to/save/html]" |
247 | exit |
248 | end |
249 | |
250 | FileUtils.mkdir_p File.join( output_path, "stylesheets" ) |
251 | |
252 | log_action "Loading manual.yml..." |
253 | manual = Syntax::Manual::Manual.load( 'manual.yml' ) |
254 | |
255 | # force these to be defined at the TOPLEVEL_BINDING |
256 | object = nil |
257 | guts = nil |
258 | |
259 | page = File.open( "page.erb" ) { |file| ERB.new( file.read ) } |
260 | page.filename = "page.erb" |
261 | |
262 | template = File.open( "index.erb" ) { |file| ERB.new( file.read ) } |
263 | template.filename = "index.erb" |
264 | |
265 | File.open( File.join( output_path, "index.html" ), "w" ) do |file| |
266 | guts = template.result |
267 | file << page.result |
268 | end |
269 | |
270 | template = File.open( "chapter.erb" ) { |file| ERB.new( file.read ) } |
271 | template.filename = "chapter.erb" |
272 | |
273 | manual.chapters.each_with_index do |object,index| |
274 | log_action "Processing chapter ##{object.index}..." |
275 | |
276 | previous_chapter = ( index < 1 ? nil : manual.chapters[index-1] ) |
277 | next_chapter = manual.chapters[index+1] |
278 | |
279 | File.open( File.join( output_path, "chapter-#{object.index}.html" ), "w" ) do |file| |
280 | guts = template.result( binding ) |
281 | file << page.result( binding ) |
282 | end |
283 | end |
284 | |
285 | template = File.open( "tutorial.erb" ) { |file| ERB.new( file.read ) } |
286 | template.filename = "tutorial.erb" |
287 | |
288 | manual.tutorials.each do |object| |
289 | log_action "Processing tutorial ##{object.index}..." |
290 | File.open( File.join( output_path, "tutorial-#{object.index}.html" ), "w" ) do |file| |
291 | guts = template.result |
292 | file << page.result |
293 | end |
294 | end |
295 | |
296 | # template = File.open( "example.erb" ) { |file| ERB.new( file.read ) } |
297 | # template.filename = "example.erb" |
298 | |
299 | # manual.examples.each do |object| |
300 | # log_action "Processing example ##{object.index}..." |
301 | # File.open( File.join( output_path, "example-#{object.index}.html" ), "w" ) do |file| |
302 | # guts = template.result |
303 | # file << page.result |
304 | # end |
305 | # end |
306 | |
307 | log_action "Copying style sheets..." |
308 | FileUtils.cp Dir["stylesheets/*.css"], File.join( output_path, "stylesheets" ) |
309 | |
310 | log_action "Done!" |
311 | end |