Commit | Line | Data |
9e609156 |
1 | #!/usr/local/bin/perl -w |
2 | |
3 | use strict ; |
4 | |
5 | use Carp ; |
6 | use YAML ; |
7 | |
8 | my @slides ; |
9 | |
10 | my %book_values ; |
11 | my ( $chap_title, $chap_abbrev ) ; |
12 | |
13 | my $page_num = 0 ; # number as read in |
14 | my $slide_num = 0 ; # slide within a chapter |
15 | my $chap_num = 0 ; |
16 | |
17 | my %part2sub = ( |
18 | |
19 | 'book' => \&process_book, |
20 | 'title' => \&process_title, |
21 | 'chapter' => \&process_chapter, |
22 | 'code' => \&process_code, |
23 | 'code2' => \&process_code2, |
24 | '*' => \&process_bullet, |
25 | '**' => \&process_bullet2, |
26 | 'haiku' => \&process_haiku, |
27 | 'html' => \&process_html, |
28 | ) ; |
29 | |
30 | |
31 | read_parse_pages() ; |
32 | |
33 | make_index() ; |
34 | |
35 | make_slides() ; |
36 | |
37 | #print Dump \@slides ; |
38 | |
39 | exit ; |
40 | |
41 | sub read_parse_pages { |
42 | |
43 | local( $/ ) = "PAGE_END\n" ; |
44 | |
45 | while ( my $page = <> ) { |
46 | |
47 | chomp( $page ) ; |
48 | |
49 | next unless $page =~ /\S/ ; |
50 | |
51 | push @slides, parse_page( $page ) ; |
52 | } |
53 | |
54 | $book_values{'TOTAL_PAGES'} = $page_num ; |
55 | } |
56 | |
57 | sub parse_page { |
58 | |
59 | my ( $page_text ) = @_ ; |
60 | |
61 | my $slide = { |
62 | 'PAGE_NUM' => ++$page_num, |
63 | 'SLIDE_NUM' => ++$slide_num, |
64 | 'CHAP_NUM' => $chap_num, |
65 | } ; |
66 | |
67 | foreach my $part ( split( /(?=^(?:\w+|\*+|):)/m, $page_text ) ) { |
68 | |
69 | next unless $part =~ /\S/ ; |
70 | |
71 | my ( $part_type, $part_body ) = split /:/, $part, 2 ; |
72 | |
73 | my $part_sub = $part2sub{ lc $part_type } or die |
74 | "unknown slide part '$part_type'\n$page_text" ; |
75 | |
76 | $part_sub->( $slide, $part_body ) ; |
77 | } |
78 | |
79 | return $slide ; |
80 | } |
81 | |
82 | |
83 | sub process_book { |
84 | |
85 | my( $slide, $book_text ) = @_ ; |
86 | |
87 | $book_values{'BOOK_NAME'} = $book_text ; |
88 | } |
89 | |
90 | sub process_chapter { |
91 | |
92 | my( $slide, $chapter_text ) = @_ ; |
93 | |
94 | ( $chap_title, $chap_abbrev ) = split( /\n/, $chapter_text ) ; |
95 | |
96 | $chap_title =~ tr/\n / /s ; |
97 | $slide->{'CHAPTER'} = $chap_title ; |
98 | |
99 | if ( $chap_abbrev ) { |
100 | $chap_abbrev =~ tr/\n / /s ; |
101 | $slide->{'CHAP_ABBREV'} = $chap_abbrev ; |
102 | } |
103 | |
104 | $chap_num++ ; |
105 | $slide_num = 1 ; |
106 | $slide->{'SLIDE_NUM'} = $slide_num ; |
107 | $slide->{'CHAP_NUM'} = $chap_num ; |
108 | } |
109 | |
110 | sub process_title { |
111 | |
112 | my( $slide, $title_text ) = @_ ; |
113 | |
114 | $title_text =~ tr/\n / /s ; |
115 | |
116 | $slide->{'TITLE'} = $title_text ; |
117 | |
118 | $slide->{'CHAPTER'} = $chap_title ; |
119 | $slide->{'CHAP_ABBREV'} = $chap_abbrev ; |
120 | } |
121 | |
122 | sub process_bullet { |
123 | |
124 | my( $slide, $bullet_text ) = @_ ; |
125 | |
126 | my ( $bullet, @paras ) = split /\n{2,}/, $bullet_text ; |
127 | # escape_entities( $_ ) for $bullet, @paras; |
128 | escape_entities( $_ ) for @paras; |
129 | |
130 | push( @{$slide->{'html_parts'}}, |
131 | apply_template( 'bullet', { 'TEXT' => $bullet } ), |
132 | map apply_template( 'para', { 'TEXT' => $_ } ), @paras ) ; |
133 | } |
134 | |
135 | sub process_bullet2 { |
136 | |
137 | my( $slide, $bullet_text ) = @_ ; |
138 | |
139 | my ( $bullet, @paras ) = split /\n{2,}/, $bullet_text ; |
140 | # escape_entities( $_ ) for $bullet, @paras; |
141 | escape_entities( $_ ) for @paras; |
142 | |
143 | push( @{$slide->{'html_parts'}}, "<UL>\n", |
144 | apply_template( 'bullet2', { 'TEXT' => $bullet } ), |
145 | map( apply_template( 'para', { 'TEXT' => $_ } ), @paras ), |
146 | "</UL>\n", |
147 | ) ; |
148 | } |
149 | |
150 | sub process_code { |
151 | |
152 | my( $slide, $code_text ) = @_ ; |
153 | |
154 | $code_text =~ s/^\n// ; |
155 | escape_entities( $code_text ) ; |
156 | |
157 | $code_text =~ s/<blue>/<font color="#0000ff">/gi ; |
158 | |
159 | push( @{$slide->{'html_parts'}}, |
160 | apply_template( 'code', { 'TEXT' => $code_text } ) ) ; |
161 | } |
162 | |
163 | # sub process_code2 { |
164 | |
165 | # my( $slide, $code_text ) = @_ ; |
166 | |
167 | # $code_text =~ s/^\n// ; |
168 | # escape_entities( $code_text ) ; |
169 | |
170 | # push( @{$slide->{'html_parts'}}, |
171 | # apply_template( 'code2', { 'TEXT' => $code_text } ) ) ; |
172 | # } |
173 | |
174 | sub escape_entities { |
175 | |
176 | print caller() if $_[0] =~ /IMG/ ; |
177 | |
178 | $_[0] =~ s/&/&/g ; |
179 | $_[0] =~ s/</</g ; |
180 | $_[0] =~ s/>/>/g ; |
181 | } |
182 | |
183 | sub process_haiku { |
184 | |
185 | my( $slide, $haiku_text ) = @_ ; |
186 | |
187 | $haiku_text =~ tr/\n / /s ; |
188 | |
189 | my @lines = split m{:}, $haiku_text ; |
190 | |
191 | push( @{$slide->{'html_parts'}}, |
192 | apply_template( |
193 | 'haiku', |
194 | { LINE1 => $lines[0], |
195 | LINE2 => $lines[1], |
196 | LINE3 => $lines[2] } |
197 | ) |
198 | ) ; |
199 | } |
200 | |
201 | sub process_html { |
202 | |
203 | my( $slide, $html_text ) = @_ ; |
204 | |
205 | push( @{$slide->{'html_parts'}}, $html_text ) ; |
206 | } |
207 | |
208 | sub make_slides { |
209 | |
210 | foreach my $slide ( @slides ) { |
211 | |
212 | my $page_num = $slide->{'PAGE_NUM'} ; |
213 | |
214 | if ( $page_num > 1 ) { |
215 | |
216 | my $prev_slide = $slides[$page_num - 2] ; |
217 | $slide->{'PREV_FILE'} = $prev_slide->{'slide_file'} ; |
218 | $slide->{'PREV_TITLE'} = $prev_slide->{'TITLE'} ; |
219 | } |
220 | |
221 | if ( $page_num < $book_values{'TOTAL_PAGES'} ) { |
222 | |
223 | my $next_slide = $slides[$page_num] ; |
224 | $slide->{'NEXT_FILE'} = $next_slide->{'slide_file'} ; |
225 | $slide->{'NEXT_TITLE'} = $next_slide->{'TITLE'} ; |
226 | } |
227 | |
228 | |
229 | my $header = apply_template( 'header', $slide ) ; |
230 | my $footer = apply_template( 'footer', $slide ) ; |
231 | |
232 | my $slide_file = "slides/$slide->{'slide_file'}" ; |
233 | |
234 | write_file( $slide_file, |
235 | $header, |
236 | "<UL>\n", |
237 | @{$slide->{'html_parts'}}, |
238 | "</UL>\n", |
239 | $footer, |
240 | ) ; |
241 | } |
242 | } |
243 | |
244 | sub make_index { |
245 | |
246 | my $name = $book_values{'BOOK_NAME'} || 'Empty' ; |
247 | |
248 | my $index_html = <<HTML ; |
249 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
250 | <HTML> |
251 | <HEAD> |
252 | <TITLE>Index of $name</TITLE> |
253 | </HEAD> |
254 | <H2>Index of $name</H2> |
255 | <P> |
256 | <UL STYLE="list-style-type:none"> |
257 | HTML |
258 | |
259 | my $toc_html = <<HTML ; |
260 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
261 | <HTML> |
262 | <HEAD> |
263 | <TITLE>Table of Contents for $name</TITLE> |
264 | </HEAD> |
265 | <H2>Table of Contents for $name</H2> |
266 | <P> |
267 | <UL STYLE="list-style-type:none"> |
268 | HTML |
269 | |
270 | foreach my $slide ( @slides ) { |
271 | |
272 | my $chap_num = $slide->{'CHAP_NUM'} ; |
273 | my $slide_num = $slide->{'SLIDE_NUM'} ; |
274 | |
275 | my $slide_file = sprintf( "slide-%02d%02d.html", |
276 | $chap_num, |
277 | $slide_num ) ; |
278 | |
279 | $slide->{'slide_file'} = $slide_file ; |
280 | |
281 | if ( $slide_num == 1 ) { |
282 | |
283 | my $chapter = $slide->{'CHAPTER'} || '' ; |
284 | |
285 | $index_html .= "</UL>\n" if $chap_num > 1 ; |
286 | |
287 | $index_html .= <<HTML ; |
288 | <LI>$chap_num. <A href="$slide_file">$chapter</A> |
289 | <UL STYLE="list-style-type:none"> |
290 | HTML |
291 | |
292 | |
293 | $toc_html .= <<HTML ; |
294 | <LI>$chap_num. <A href="$slide_file">$chapter</A> |
295 | HTML |
296 | |
297 | } |
298 | |
299 | $index_html .= <<HTML ; |
300 | <LI>$chap_num.$slide_num <A href="$slide_file">$slide->{'TITLE'}</A> |
301 | HTML |
302 | |
303 | } |
304 | |
305 | $index_html .= <<HTML ; |
306 | </UL> |
307 | </HTML> |
308 | HTML |
309 | |
310 | $toc_html .= <<HTML ; |
311 | </UL> |
312 | </HTML> |
313 | HTML |
314 | |
315 | |
316 | write_file( 'slides/index.html', $index_html ) ; |
317 | $book_values{'INDEX'} = 'index.html' ; |
318 | |
319 | write_file( 'slides/toc.html', $toc_html ) ; |
320 | $book_values{'TOC'} = 'toc.html' ; |
321 | } |
322 | |
323 | my %templates ; |
324 | |
325 | sub apply_template { |
326 | |
327 | my( $tmpl_name, $add_values ) = @_ ; |
328 | |
329 | my $template = $templates{ $tmpl_name } ; |
330 | |
331 | unless( $template ) { |
332 | |
333 | $template = read_file( "templates/$tmpl_name.tmpl" ) ; |
334 | |
335 | $templates{ $tmpl_name } = $template ; |
336 | } |
337 | |
338 | my %tmpl_values = ( %book_values, %{$add_values} ) ; |
339 | |
340 | $template =~ s/<%(\w+?)%>/$tmpl_values{$1} || ''/ge ; |
341 | |
342 | $template =~ s[<A HREF="">(.+?)</A>][$1]i ; |
343 | |
344 | return $template ; |
345 | } |
346 | |
347 | sub read_file { |
348 | |
349 | my( $file_name ) = shift ; |
350 | |
351 | my( $buf ) ; |
352 | |
353 | local( *FH ) ; |
354 | |
355 | open( FH, $file_name ) || croak "can't open $file_name $!" ; |
356 | |
357 | return <FH> if wantarray ; |
358 | |
359 | read( FH, $buf, -s FH ) ; |
360 | return $buf ; |
361 | } |
362 | |
363 | sub write_file { |
364 | |
365 | my( $file_name ) = shift ; |
366 | |
367 | local( *FH ) ; |
368 | |
369 | open( FH, ">$file_name" ) || croak "can't create $file_name $!" ; |
370 | |
371 | print FH @_ ; |
372 | } |