package votorola::b::Glossary; # Copyright 2009, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. use strict; use warnings; =pod =head1 DESCRIPTION Glossary construction for documents. =head1 EXPORTS =over 4 =cut BEGIN { use Exporter (); our @ISA; @ISA = qw( Exporter ); our @EXPORT_OK; @EXPORT_OK = qw( auto_edit_glossary hash_to_text ); } our @EXPORT_OK; =pod =item B( $I, @I ) For embedded AutoEditor scripts, updates the immediately preceding glossary that commences at line $C. Dies if $C was not defined, e.g. by a previous embedded script; otherwise automatically undefines it, in preparation for the next use. =cut sub auto_edit_glossary( $@ ) { use votorola::b::AutoEditor qw( $auto_edit_top $begin @buffer $is_buffer_changed ); my $basepath = shift; defined $auto_edit_top or die; my $top = $auto_edit_top; undef $auto_edit_top; my $new_text = hash_to_text( $basepath, @_ ); $is_buffer_changed = $new_text ne join( '', @buffer[$top..$begin-1] ); $is_buffer_changed or return; splice( @buffer, $top, $begin - $top, $new_text ); } =pod =item B( $I, @I ) Converts the specified list of glossary hash references to text, suitable for insertion in a document. The $I is the path to the base "votorola" directory, e.g. "../.." or ".". =cut sub hash_to_text( $@ ) { my $basepath = shift; my %glossary; for my $glossaryHASH( @_ ) { for my $term( keys %$glossaryHASH ) { my %entry; { my $entryHASH = $glossary{$term}; if( defined $entryHASH ) { %entry = %$entryHASH } else { %entry = ( 'def' => [] ); # empty entry $glossary{$term} = \%entry; } } my %entryNew = %{$$glossaryHASH{$term}}; for my $key( keys %entryNew ) { if( $key eq 'def' ) { push( @{$entry{'def'}}, @{$entryNew{'def'}} ); # append definitions } else { $entry{$key} = $entryNew{$key}; # clobber all others with new items # old items should usually be undefined, anyway } } } } my $text = "\n \n"; my @term = sort { lc($a) cmp lc($b) } keys %glossary; for my $term( @term ) { my $entryHASH = $glossary{$term}; my $id = $$entryHASH{'id'}; if( !$id ) { $id = 'gn-' . $term; $id =~ s![^a-zA-z0-9]!-!g; } $text .= qq|
\n|; my $ref = $$entryHASH{'ref'}; defined $ref or die "no 'ref' defined for glossary term '$term'\n"; $text .= qq| $term|; # no newlines in here, or Firefox sometimes breaks the natural flow my @def = @{$$entryHASH{'def'}}; for my $def( @def ) { $text .= qq|$def|; } $text .= qq|\n
\n|; } $text .= qq|\n|; $text =~ s!{basepath}!$basepath!g; return $text; } =pod =back =cut 1;