#!/usr/bin/perl -w $| = 1; use strict; ######################################################################### # Script: mytexi - Derivative of texinfo software documentation system. # Reformed texinfo syntax for easy of use. It is primarily # designed for creating online manuals. #------------------------------------------------------------------------ # Author : Reto Schaer-Hersiczky # Date : 24AUG2004 # Docu : http://www.infocopter.com/know-how/mytexi/ # Source : http://www.infocopter.com/know-how/mytexi/mytexi_source_pl.txt # New: http://primus.pgate.net/_pubsource/mytexi_pl.txt # Location: www2 #------------------------------------------------------------------------ # Usage: mytexi [params] # # params: --extract="index[,foo]" # my $VERSION = '0.98.02'; ######################################################################### my $INFILE = $ARGV[0]; my $PARA = $ARGV[1] || ''; my $MAX_DEEPNESS = 4; # 0 = top level, 4 = Five-level chapter - # e.g. 1.1.1.1.1, usually, this is enough ;-) my $DEBUG = 0; # 0,1,2 -- ZZ my %META = (); my %INDEX = (); my %INDEX_MEMO = (); # Prevent doubled words my %CURRENT_CHAPTER = (); my $i = 0; for (0 .. $MAX_DEEPNESS) { $CURRENT_CHAPTER{$i++} = 0 } my %BEFORE_CHAPTER = (); my $j = 0; for (0 .. $MAX_DEEPNESS) { $BEFORE_CHAPTER{$j++} = 0 } my %TOC_HASH = (); $TOC_HASH{"::error\tcount"} = 0; my @CHAPTERS = (); my $PAGE_COUNTER = 0; my %EXTRACT = (); if ($PARA =~ /^--extract[^_]={0,1}['"]?(.*)['"]?$/) { my @ext = split /,/, $1; foreach (@ext) { $EXTRACT{$_} = 1; } } else { if ($PARA) { print STDERR "ERR: Unknown para: \"$PARA\"\n"; sleep 1; } } # foreach (keys %EXTRACT) { print "X '$_' = \"$EXTRACT{$_}\"\n"; } &main(); if ($EXTRACT{'index'}) { close INDX; } print "\n=======> $PAGE_COUNTER pages have been genereated with ", $TOC_HASH{"::error\tcount"}, " errors\n"; ######################################################################### sub main() { ######################################################################### unless ($INFILE =~ /\.mtxi$/) { print STDERR "Warning: Probably no mytexi source!\n"; sleep 3; } open(IN, $INFILE) or die "ERR \"$INFILE\" $!\n"; while() { next if /^\@comment/; chomp; last unless $_; s/\:/__\:\:__/; # repl first occ my ($key, $val) = split /__\:\:__/; $key =~ tr/[ \t]//d; $val = join " ", grep { $_ } split /[ \t]/, $val; # trim $val =~ s/__\:\:__/\:/g; # repl back $META{$key} = $val; print "[META] \"$key\" : \"$val\"\n" if $DEBUG; } $META{'NAV_PREFIX'} ||= ''; unless (-d $META{PROJECT} ) { print "Creating directory $META{PROJECT} ...\n"; mkdir $META{PROJECT} or print STDERR "ERR $!\n"; } if ($EXTRACT{'index'}) { open(INDX, ">zz_aindex_$META{PROJECT}.txt") or print STDERR $!; print INDX '# title=', "$META{title}\n"; print INDX '# project=', "$META{PROJECT}\n"; } print "============================================\n\n" if $DEBUG; my $WITHIN_TITLEPAGE_FLAG = 0; while() { next if /^\@comment /; chomp; my $before = $BEFORE_CHAPTER{0}; $before .= "\.$BEFORE_CHAPTER{1}" if $BEFORE_CHAPTER{1}; $before .= "\.$BEFORE_CHAPTER{2}" if $BEFORE_CHAPTER{2}; $before .= "\.$BEFORE_CHAPTER{3}" if $BEFORE_CHAPTER{3}; $before .= "\.$BEFORE_CHAPTER{4}" if $BEFORE_CHAPTER{4}; my $ref = $_; my $caption = my $type = my $control = ''; my $deepness = 0; if (/(^\@[sub]*chapter) .+/) { print "==> !!! CHAPTER FOUND: \"$1\"\n" if $DEBUG > 1; $type = $1; $ref =~ s/^$type //; $caption = $control = $ref; # List all args left from "$ref" $ref =~ s/.*ref="(.+?)".*[^"]*?/$1/; $ref = "$META{NAV_PREFIX}$ref"; $caption =~ s/.*caption="(.+?)".*[^"]*?/$1/; # - Optional args: if (/control="/) { $control =~ s/.*control="(.+?)".*[^"]*?/$1/ } else { $control = ''; } my @deepness_arr = split /sub/, $type; $deepness = $#deepness_arr; } if ($type) { $CURRENT_CHAPTER{$deepness}++; for (my $i = $deepness + 1; $i < 10; $i++) { $CURRENT_CHAPTER{$i} = 0; } } if ($type) { $WITHIN_TITLEPAGE_FLAG = 0; print "=> Found Chapter, Deepness=$deepness\n" if $DEBUG > 1; &process_chapter( ref => $ref, before => $before, caption => $caption, control => $control ); next; } if (/^\@titlepage/ or $WITHIN_TITLEPAGE_FLAG) { # X 2004-08-26 NEW $WITHIN_TITLEPAGE_FLAG = 1; $TOC_HASH{"0\tCONTENT"} .= "$_\n"; next; } my $current = $CURRENT_CHAPTER{0}; $current .= "\.$CURRENT_CHAPTER{1}" if $CURRENT_CHAPTER{1}; $current .= "\.$CURRENT_CHAPTER{2}" if $CURRENT_CHAPTER{2}; $current .= "\.$CURRENT_CHAPTER{3}" if $CURRENT_CHAPTER{3}; $current .= "\.$CURRENT_CHAPTER{4}" if $CURRENT_CHAPTER{4}; print "==> [$current] $_\n" if $DEBUG > 1; $TOC_HASH{"$current\tCONTENT"} .= "$_\n"; } # /while $TOC_HASH{"0\tREF"} ||= ''; close IN; my $here_date = &date_time(); $META{'date'} =~ s/\@DATE{NOW,DD.MM.YYYY}/$here_date/; foreach (sort keys %TOC_HASH) { my ($key, $attr) = split /\t/; next unless $key; next if $attr eq 'CONTENT' or $attr eq 'AFTER' or $attr eq 'BEFORE'; print "==> $key \t($attr) = \"$TOC_HASH{$_}\"\n" if $DEBUG; } my @title_page = split /\n/, $TOC_HASH{"0\tCONTENT"}; my $TITLE_PAGE = my $HEADER = my $HEADER_PRINT = my $FOOTER = ''; my $TITLE_PAGE_FLAG = my $HEADER_FLAG = my $HEADER_PRINT_FLAG = my $FOOTER_FLAG = 0; foreach (@title_page) { print "----------------> \t$_\n" if $DEBUG > 1; if (/^\@titlepage/) { $TITLE_PAGE_FLAG = 1; $HEADER_FLAG = $HEADER_PRINT_FLAG = $FOOTER_FLAG = 0; next; } if ($_ eq '@header') { $HEADER_FLAG = 1; $TITLE_PAGE_FLAG = $FOOTER_FLAG = $HEADER_PRINT_FLAG = 0; next; } if (/^\@header_print/) { $HEADER_PRINT_FLAG = 1; $TITLE_PAGE_FLAG = $FOOTER_FLAG = $HEADER_FLAG = 0; next; } if (/^\@footer/) { $FOOTER_FLAG = 1; $TITLE_PAGE_FLAG = $HEADER_FLAG = $HEADER_PRINT_FLAG = 0; next; } foreach my $metakey (keys %META) { s/\$VAR{$metakey}/$META{$metakey}/; } $TITLE_PAGE .= "$_\n" if $TITLE_PAGE_FLAG; $HEADER .= "$_\n" if $HEADER_FLAG; $HEADER_PRINT .= "$_\n" if $HEADER_PRINT_FLAG; $FOOTER .= "$_\n" if $FOOTER_FLAG; } print 'title: ', $META{'title'}, "\n"; print 'author: ', $META{'author'}, "\n"; print 'date: ', $META{'date'}, "\n\n"; my $main_chap_current = 0; my $TOC_DATA = ''; foreach (@CHAPTERS) { my $first = $_; my $second = ' '; my $third = qq~~ . $TOC_HASH{"$_\tCAPTION"} . ''; if ($DEBUG > 0) { foreach my $ckey (keys %{$TOC_HASH{"$_\tCONTROL"}}) { print '(control of ', $TOC_HASH{"$_\tREF"}, "\t $ckey = \"", $TOC_HASH{"$_\tCONTROL"}->{$ckey}, "\"\n" if $TOC_HASH{"$_\tCONTROL"}->{$ckey}; } } if (/\.\d+\./) { # is subsub chapter $first = ' '; $second = $_; $TOC_DATA .= " " . "\n" unless $TOC_HASH{"$_\tCONTROL"}->{'not_on_main_toc'} == 1; $TOC_HASH{"$main_chap_current\tSUBTOC"} .= "\n"; } elsif (/\./) { # is sub chapter $first = ' '; # e.g. 1, 2, ... $second = $_; # e.g. 1.1, 1.2, ... $TOC_DATA .= " " . "" . "" . "\n" unless $TOC_HASH{"$_\tCONTROL"}->{'not_on_main_toc'} == 1; $TOC_HASH{"$main_chap_current\tSUBTOC"} .= " " . "\n"; } else { $main_chap_current = $_; # is main chapter $second = $third; $third = ' '; unless ($TOC_HASH{"$_\tCONTROL"}->{'not_on_main_toc'} == 1) { $TOC_DATA .= qq~~ if $main_chap_current > 1; $TOC_DATA .= "" . " " . "\n"; } } } $TOC_DATA .= '
$first $second    $third
 $second  $third
$first$second$third    
$second  $third
$first$second
'; if ($HEADER_PRINT) { print "=======> Includes printer-friendly pages ($META{PROJECT}/print/)\n"; mkdir "$META{PROJECT}/print" or print STDERR "$!\n" unless -e "$META{PROJECT}/print"; } open(FF, ">$META{PROJECT}/_complete$META{HTML_SUFFIX}") or print STDERR $!; print "============> TITLE PAGE - $META{PROJECT}/index$META{HTML_SUFFIX} <============\n"; $META{TITLE_INDEX} ||= 'index'; $TITLE_PAGE =~ s/\$MENU{}/$TOC_DATA/; # X NEW 2004-09-01 my @titlepage_lines = split /\n/, $TITLE_PAGE; for (my $i = 0; $i < $#titlepage_lines; $i++) { # Extract a filename or file path if ($titlepage_lines[$i] =~ /.*\@include ([a-z0-9\._\-\/:\\]+)[\t ]*/i) { print "\t--> (titlepage) include file: -- \"$1\" --\n" if $DEBUG; open(INCL, "<$1") or print STDERR "$1 $!\n"; local $/ = undef; my $include = ; close INCL; $titlepage_lines[$i] =~ s/\@include $1/$include/; } } # -- Re-assemble the title page $TITLE_PAGE = join "\n", @titlepage_lines; open(F, ">$META{PROJECT}/$META{NAV_PREFIX}$META{TITLE_INDEX}$META{HTML_SUFFIX}") or print STDERR $!; print F $TITLE_PAGE; close F; if ($HEADER_PRINT) { # X NEW 2004-09-01 my @complete_document_header = split /\n/, $HEADER_PRINT; foreach (@complete_document_header) { s/\$VAR{::.+}//g; print FF; } print FF $TOC_DATA; } else { my @complete_document_header = split /\n/, $TITLE_PAGE; foreach (@complete_document_header) { last if /\<\/body>/i; print FF; } } print FF "
\n"; print "$TITLE_PAGE\n\n" if $DEBUG > 1; foreach (@CHAPTERS) { my $f_has_includes = 0; print "=======> [$_] - $META{PROJECT}/", $TOC_HASH{"$_\tREF"}, "$META{HTML_SUFFIX}\n"; $TOC_HASH{"$_\tAFTER"} ||= ''; my $before_chap = $TOC_HASH{"$_\tBEFORE"}; my $after_chap = $TOC_HASH{"$_\tAFTER"}; $TOC_HASH{"$before_chap\tREF" } = '/' unless $before_chap; $TOC_HASH{"$before_chap\tCAPTION"} = '/' unless $before_chap; $TOC_HASH{"$after_chap\tREF" } = '::end' unless $after_chap; $TOC_HASH{"$after_chap\tCAPTION"} = '::end' unless $after_chap; my @nav_up_arr = split /\./; pop @nav_up_arr; my $nav_up_number = (join '.', @nav_up_arr) || 0; my $nav_up = qq~ up ~; $nav_up = qq~ up ~ if $nav_up_number eq '0'; my $nav_previous = "" . $before_chap . ' ' . $TOC_HASH{"$before_chap\tCAPTION"} . ""; my $nav_next = "" . $after_chap . ' ' . $TOC_HASH{"$after_chap\tCAPTION"} . ""; $nav_previous = 'top' unless $before_chap; $nav_next = 'end' unless $after_chap; my $nav_dmoz = ''; my $nav_up_capt = $TOC_HASH{"$nav_up_number\tCAPTION"}; if ($nav_up_capt eq '/') { $nav_dmoz = $TOC_HASH{"$_\tCAPTION"}; } else { $nav_dmoz = qq~ $nav_up_capt~ . " > " . $TOC_HASH{"$_\tCAPTION"}; } # -- Parse @header section my $page_title = $TOC_HASH{"$_\tCAPTION"}; (my $THIS_HEADER = $HEADER) =~ s/\$VAR{::chapter::caption}/$page_title/g; $THIS_HEADER =~ s/\$VAR{::nav_previous}/$nav_previous/; $THIS_HEADER =~ s/\$VAR{::nav_next}/$nav_next/; $THIS_HEADER =~ s/\$VAR{::nav_up}/$nav_up/; $THIS_HEADER =~ s/\$VAR{::chapter::number}/$_/g; $THIS_HEADER =~ s/\$VAR{::nav_dmoz}/$nav_dmoz/; (my $THIS_FOOTER = $FOOTER) =~ s/\$VAR{::chapter::caption}/$page_title/g; # X NEW 2004-09-01 my @header_lines = split /\n/, $THIS_HEADER; for (my $i = 0; $i < $#header_lines; $i++) { # Extract a filename or file path if ($header_lines[$i] =~ /.*\@include ([a-z0-9\._\-\/:\\]+)[\t ]*/i) { print "\t--> (header) include file: -- \"$1\" --\n" if $DEBUG; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; while(my $iline = ) { if ($iline =~ /.*\@url\{.+\}.*/) { $iline = &urlify($iline, $TOC_HASH{"$_\tREF"}); } $include .= $iline; } close INCL; $header_lines[$i] =~ s/\@include $1/$include/; } if ($header_lines[$i] =~ /.*\@include_core_body ([a-z0-9\._\-\/:\\]+)[\t ]*/i) { print "\t--> include file: -- \"$1\" --\n" if $DEBUG > 1; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; my $within_body = 0; while(my $iline = ) { if ($iline =~ /\ include file: -- \"$1\" --\n" if $DEBUG > 1; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; my $within_body = 0; while(my $iline = ) { if ($iline =~ /\ include file: -- \"$1\" --\n" if $DEBUG; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; while(my $iline = ) { if ($iline =~ /.*\@url\{.+\}.*/) { $iline = &urlify($iline, $TOC_HASH{"$_\tREF"}); } $include .= $iline; } close INCL; $content_lines[$i] =~ s/\@include $1/$include/; } if ($content_lines[$i] =~ /.*\@include_body ([a-z0-9\._\-\/:\\]+)[\t ]*/i) { $f_has_includes = 1; print "\t--> include file: -- \"$1\" --\n" if $DEBUG > 1; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; my $within_body = 0; while(my $iline = ) { if ($iline =~ /\ include file: -- \"$1\" --\n" if $DEBUG > 1; open(INCL, "<$1") or print STDERR "$1 $!\n"; my $include = ''; my $within_body = 0; while(my $iline = ) { if ($iline =~ /\ Index: \"$iword\"\n" if $DEBUG; my $ref = $TOC_HASH{"$_\tREF"}; my $letters = uc $iword; my $identifier = ' (' . (++$INDEX_MEMO{$letters}) . '.)'; $INDEX{"$letters$identifier$ref"} = "$ref$META{HTML_SUFFIX}\t$iword$identifier\t" . $TOC_HASH{"$_\tCAPTION"}; if ($EXTRACT{'index'}) { print INDX "$iword\t$ref$META{HTML_SUFFIX}\t", $TOC_HASH{"$_\tCAPTION"}, "\n"; } } if ($content_lines[$i] =~ /\@index/) { &sort_index(); $content_lines[$i] =~ s/\@index/$META{__INDEX}/; } if ($content_lines[$i] =~ /\@end .+/) { next; } elsif ($content_lines[$i] =~ /\@suppress_if_.+/) { next; } # X NEW 2004-11-03 if ($content_lines[$i] =~ /\@call cmd="(.+)"/) { my $cmd = $1; print "-> call \"$cmd\" ...\n"; my $result = `$cmd`; $content_lines[$i] =~ s/\@call cmd="$cmd"/$result/; } if ($f_has_includes) { foreach my $metakey (keys %META) { $content_lines[$i] =~ s/\$VAR{$metakey}/$META{$metakey}/g; } } print F $content_lines[$i], "\n"; } foreach my $metakey (keys %META) { $THIS_HEADER =~ s/\$VAR{$metakey}/$META{$metakey}/g; } $TOC_HASH{"$_\tCONTENT"} = join "\n", @content_lines; # XX Old: (my $THIS_FOOTER = $FOOTER) =~ s/\$VAR{::chapter::caption}/$page_title/g; $THIS_FOOTER =~ s/\$VAR{::nav_previous}/$nav_previous/; $THIS_FOOTER =~ s/\$VAR{::nav_next}/$nav_next/; $THIS_FOOTER =~ s/\$VAR{::nav_up}/$nav_up/; $THIS_FOOTER =~ s/\$VAR{::chapter::number}/$_/g; $THIS_FOOTER =~ s/\$VAR{::filename}/$TOC_HASH{"$_\tREF"}$META{HTML_SUFFIX}/g; # X NEW print F "$THIS_FOOTER\n"; # -- Close single page close F; # -- Create printer-friendly page if ($HEADER_PRINT) { my $page_title = $TOC_HASH{"$_\tCAPTION"}; (my $THIS_HEADER = $HEADER_PRINT) =~ s/\$VAR{::chapter::caption}/$page_title/g; # X my @content_lines = split /\n/, $TOC_HASH{"$_\tCONTENT"}; # X NEW 2004-09-08 my $pf_file = "$META{PROJECT}/print/" . $TOC_HASH{"$_\tREF"} . $META{HTML_SUFFIX}; open(F, ">$pf_file") or print STDERR "ERR $! $pf_file\n"; print F "$THIS_HEADER\n"; my $suppress = 0; foreach (@content_lines) { if (/\@suppress_if_printer_friendly/) { $suppress = 1; next; } if (/\@end suppress_if_printer_friendly/) { $suppress = 0; next; } print F "$_\n" unless $suppress; } print F "$FOOTER\n"; close F; } # -- /Create printer-friendly page print FF "

$_", ' ', $TOC_HASH{"$_\tCAPTION"}, "

\n"; my $suppress = 0; foreach (@content_lines) { if (/\@suppress_if_printer_friendly/) { $suppress = 1; next; } if (/\@end suppress_if_printer_friendly/) { $suppress = 0; next; } print FF "$_\n" unless $suppress; } print "$THIS_HEADER\n" if $DEBUG > 1; $PAGE_COUNTER++; } # /foreach @CHAPTERS print FF "
"; close FF; } ######################################################################### sub process_chapter (%) { my %args = @_; $BEFORE_CHAPTER{0} = $CURRENT_CHAPTER{0}; $BEFORE_CHAPTER{1} = $CURRENT_CHAPTER{1}; $BEFORE_CHAPTER{2} = $CURRENT_CHAPTER{2}; $BEFORE_CHAPTER{3} = $CURRENT_CHAPTER{3}; $BEFORE_CHAPTER{4} = $CURRENT_CHAPTER{4}; my $current = $CURRENT_CHAPTER{0}; $current .= "\.$CURRENT_CHAPTER{1}" if $CURRENT_CHAPTER{1}; $current .= "\.$CURRENT_CHAPTER{2}" if $CURRENT_CHAPTER{2}; $current .= "\.$CURRENT_CHAPTER{3}" if $CURRENT_CHAPTER{3}; $current .= "\.$CURRENT_CHAPTER{4}" if $CURRENT_CHAPTER{4}; print "==> [process_chapter] current=\"$current\", before=\"$args{'before'}\", caption=\"$args{'caption'}\"\n" if $DEBUG > 1; if ($args{'control'} && $args{'control'} !~ /\|\|/) { print STDERR "*** Warning: No delimiter || found in $args{'control'}\n"; sleep 1; } my @control = split /\|\|/, $args{'control'}; # Delimiter '||' my %control = (); foreach (@control) { my ($key, $val) = split /=/; $control{$key} = $val; print "$args{'ref'}: (control) $key = \"$val\"\n" if $DEBUG; } $control{'not_on_main_toc'} ||= 0; if (defined $TOC_HASH{"::defined\t$args{'ref'}"}) { print STDERR "\n*** ERROR: $args{'ref'} already defined!\n"; $TOC_HASH{"::error\tcount"}++; } $TOC_HASH{"$current\tREF" } = $args{'ref' }; $TOC_HASH{"$current\tBEFORE" } = $args{'before' }; $TOC_HASH{"$current\tCAPTION"} = $args{'caption'}; $TOC_HASH{"$current\tCONTROL"} = \%control; $TOC_HASH{"$args{'before'}\tAFTER"} = $current if $args{'before'}; $TOC_HASH{"::defined\t$args{'ref'}"} = 1; push(@CHAPTERS, $current); } sub sort_index () { $META{__INDEX} = '
    '; my $char_before = ''; my @sub_index = (); my $flag_open_indent = 0; #my $indent_pattern = '> '; #my $indent_pattern = ''; my $indent_pattern = '→  '; foreach (sort keys %INDEX) { my ($link, $word, $chap) = split /\t/, $INDEX{$_}; my $capitolchar = uc substr($word, 0, 1); if ($capitolchar ne $char_before) { push(@sub_index, qq~ $capitolchar ~) if $capitolchar =~ /[A-Z]/; $META{__INDEX} .= "
\n\n

$capitolchar  

\n
    \n"; $char_before = $capitolchar; } $word =~ s/ \(1\.\)$//; my $indent_flag = 0; my $indent = ''; if ($word =~ / \(\d+\.\)$/) { $indent = $indent_pattern; $indent_flag = 1; } $INDEX_MEMO{uc $word} ||= 0; if ($INDEX_MEMO{uc $word} > 1 && $word !~ / \(\d+\.\)$/) { # Put a meta word above other references $indent = "
  • $word
    \n$indent_pattern"; $indent_flag = 1; $flag_open_indent = 1; } if ($indent_flag) { $META{__INDEX} .= qq~$indent$chap   
    ~ . "\n"; } else { $META{__INDEX} .= "
  • \n" if $flag_open_indent; $flag_open_indent = 0; $META{__INDEX} .= qq~
  • $indent$word   $chap
  • ~ . "\n"; } } $META{__INDEX} .= '
'; $META{__INDEX} = '' . join(' - ', @sub_index) . "

\n" . $META{__INDEX}; } sub urlify ($$) { my $iline = $_[0]; my $page = $_[1]; if ($iline =~ /.*\@url\{([a-z~0-9\#\?\=\&,\.%_\-\/:\\]+)\}[\t ]*/i) { my $url = my $url_regex = $1; print "url ------->> \"$url\"\n" if $DEBUG; # $SMTH_GLOB_BUT_NOT_META{"__URL:$url\t$page"} = $page; $url_regex =~ s/\?/\\\?/g; if ($url =~ /^https?\:\/\//i) { (my $url_caption = $url) =~ s/^http:\/\///; $url_caption =~ s/^https:\/\///; $iline =~ s/\@url\{$url_regex\}/$url_caption<\/a>\↑/; } else { (my $url_caption = $url) =~ s/\.html?$//; $url_caption =~ tr/-/ /; $url_caption =~ tr/_/ /; $url_caption = ucfirst lc $url_caption; $iline =~ s/\@url\{$url_regex\}/$url_caption<\/a>/; } } $iline; } ######################################################################### sub date_time () { my ($y, $m, $d) = (localtime)[5,4,3]; $y += 1900; $m += 1; sprintf("%02d.%02d.%d", $d, $m, $y); } __END__