File Coverage

blib/lib/PerlPoint/Anchors.pm
Criterion Covered Total %
statement 45 47 95.7
branch 20 40 50.0
condition 7 18 38.8
subroutine 9 9 100.0
pod 6 6 100.0
total 87 120 72.5


line stmt bran cond sub pod time code
1            
2            
3             # = HISTORY SECTION =====================================================================
4            
5             # ---------------------------------------------------------------------------------------
6             # version | date | author | changes
7             # ---------------------------------------------------------------------------------------
8             # 0.03 |18.08.2003| JSTENZEL | new method generic();
9             # |05.05.2004| JSTENZEL | anchors now store the absolute number of their page,
10             # | | | (which changes the results of query() from scalar string
11             # | | | to [$headline, $page]!;
12             # |12.09.2004| JSTENZEL | using the portable fields::new();
13             # |16.09.2004| JSTENZEL | objects declared as typed lexicals now;
14             # 0.02 |< 14.04.02| JSTENZEL | new methods checkpoint() and reportNew();
15             # |19.04.2002| JSTENZEL | adapted the construction of reportNew()'s return
16             # | | | value construction to certainly reply a hash ref.;
17             # 0.01 |11.10.2001| JSTENZEL | new.
18             # ---------------------------------------------------------------------------------------
19            
20             # = POD SECTION =========================================================================
21            
22             =head1 NAME
23            
24             B - simple anchor collection class
25            
26             =head1 VERSION
27            
28             This manual describes version B<0.03>.
29            
30             =head1 SYNOPSIS
31            
32             # make a new object
33             my $anchors=new PerlPoint::Anchors;
34            
35             # register an anchor
36             $anchors->add('page number', '500');
37            
38             # check an anchor for being known
39             ... if $anchors->query('page number');
40            
41             # get a list of all registered anchors
42             my %regAnchors=%{$anchors->query};
43            
44            
45             =head1 DESCRIPTION
46            
47             Anchors are no part of the PerlPoint language definition, but used by various tags
48             which either define or reference them. To support those tags, this simple collection
49             class was implemented. It provides a consistent and general interface for dealing
50             with anchors.
51            
52             By using the module, one can register an anchor together with a value and query
53             these data later, to check if a certain anchor was already registered or to access
54             the anchor related value. A value can be any valid Perl data. Additionally, the
55             complete collection can be requested.
56            
57            
58             =head1 METHODS
59            
60             =cut
61            
62            
63            
64            
65             # check perl version
66             require 5.00503;
67            
68             # = PACKAGE SECTION (internal helper package) ==========================================
69            
70             # declare package
71             package PerlPoint::Anchors;
72            
73             # declare package version
74             $VERSION=0.03;
75            
76            
77            
78             # = PRAGMA SECTION =======================================================================
79            
80             # set pragmata
81 34     34   203 use strict;
  34         81  
  34         1480  
82            
83             # declare attributes
84 34     34   1241 use fields qw(anchors logMode newAnchors genericPrefix generator);
  34         1718  
  34         416  
85            
86            
87            
88             # = LIBRARY SECTION ======================================================================
89            
90             # load modules
91 34     34   4203 use Carp;
  34         80  
  34         28646  
92            
93            
94             # = CODE SECTION =========================================================================
95            
96            
97             =pod
98            
99             =head2 new()
100            
101             The constructor builds and prepares a new collection object. You may
102             have more than one object at a certain time, they work independently.
103            
104             B
105            
106             =over 4
107            
108             =item class
109            
110             The class name.
111            
112             =item class
113            
114             An optional prefix for generic anchor names. Defaults to "__GANCHOR__".
115            
116             =back
117            
118             B the new object.
119            
120             B
121            
122             my $anchors=new PerlPoint::Anchors;
123            
124             =cut
125             sub new
126             {
127             # get parameter
128 36     36 1 106 my ($class, $genericPrefix)=@_;
129            
130             # check parameters
131 36 50       194 confess "[BUG] Missing class name.\n" unless $class;
132            
133             # build object
134 36         270 my $me=fields::new($class);
135            
136             # set logging up
137 36         161554 $me->checkpoint(0);
138            
139             # init generator of anchor generic anchor names
140 36         92 $me->{generator}=0;
141 36 50       368 $me->{genericPrefix}=defined $genericPrefix ? $genericPrefix : '__GANCHOR__';
142            
143             # supply new object
144 36         949 $me;
145             }
146            
147            
148            
149             =pod
150            
151             =head2 add()
152            
153             Registers a new anchor together with a related value. The value is optional
154             and might be whatever data Perl allows to store via a scalar.
155            
156             B
157            
158             =over 4
159            
160             =item object
161            
162             An object made by C.
163            
164             =item name
165            
166             The anchors name. This is a string. It is I checked if the name was
167             already registered before, an existing entry will be overwritten quietly.
168            
169             =item value
170            
171             Data related to the anchor. This is an scalar. The object does nothing
172             with it then storing and providing it on request, so it is up to the user
173             what kind of data is collected here.
174            
175             =item page
176            
177             The absolute number of the page the anchor is located in. This counting starts
178             with 1 for the first chapter and continues with 2, 3 etc. regardless of chapter levels.
179            
180             =back
181            
182             B the object.
183            
184             B
185            
186             $anchors->add('new anchor', [{new=>'anchor'}], 17);
187            
188             =cut
189             sub add
190             {
191             # get and check parameters
192 15     15 1 42 ((my __PACKAGE__ $me), my ($name, $value, $page))=@_;
193 15 50       38 confess "[BUG] Missing object parameter.\n" unless $me;
194 15 50 33     84 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
195 15 50       34 confess "[BUG] Missing anchor name parameter.\n" unless defined $name;
196 15 50       28 confess "[BUG] Missing page number parameter.\n" unless defined $page;
197            
198             # add new anchor (should we check overwriting?)
199 15 50       80 $me->{anchors}{$name}=[defined $value ? $value : undef, $page];
200            
201             # update anchor log, if necessary
202 15 50       42 $me->{newAnchors}{$name}=$me->{anchors}{$name} if $me->{logMode};
203            
204             # supply modified object
205 15         33 $me;
206             }
207            
208            
209            
210             =pod
211            
212             =head2 query()
213            
214             Requests anchors from the collection. This can be either the complete
215             collection or just one entry. The method can be used both to check
216             if an anchor was registered and to get its value.
217            
218            
219             B
220            
221             =over 4
222            
223             =item object
224            
225             An object made by C.
226            
227             =item name
228            
229             The name of the anchor of interest.
230            
231             This parameter is optional.
232            
233             =back
234            
235             B
236            
237             If no C was passed, the complete collection is provided as a
238             reference to a hash containing name-value/page-pairs. The referenced hash
239             is the objects own hash used internally, so modifications will affect
240             the object.
241            
242             If an anchor name was passed and this name was registered, a hash
243             reference is provided as well (for reasons of consistency). The
244             referenced hash is a I and contains the appropriate pair of
245             anchor name and a reference to an array of its value and page.
246            
247             If an anchor name was passed and this name was I registered,
248             the method returns an undefined value.
249            
250             B
251            
252             # check an anchor for being known
253             ... if $anchors->query('new anchor');
254            
255             # get the value of an anchor
256             if ($anchors->query('new anchor'))
257             {$value=$anchors->query('new anchor')->{'new anchor'};}
258            
259             # get the collection
260             my %anchorHash=%{$anchors->query};
261            
262             =cut
263             sub query
264             {
265             # get and check parameters
266 4     4 1 28 ((my __PACKAGE__ $me), my $name)=@_;
267 4 50       11 confess "[BUG] Missing object parameter.\n" unless $me;
268 4 50 33     24 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
269            
270             # certain name of interest?
271 4 50       10 if (defined $name)
  4 50       26  
272             {return exists $me->{anchors}{$name} ? {$name=>$me->{anchors}{$name}} : undef;}
273            
274             # ok, provide the complete list
275 0 0       0 %{$me->{anchors}} ? $me->{anchors} : undef;
  0         0  
276             }
277            
278            
279             =pod
280            
281             =head2 checkpoint()
282            
283             Activates or deactivates logging of all anchors added after this call.
284             By default, logging is switched off.
285            
286             The list of new anchors can be requested by a call of I.
287            
288             Previous logs are I by a new call of C.
289            
290             B
291            
292             =over 4
293            
294             =item object
295            
296             An object made by C.
297            
298             =item logging mode
299            
300             Logging is activated by a true value, disabled otherwise.
301            
302             =back
303            
304             B the object.
305            
306             B
307            
308             $anchors->checkpoint;
309            
310             =cut
311             sub checkpoint
312             {
313             # get and check parameters
314 140     140 1 396 ((my __PACKAGE__ $me), my $mode)=@_;
315 140 50       1046 confess "[BUG] Missing object parameter.\n" unless $me;
316 140 50 33     1406 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
317            
318             # reset log, flag logging state
319 140         749 $me->{newAnchors}={};
320 140 100 66     1308 $me->{logMode}=(defined $mode and $mode) ? 1 : 0;
321            
322             # supply modified object
323 140         479 $me;
324             }
325            
326            
327             =pod
328            
329             =head2 reportNew()
330            
331             Reports anchors added after the last recent call of C.
332             If the C invokation disabled anchor logging, the result
333             will by empty even if anchors I added.
334            
335             Requesting the log does I reset the logging data. To reset it,
336             I needs to be called again.
337            
338             B
339            
340             =over 4
341            
342             =item object
343            
344             An object made by C.
345            
346             =back
347            
348             B A reference to a hash containing names and values of
349             newly added anchors. The supplied hash can be modified without
350             effect to the object.
351            
352             B
353            
354             my $newAnchorHash=$anchors->reportNew;
355            
356             =cut
357             sub reportNew
358             {
359             # get and check parameters
360 60     60 1 133 (my __PACKAGE__ $me)=@_;
361 60 50       175 confess "[BUG] Missing object parameter.\n" unless $me;
362 60 50 33     372 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
363            
364             # supply a reference to a hash of added anchors (use a helper variable
365             # to enforce perl to recognize the hash reference constructor)
366 60         84 my $rc={%{$me->{newAnchors}}};
  60         234  
367 60         433 $rc;
368             }
369            
370            
371             =pod
372            
373             =head2 generic()
374            
375             Supplies a generic anchor name build according to the pattern /^\d+$/ (with
376             the set up in the call of I) - so it is recommended not to use those
377             names explicitly.
378            
379             B
380            
381             =over 4
382            
383             =item object
384            
385             An object made by C.
386            
387             =back
388            
389             B The new anchor name.
390            
391             B
392            
393             $anchors->add($anchors->generic, $data);
394            
395             =cut
396             sub generic
397             {
398             # get and check parameters
399 7     7 1 10 (my __PACKAGE__ $me)=@_;
400 7 50       21 confess "[BUG] Missing object parameter.\n" unless $me;
401 7 50 33     40 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
402            
403             # suppply a new generic name
404 7         79 join('', $me->{genericPrefix}, ++$me->{generator});
405             }
406            
407            
408            
409            
410             # flag successful loading
411             1;
412            
413             # = POD TRAILER SECTION =================================================================
414            
415             =pod
416            
417             =head1 NOTES
418            
419            
420             =head1 SEE ALSO
421            
422             =over 4
423            
424             =item B
425            
426             The parser module working on base of the declarations.
427            
428            
429             =back
430            
431            
432             =head1 SUPPORT
433            
434             A PerlPoint mailing list is set up to discuss usage, ideas,
435             bugs, suggestions and translator development. To subscribe,
436             please send an empty message to perlpoint-subscribe@perl.org.
437            
438             If you prefer, you can contact me via perl@jochen-stenzel.de
439             as well.
440            
441             =head1 AUTHOR
442            
443             Copyright (c) Jochen Stenzel (perl@jochen-stenzel.de), 1999-2004.
444             All rights reserved.
445            
446             This module is free software, you can redistribute it and/or modify it
447             under the terms of the Artistic License distributed with Perl version
448             5.003 or (at your option) any later version. Please refer to the
449             Artistic License that came with your Perl distribution for more
450             details.
451            
452             The Artistic License should have been included in your distribution of
453             Perl. It resides in the file named "Artistic" at the top-level of the
454             Perl source tree (where Perl was downloaded/unpacked - ask your
455             system administrator if you dont know where this is). Alternatively,
456             the current version of the Artistic License distributed with Perl can
457             be viewed on-line on the World-Wide Web (WWW) from the following URL:
458             http://www.perl.com/perl/misc/Artistic.html
459            
460            
461             =head1 DISCLAIMER
462            
463             This software is distributed in the hope that it will be useful, but
464             is provided "AS IS" WITHOUT WARRANTY OF ANY KIND, either expressed or
465             implied, INCLUDING, without limitation, the implied warranties of
466             MERCHANTABILITY and FITNESS FOR A PARTICULAR PURPOSE.
467            
468             The ENTIRE RISK as to the quality and performance of the software
469             IS WITH YOU (the holder of the software). Should the software prove
470             defective, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
471             CORRECTION.
472            
473             IN NO EVENT WILL ANY COPYRIGHT HOLDER OR ANY OTHER PARTY WHO MAY CREATE,
474             MODIFY, OR DISTRIBUTE THE SOFTWARE BE LIABLE OR RESPONSIBLE TO YOU OR TO
475             ANY OTHER ENTITY FOR ANY KIND OF DAMAGES (no matter how awful - not even
476             if they arise from known or unknown flaws in the software).
477            
478             Please refer to the Artistic License that came with your Perl
479             distribution for more details.
480