initial commit
[urisagit/CMS-Simple.git] / make_slides / make_slides.pl
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/&/&amp;/g ;
179         $_[0] =~ s/</&lt;/g ;
180         $_[0] =~ s/>/&gt;/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 }