Replace escaped $.
[artemus.git] / artemus
blob9091448a95246962953847fd74730e230fe26edd
1 #!/usr/bin/perl
4 # artemus - HTML (and other things) Preprocessor
6 # Copyright (C) 2000/2003 Angel Ortega <angel@triptico.com>
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 # http://www.triptico.com
25 use locale;
26 use Getopt::Long;
28 use Artemus;
30 # substitution variables
31 %vars = ();
33 # substitution functions
34 %funcs = ();
36 # source and destination files
37 $src = "";
38 $dst = "";
40 # config file
41 $config_file = "artemus.conf";
43 # local configuration file
44 $local_config_file = "local-artemus.conf";
46 # paragraph separator
47 $para_sep = "";
49 # use cr/lf instead of lf
50 $use_cr_lf = 0;
52 # append instead of overwrite output file
53 $append = 0;
55 # send files using ftp
56 $use_ftp = 0;
58 # build site map
59 $site_map = 0;
61 # create makefile template
62 $makefile_template = 0;
64 # quiet flag
65 $quiet = 0;
67 # inverse substitutions
68 $inverse_config_file = "artemus-inv.conf";
69 %inv_vars = ();
71 # include path
72 $include_path = "";
74 # include debugging info
75 $debug = 0;
77 # unresolved templates
78 @unresolved = ();
80 #####################################################################
82 # special utility functions
83 $funcs{"filesize"} = sub { -s $_[0] };
84 $funcs{"shell"} = sub { $_=`$_[0]`; chop; return $_ };
86 # id
87 $VERSION = $Artemus::VERSION;
88 $artemus_id = "Artemus $VERSION";
90 usage() if (!GetOptions( "i|input=s" => \$src,
91 "o|output=s" => \$dst,
92 "c|conf=s" => \$config_file,
93 "p|paragraph=s" => \$para_sep,
94 "m|msdos" => \$use_cr_lf,
95 "a|append" => \$append,
96 "v|version-only" => \$version_only,
97 "f|ftp" => \$use_ftp,
98 "k|makefile" => \$makefile_template,
99 "s|site-map" => \$site_map,
100 "q|quiet" => \$quiet,
101 "l|include-path=s" => \$include_path,
102 "d|debug" => \$debug,
103 "h|help" => \$help) or $help);
105 $dst = ">-" if $dst eq "-";
107 version_only() if $version_only;
109 make_makefile() if $makefile_template;
111 build_site_map(@ARGV) if $site_map;
113 if (!$use_ftp) {
114 usage() unless $src;
115 usage() unless $dst;
118 # read the configuration files
119 read_config($config_file) if -f $config_file;
120 read_config($local_config_file) if -f $local_config_file;
121 read_config($inverse_config_file,1) if -f $inverse_config_file;
123 ftp_send() if $use_ftp;
125 open F, $src or die "can't open '$src'";
127 # get all the file
128 #undef $/;
129 $data = join("",<F>);
130 close F;
132 # create the Artemus handle
133 $ah = new Artemus("paragraph-separator" => $para_sep,
134 "vars" => \%vars,
135 "inv-vars" => \%inv_vars,
136 "funcs" => \%funcs,
137 "include-path" => $include_path,
138 "use-cr-lf" => $use_cr_lf,
139 "unresolved" => \@unresolved
142 # do it
143 $data = $ah->process($data);
145 # save file
147 open F, ($append ? ">" : "").">$dst" or die "can't write '$dst'";
148 print F $data;
149 close F;
151 foreach my $t (@unresolved) {
152 print STDERR "Artemus: unresolved '$t'\n";
155 exit(0);
157 ######################################################################
159 sub read_config
161 my ($conf,$inverse) = @_;
162 local (*F);
164 # read config file
165 unless (open F, $conf) {
166 if($quiet) {
167 return;
169 else {
170 die "'$conf' bad config file";
174 while (<F>) {
175 my ($key, $val);
177 chomp($_);
179 unless (/^#/ or /^$/) {
180 ($key, $val) = split("=",$_,2);
182 if ($val =~ s/^\|//) {
183 $val = `$val`;
184 chop($val);
186 elsif ($val eq "<<EOF") {
187 # 'document here' construction
188 $val = '';
190 while (<F>) {
191 last if /^EOF/;
193 $val .= $_;
196 elsif ($key eq "\\INCLUDE") {
197 read_config($val);
198 next;
201 $vars{$key} = $val;
202 $inv_vars{$key} = $val if($inverse);
206 close F;
210 sub usage
212 print("$artemus_id - HTML (and other things) Preprocessor\n");
213 print("Copyright (C) 2000/2003 Angel Ortega <angel\@triptico.com>\n\n");
215 print("Usage:\n");
216 print(" artemus -i|--input={input file} -o|--output={output file}\n");
217 print(" [-c|--conf={config file}]\n");
218 print(" [-l|--include-path={path to includes}]\n");
219 print(" [-p|--paragraph={paragraph_separator}]\n");
220 print(" [-q|--quiet]\n");
221 print(" [-m|--msdos] [-a|--append] [-d|--debug]\n\n");
222 print(" or\n\n");
223 print(" artemus -f|--ftp {files to ftp...}\n\n");
224 print(" or\n\n");
225 print(" artemus -k|--makefile\n");
226 print(" or\n\n");
227 print(" artemus -s|--site-map\n");
229 exit(1);
233 sub version_only
235 print("$VERSION\n");
236 exit(0);
240 sub ftp_send
241 # send files using ftp
243 my ($ftp);
245 require Net::FTP;
247 if (scalar(@ARGV) == 0) {
248 print "Nothing to send.\n";
249 exit(0);
252 print "Connecting to $vars{'ftp.host'}...\n";
253 $ftp = Net::FTP->new($vars{'ftp.host'});
254 print "OK\n";
256 print "Logging in as $vars{'ftp.user'}...\n";
257 $ftp->login($vars{'ftp.user'},$vars{'ftp.passwd'})
258 or die "ftp login error";
259 print "OK\n";
261 if (defined($vars{'ftp.dir'})) {
262 print "Chdir $vars{'ftp.dir'}...\n";
263 $ftp->cwd($vars{'ftp.dir'});
264 print "OK\n";
267 $ftp->binary();
269 foreach my $f (@ARGV) {
270 print "Sending $f...\n";
271 $ftp->put($f,$f);
272 print "OK\n";
275 print "Done.\n";
276 $ftp->quit;
278 exit(0);
282 sub make_makefile
283 # makes a makefile template
285 print <<"EOF";
287 # Makefile template created by $artemus_id
288 # for HTML projects (GNU Make)
290 # artemus (C) 2000/2003 Angel Ortega <angel\@triptico.com>
292 # Use:
293 # make -- to build everything
294 # make file.html -- to build just file.html from file.artemus
295 # make clean -- to delete every rebuildable thing
296 # make ftp -- to upload using ftp
299 # Fill DEST with a list of the .html files created by artemus
300 # Use relative paths (e.g. misc/contact.html) if there are
301 # subdirectories. This paths will be the same when uploading;
302 # subdirs on ftp server must exist
304 DEST= index.html [MODIFY HERE]
306 # Add \$(DEST) to INET plus any other file/directory than will
307 # be uploaded but not built by this makefile.
308 # e.g.: download/* or images/*
310 INET=\$(DEST) images/* [MODIFY HERE]
312 # directories for the site map
313 DIRS= [MODIFY HERE]
315 # default target
316 .PHONY: all
317 all: \$(DEST)
319 # default rule. Artemus sources use the .artemus extension.
320 # Change if you use another
321 %.html: %.artemus
322 artemus -i \$< -o \$@
324 # site map. File sitemap/index.artemus must be included
325 # in DEST in order to be correctly remade.
326 map:
327 artemus --site-map \$(DIRS) > sitemap/index.artemus
328 \$(MAKE)
330 # The usual clean
331 .PHONY: clean
332 clean:
333 -rm \$(DEST) unresolved
335 # Last upload timestamp
336 .PHONY: ftp
337 ftp: ftpstamp
339 # if any file is newer than the last upload,
340 # send it and recreate timestamp
341 ftpstamp: \$(INET)
342 artemus --ftp \$?
343 touch ftpstamp
347 exit(0);
351 sub build_site_map
352 # builds a site map from current directory to stdout
354 my (@dirs) = @_;
356 # special artemus token site-map-head
357 print "{-site-map-head}\n\n";
358 print "<ul>\n";
360 foreach my $dir (@dirs) {
361 my ($cnt, @l);
363 open F, "find $dir -name \"*.html\" -follow|" or next;
365 while (<F>) {
366 chop;
367 s/^\.\///;
368 push(@l,$_) unless /index.html$/;
371 close F;
373 @l = sort(@l);
375 # the (supposed) index.html is put the first
376 unshift(@l,"$dir/index.html");
378 # travel the list
379 $cnt = 0;
380 foreach my $i (@l) {
381 my ($size, $file, $title);
383 $size = -s $i;
385 # slurps all
386 open F, $i or next;
387 $file = join("",<F>);
388 close F;
390 if ($file =~ /<title>([^<]*)/i) {
391 $title = $1;
393 else {
394 $title = $i;
397 print "<li><a href='../$i'>$title</a> [$i] $size bytes\n";
398 print "<ul>\n" unless $cnt;
400 $cnt++;
402 print "</ul>\n";
405 print "</ul>\n";
407 # special artemus token site-map-foot
408 print "{-site-map-foot}\n";
410 exit(0);