Page format is trivial: it is arbitrary formatted plaintext.
It will be rendered in HTML through the <pre> tag.
The only specific inline formatting construction is [LINKS].
+It may be followed by "#name" to create an anchored link.
But there are also special "command" lines, ending with "\r\n"
instead of ordinary "\n". Here are possible commands, playing
* => URL[ optional text]
Creates <a href="URL">{optional text|URL}</a> link in HTML.
+
* img URL[ optional text][ => URL-A]
Creates <img src="URL" [alt="optional text"] /> in HTML.
If "=> URL" is specified, then <a href="URL-A"><img ... /></a>.
+
* |...
Just inserts raw ... line to HTML output as-is.
+
* #...
Does nothing, commented line.
-* do-backs
- Forcefully creates a table with all backlinks to the page.
+
* <<[indent][page]
Include contents of the specified page. indent is optional.
Brackets around [page] are for making a link to page.
+
+* do-backs
+ Forcefully creates a table with all backlinks to the page.
+
+* A name
+ Creates an invisible anchor with the specified name.
+
+* A [page] name
+ Also creates an anchor, but also links resulting page+anchor to the
+ specified page. It may be useful for creating index-pages.
use utf8;
use Carp q{croak};
-use version; our $VERSION = qv(1.0.0);
+use version; our $VERSION = qv(1.1.0);
use Encode qw(encode decode);
binmode STDOUT, q{:encoding(UTF-8)};
$cat = dirname $pth;
$cat = ($cat eq q{.}) ? q{/} : "$cat/";
if (-d $fn) {
- if (not defined $CatFiles{$pth}) {
+ if (not exists $CatFiles{$pth}) {
my @files;
my @dirs;
$CatFiles{$pth} = \@files;
for my $pth (keys %Mtimes) {
my %found;
my $lines = 0;
+ my $vlines = 0; # visible lines
+ my sub assureInFound {
+ my ($w) = @_;
+ if (not exists $found{$w}) {
+ my %h;
+ $found{$w} = \%h;
+ }
+ return;
+ }
+ my sub isMissing {
+ my ($w) = @_;
+ if (not exists $Mtimes{$w}) {
+ if (exists $ENV{SWG_PRINT_MISSING}) {
+ print "missing $w\n";
+ }
+ return 1;
+ }
+ return 0;
+ }
my sub procline;
sub procline {
my ($line) = @_;
if ($line =~ /^.*<<.*\[(.*)\]${CR}/) {
- $found{$1} = 1;
+ assureInFound $1;
+ $found{$1}{q{}} = 0;
open my $fh, q{<:encoding(UTF-8)}, $1 or croak "$!";
while (<$fh>) { $lines++; procline $_ }
close $fh or croak "$!";
return;
}
+ if ($line !~ /^\s*[#A]|do-backs.*${CR}$/) {
+ $vlines++;
+ }
+ if ($line =~ /^\s*#.*${CR}$/) {
+ return;
+ }
+ if ($line =~ /^\s*A\s+\[([^[]+)\]${CR}$/) {
+ my $w = $1;
+ return if isMissing $w;
+ assureInFound $w;
+ $found{$w}{q{}} = $vlines;
+ return;
+ }
+ if ($line =~ /^\s*A\s+\[([^[]+)\]\s+(.+)${CR}$/) {
+ my $w = $1;
+ return if isMissing $w;
+ assureInFound $w;
+ $found{$w}{$2} = $vlines;
+ return;
+ }
foreach my $w (split /\s+/, $line) {
if ($w =~ /\[([^]]+)\]/) {
$w = $1;
next;
}
} else {
- if (not exists $Mtimes{$w}) {
- if (exists $ENV{SWG_PRINT_MISSING}) {
- print "missing $w\n";
- }
- next;
- }
+ next if isMissing $w;
}
- $found{$w} = 1;
+ assureInFound $w;
+ $found{$w}{q{}} = 0;
}
return;
}
my %h;
$Backs{$_} = \%h;
}
- $Backs{$_}{$pth} = 1;
+ $Backs{$_}{$pth} = $found{$_};
}
}
}
$base = dirname $base;
if ($base eq q{/}) {
- $base = ".";
+ $base = q{.};
}
foreach (@links) {
$rel = File::Spec->abs2rel($_, $base);
} elsif ($cmd eq q{do-backs}) {
$doBacks = 1;
return;
+ } elsif ($cmd =~ /^A\s+\[[^[]+\]$/) {
+ return;
+ } elsif ($cmd =~ /^A\s+\[[^[]+\]\s+(.+)$/) {
+ print {$out} "<a id=\"$1\"></a>";
+ return;
+ } elsif ($cmd =~ /^A\s+(.+)$/) {
+ print {$out} "<a id=\"$1\"></a>";
+ return;
} elsif ($cmd =~ /^#/) {
return;
} elsif ($cmd =~ /^[|]/) {
$_ = htmlescape $_;
if (/\[.+\]/) {
while (my ($i, $l) = each @links) {
- s/\[\Q$l\E\]/<a href="$rels[$i].html">[$l]<\/a>/g;
+ s/\[\Q$l\E\]#(\S+)/<a href="$rels[$i].html#$1">[$l]#$1<\/a>/g;
+ if (not defined $1) {
+ s/\[\Q$l\E\]/<a href="$rels[$i].html">[$l]<\/a>/g;
+ }
}
}
}
while (<$fh>) { procline $_ }
close $fh or croak "$!";
}
- @links = sort keys %{$Backs{noindex $page}};
- my $backsWereGenerated = ($doBacks && $#links != -1) ? 1 : 0;
- if ($backsWereGenerated) {
- makerels;
- procline "|<a id=\"backs\"><hr/>${CR}\n";
- print {$out} " Backlinks:\n";
- my $ctr = 0;
- my $pth;
- foreach my $l (@links) {
- $pth = noindex $l;
- procline sprintf "%3d % -39s %19s %8d\n",
- $ctr, "[$pth]", ($Mtimes{$l} or q{}), ($Lines{$l} or 0);
- $ctr++;
+ my $backsWereGenerated = 0;
+ {
+ @links = ();
+ my %backs;
+ if (exists $Backs{noindex $page}) {
+ %backs = %{$Backs{noindex $page}};
+ @links = sort keys %backs;
+ }
+ if ($doBacks && $#links != -1) {
+ my $backsWereGenerated = 1;
+ makerels;
+ procline "|<a id=\"backs\"><hr/>${CR}\n";
+ print {$out} " Backlinks:\n";
+ my $ctr = 0;
+ my $pth;
+ foreach my $l (@links) {
+ $pth = noindex $l;
+ foreach my $a (sort keys %{$backs{$l}}) {
+ procline sprintf "%3d % -39s %19s %8d\n",
+ $ctr, ($a eq q{}) ? "[$pth]" : "[$pth]#$a",
+ ($Mtimes{$l} or q{}), ($Lines{$l} or 0);
+ $ctr++;
+ }
+ }
}
}
print {$out} "</pre>\n";
return $n;
}
-sub printMenuEntry {
- print q{* } . (nodename $_) . q{: } . (nodename $_) . ".\n";
+sub printIndexMenuEntry {
+ my ($node, $anchor, $line) = @_;
+ $node = nodename $node;
+ print "* $node#$anchor: $node. (line $line)\n";
return;
}
+my $InfoIndexCmd = "\0\b[index\0\b]\n* Menu:\n";
+
+sub printInfoBacks {
+ my $page = $_[0];
+ if (not defined $Backs{noindex $page}) {
+ return;
+ }
+ my %backs = %{$Backs{noindex $page}};
+ if (scalar keys %backs > 0) {
+ print "${InfoIndexCmd}Backlinks:\n";
+ foreach my $l (sort keys %backs) {
+ my %as = %{$backs{$l}};
+ foreach my $a (sort keys %as) {
+ printIndexMenuEntry $l, $a, $as{$a} + 2;
+ }
+ }
+ print "\n";
+ }
+}
+
sub genInfo {
my $page = shift;
my %links;
if (/${CR}$/) {
chop;
/^\s*(.*)$/;
- if (($1 =~ /^#/) or ($1 =~ /^do-backs/)) {
+ if ($1 =~ /^[#A]|do-backs/) {
next;
}
}
print "$_\n";
}
close $fh or croak "$!";
- my @backs = sort keys %{$Backs{noindex $page}};
- if ($#backs != -1) {
- print "\n* Menu:\nBacklinks:\n";
- foreach (@backs) {
- printMenuEntry $_;
- }
- print "\n";
- }
+ printInfoBacks $page;
return;
}
chop;
/^\s*(.*)$/;
my $cmd = $1;
- if (($cmd =~ /^#/) or ($cmd =~ /^do-backs/)) {
+ if ($cmd =~ /^[#A]|do-backs/) {
next;
}
if ($cmd =~ /^=> (\S+)\s?(.*)$/) {
return;
}
+sub printMenuEntry {
+ my ($node) = @_;
+ $node = nodename $node;
+ print "* $node: $node.\n";
+ return;
+}
+
sub genInfoIndex {
my $page = shift;
my $pth;
printMenuEntry $_;
}
print "\n";
- my @links = sort @{$CatDirs{$page}};
- if ($#links != -1) {
- print "\n* Menu:\nSubcategories:\n";
- foreach (@links) {
- printMenuEntry $_;
- }
- print "\n";
- }
- @links = sort keys %{$Backs{noindex $page}};
- if ($#links != -1) {
- print "\n* Menu:\nBacklinks:\n";
- foreach (@links) {
- printMenuEntry $_;
+ {
+ my @links = sort @{$CatDirs{$page}};
+ if ($#links != -1) {
+ print "\n* Menu:\nSubcategories:\n";
+ foreach (@links) {
+ printMenuEntry $_;
+ }
+ print "\n";
}
- print "\n";
}
+ printInfoBacks $page;
return;
}
genInfo $page;
}
print "${sep}File: self, Node: index, Up: Top\n\n";
- print "\0\b[index\0\b]\n* Menu:\n";
+ print $InfoIndexCmd;
foreach my $cat (keys %CatFiles) {
print q{* } . (nodename $cat) . q{: } .
(nodename $cat) . ". (line 0)\n";
delete $Mtimes{q{index}};
delete $CatFiles{q{/}};
} else {
- genLaTeXSection "/", genIndex2Buf q{/};
+ genLaTeXSection q{/}, genIndex2Buf q{/};
delete $CatFiles{q{/}};
}
foreach my $cat (keys %CatFiles) {