<code>
tags, and <insert>
tags are replaced with the label, not the name, of the respective items.
The overall code for weave looks a lot like the scan code, because it's doing very similar
things. It scans lines of input, using global variables to mark its current state.
Setup is straightforward: we rewind the INPUT
filehandle, load the template
into a list (because we'll be scanning it once for each item page) and set some globals to
blank values.
seek INPUT, 0, 0; $name = ''; $item = 0; $piece = 0; while (<INPUT>) { |
<item>
tags first. For each item we encounter, we'll set
up replacement tags as follows: [##next##]
and [##prev##]
[##prev##]
pointing to the index, and the last has a
[##next##]
pointing to the index.
[##nextlabel##]
and [##prevlabel##]
[##body##]
[##body##]
tag.
[##name##]
, [##url##]
and [##label##]
if (/(<item .*>)/i) { $tag = $1; $tag =~ s/^<item\s+//i; $attr = ""; %thisitem = (name => '', label => '', pattern => '', language => '', format => 'default'); foreach $part (split /"/, $tag) { if ($attr eq '') { $attr = $part; $attr =~ s/^\s*//; $attr =~ s/\s*=\s*$//; } else { $thisitem{$attr} = $part; $attr = ''; } } $name = $thisitem{name}; $formatname = $thisitem{format}; if ($parent{$name} eq '') { $tags{name} = $name; $tags{url} = $url{$name}; $tags{label} = $label{$name}; if ($item == 0) { $i = $items[$#items]; } else { $i = $items[$item-1]; } if ($parent{$i} ne '') { $i = $parent{$i}; } $tags{prev} = $url{$i}; $tags{prevlabel} = $label{$i}; $tags{body} = ''; } else { $n = $name; $n =~ s/^.*?\.//; $tags{body} .= "<br><br>\n"; $tags{body} .= "<a name=\"$n\">\n"; $tags{body} .= "<i>$label{$name}</i><br>\n"; } if ($item == $#items) { $tags{next} = $url{$items[0]}; $tags{nextlabel} = $label{$items[0]}; } else { $tags{next} = $url{$items[$item+1]}; $tags{nextlabel} = $label{$items[$item+1]}; } next; } next if $name eq ''; |
if (/(<\/item\s*>)/i) { if (($parent{$name} eq '' && $children{$name} == 0) || $lastchild{$parent{$name}} eq $name) { if ($parent{$name} eq '') { open OUT, ">$url{$name}"; } else { open OUT, ">$url{$parent{$name}}"; } foreach $line (split /\n/, $format{$formatname}) { $_ = $line . "\n"; while (/\[##(.*?)##\]/) { $tag=$1; s/\[##$tag##\]/$tags{$tag}/e; } s(</li>)()g; s(<p/>)(<p></p>)g; s(<br/>)(<br>)g; s(<hr(.*?)/>)(<hr$1>)g; s(<nbsp/>)( )g; s(<li><b>)(<b><li>)g; print OUT; } close OUT; } $name = ''; $item++; next; } |
<item>
, we scan for pieces, just like scan. Text inside pieces
is formatted differently (with spacing and linebreaks intact.)
if (/(<piece.*>)/i) { $tag = $1; $tag =~ s/^<piece\s*//i; $attr = ""; %thispiece = (add-to => '', language => ''); foreach $part (split /"/, $tag) { if ($attr eq '') { $attr = $part; $attr =~ s/^\s*//; $attr =~ s/\s*=\s*$//; } else { $thispiece{$attr} = $part; $attr = ''; } } $tags{body} .= "<table width=100%>\n"; $tags{body} .= "<tr><td width=30 bgcolor=eeeeee> </td><td width=100%>\n"; if ($thispiece{'add-to'} ne '') { $tags{body} .= "<i>Add the following to \"$label{$thispiece{'add-to'}}\"</i><br>\n"; } $tags{body} .= "<pre>"; $piece = 1; next; } if (/<\/piece\s*>/i) { $tags{body} .= "</pre>"; $tags{body} .= "</td></tr></table>\n"; $piece = 0; next; } |
<insert>
tags.
if (/(<insert\s.*>)/i) { $tag = $1; $before = $`; $after = $'; $tag =~ s/^<insert\s+//i; $attr = ""; %thisinsert = (name => ''); foreach $part (split /"/, $tag) { if ($attr eq '') { $attr = $part; $attr =~ s/^\s*//; $attr =~ s/\s*=\s*$//; } else { $thisinsert{$attr} = $part; $attr = ''; } } if ($thisinsert{name} =~ /^\./) { $thisinsert{name} = $name . $thisinsert{name}; } $tags{body} .= $before . "<i>See <a href=\"$url{$thisinsert{name}}\">"; $tags{body} .= "$label{$thisinsert{name}}</a></i>$after"; next; } |
<insert>
and which is actually
within an <item>
simply gets tacked onto the current item's body after we
make sure all the characters are going to display correctly. Note especially the attention
to detail with the [## delimiter -- if we didn't replace that with a version containing an
HTML entity instead (#) then we'd have a problem with recursion once we get into the
template application code. Which, of course, I realized only after having a problem with
recursion once I got into the template application code.
s/&/&/g if $piece; s/\[\[/</g if $piece; s/\[\#\#/[##/g; s/#\^7/&/g if $piece; s/#\^lt#/</g if $piece; $tags{body} .= $_ if $name ne ''; } |
This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. |