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. |
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. |
WEB
, of course,
generated a comprehensive list of crossreferences and a list of identifiers during tangle.<insert>
tag is replaced by the label of its item, suitably formatted.
Text pieces are formatted as code blocks. <object>
, <item>
, and
<piece>
. Oh, and I've just added <format>
.
One of the things the tag handlers do is to set and unset various state markers.
For instance, I terminate the <item>
tag by setting the $name
global to blank. I also set the $piecename
global to blank in case the user
forgot to terminate the current piece. I know that violates the principles of XML tokenization,
but again, later we'll get into real XML tokenization and I don't want to mess with it yet.
<object>
tag.
Note that this is assuming that the tag will be the only thing on the line. I don't want to
get into real tokenizing of the XML input, because that will be the province of the QDMT, which
is my next four-letter vowelless acronym. The next version of lpml will use the QDMT to tokenize
its input.
At any rate, if the object tag is encountered, I read its attributes into the
$thistag
hash. The other handlers reuse this hash.
<piece>
tag, which is pretty analogous to
<item>
.
<format>
tag simply takes its content and stashes it into a hash, just
like pieces. The only attribute we care about in a format tag is its name.
$pieces
hash we populated during the scan step to generate code. We insert items in other items by
using the <insert>
tag.
Since our coding language is XML, we can't use the character '<
' explicitly
in our code. Irritating, but that's one of the tiny little disadvantages of using XML, and it's
offset by so many advantages that living with it isn't so hard. All we do is use
'[[
' instead (hard-coded in this version, soon to be specifiable.) So the tangle
step also takes care of substituting our '<
' back in.
Tangle is inherently recursive. I'm dumbly following the whole recursive structure in a
depth-first manner; the smarter thing would be to cache items as they're tangled in case of
reuse (then I wouldn't have to retangle that item). Since I'm working with small files here,
that probably isn't worth the effort, so I'm not going into it.
Note also that since Perl can define subroutines right in the middle of the rest of the code,
I found it more natural simply to include the recursive routine here right in the middle of
things, instead of packing it off into some subroutine block.
<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.
<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##]
<item>
, we scan for pieces, just like scan. Text inside pieces
is formatted differently (with spacing and linebreaks intact.)
<insert>
tags.
<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.
<format>
tag working, it turned out to be much
cleaner simply to make those tags available for all pages, then allow an item named
"index" to write out the index page. So instead of writing the index page in this block, I'm
just going to build the tags and trust that the document will use them. And frankly, if not,
no skin off my nose. In that case, the document will need some kind of explicitly generated
navigation.
So let's build our item and object indices. Each of these is hardwired to
be a bullet point list at the moment; that would be a nice thing to open up to configuration
but that sort of enhancement will come later.
Since the index page is now a plain old item, I'm going to omit it from the table of contents.
It's kind of jarring to see it there. On the other hand, since the index page is now a plain
old item, I can use its label in further link formatting!
The use of the tags
hash has to do with the way I do template printing.
The item list has a variable $level
which keeps track of the table of contents
level. Subitems are indented under their parents. When a non-subitem is encountered and the
$level
is 1, then we have to terminate the sublevel.
<format>
tag 5/7/2000