File Coverage

blib/lib/PerlPoint/Backend.pm
Criterion Covered Total %
statement 187 214 87.3
branch 113 218 51.8
condition 46 120 38.3
subroutine 21 22 95.4
pod 14 14 100.0
total 381 588 64.8


line stmt bran cond sub pod time code
1            
2            
3             # = HISTORY SECTION =====================================================================
4            
5             # ---------------------------------------------------------------------------------------
6             # version | date | author | changes
7             # ---------------------------------------------------------------------------------------
8             # 0.15 |07.03.2006| JSTENZEL | the new simple dummy tokens are ignored;
9             # 0.14 |16.09.2004| JSTENZEL | objects declared as typed lexicals now;
10             # 0.13 |29.05.2003| JSTENZEL | new optional generator passing;
11             # |15.06.2003| JSTENZEL | new general handler interface (DIRECTIVE_EVERY);
12             # |12.09.2004| JSTENZEL | using the portable fields::new();
13             # 0.12 |04.02.2003| JSTENZEL | new method headlineIds2Data();
14             # 0.11 |08.03.2002| JSTENZEL | new method docstreams();
15             # 0.10 |14.08.2001| JSTENZEL | adapted to new stream data format, introduced modes;
16             # | | JSTENZEL | slight POD fixes;
17             # |16.08.2001| JSTENZEL | added bind(), headlineNr() and move2chapter();
18             # |17.08.2001| JSTENZEL | added unbind() and next();
19             # |27.09.2001| JSTENZEL | added currentChapterNr();
20             # |29.09.2001| JSTENZEL | stream position is no stored in the backend object,
21             # | | | this will allow to have several backend objects
22             # | | | operating on the same stream;
23             # | | JSTENZEL | added toc();
24             # |11.10.2001| JSTENZEL | toc() now takes documents without headlines into acc.,
25             # |14.10.2001| JSTENZEL | using new stream directive index constants,
26             # | | JSTENZEL | adapted to modified stream directive structure: the
27             # | | | first entry is a hint hash now;
28             # | | JSTENZEL | stream parts can now be hidden or ignored on parsers cmd.;
29             # |18.11.2001| JSTENZEL | extended traces
30             # |23.11.2001| JSTENZEL | fixed POD bugs: I had written ==head2 ;-)
31             # |24.11.2001| JSTENZEL | bugfix in toc(): special case when startup headline is the
32             # | | | last headline in the stream;
33             # 0.09 |14.03.2001| JSTENZEL | added stream processing time report;
34             # | | JSTENZEL | slight code optimizations;
35             # 0.08 |13.03.2001| JSTENZEL | simplified code slightly;
36             # | | JSTENZEL | added visibility feature to visualize processing;
37             # |14.03.2001| JSTENZEL | added mailing list hint to POD;
38             # 0.07 |07.12.2000| JSTENZEL | new namespace PerlPoint;
39             # 0.06 |19.11.2000| JSTENZEL | updated POD;
40             # 0.05 |13.10.2000| JSTENZEL | slight changes;
41             # 0.04 |30.09.2000| JSTENZEL | updated POD;
42             # 0.03 |27.05.2000| JSTENZEL | updated POD;
43             # | | JSTENZEL | added $VERSION;
44             # 0.02 |13.10.1999| JSTENZEL | added real POD;
45             # | | JSTENZEL | constants went out, so I could remove the could to generate
46             # | | | them at compile time;
47             # 0.01 |11.10.1999| JSTENZEL | new.
48             # ---------------------------------------------------------------------------------------
49            
50             # = POD SECTION =========================================================================
51            
52             =head1 NAME
53            
54             B - frame class to transform PerlPoint::Parser output
55            
56             =head1 VERSION
57            
58             This manual describes version B<0.15>.
59            
60             =head1 SYNOPSIS
61            
62             # load the module:
63             use PerlPoint::Backend;
64            
65             # build the backend
66             my ($backend)=new PerlPoint::Backend(name=>'synopsis');
67            
68             # register handlers
69             $backend->register(DIRECTIVE_BLOCK, \&handleBlock);
70             $backend->register(DIRECTIVE_COMMENT, \&handleComment);
71             $backend->register(DIRECTIVE_DOCUMENT, \&handleDocument);
72             $backend->register(DIRECTIVE_HEADLINE, \&handleHeadline);
73             $backend->register(DIRECTIVE_POINT, \&handlePoint);
74             $backend->register(DIRECTIVE_SIMPLE, \&handleSimple);
75             $backend->register(DIRECTIVE_TAG, \&handleTag);
76             $backend->register(DIRECTIVE_TEXT, \&handleText);
77             $backend->register(DIRECTIVE_VERBATIM, \&handleVerbatim);
78            
79             # finally run the backend
80             $backend->run(\@streamData);
81            
82             =head1 DESCRIPTION
83            
84             After an ASCII text is parsed by an B object, the original text is transformed
85             into stream data hold in a Perl array. To process this intermediate stream further (mostly
86             to generate output in a certain document description language), a program has to walk through
87             the stream and to process its tokens.
88            
89             Well, B provides a class which encapsulates this walk in objects which deal
90             with the stream, while the translator programmer is focussed on generating the final
91             representation of the original text. This is done by registering I which will be
92             called when their target objects are discovered in the intermediate stream.
93            
94             The stream walk can be performed in various ways (please see following sections for details).
95             The common way is to use I which walks through the stream from its first to its last
96             token and takes everything found into account to invoke appropriate callbacks.
97            
98            
99             =head2 Modes
100            
101             By default, a backend object inspects the token stream token by token. This way everything
102             is handled in the original order, according to the input once parsed. But sometimes you want
103             to know something about the documents I which simply means about headlines only.
104            
105             For example, consider the case that you want to build
106             a table of contents or a table of valid chapter references
107             before the "real" slides are made. In the mentioned token
108             mode this takes more time than it should, because a lot
109             of additional tokens are processed besides the headlines.
110            
111             In such cases, the backend can be enforced to work in "headline mode". This means that I
112             headlines are processed which accelerates things significantly.
113            
114             Modes are switched by method I. Please note that a stream can be processed more than once,
115             so one can process it in headline mode first, use the headline information, and then switch back
116             to the usual token mode and process the entire document data.
117            
118            
119             =head2 Ways of stream processing
120            
121             The base model of stream processing implemented by this class is based on "events". This means
122             that the token stream is processed by a loop which invokes user specified callback functions
123             to handle certain token types. In this model, the loop is in control. This works fine in stream
124             translation, e.g. to produce slides/documents in a target format, and is done by invoking the
125             method I.
126            
127             Nevertheless, there are cases when converters need to be in full control, which means in fine
128             grained control of token processing. In this model the calling program (the converter) initiates
129             the processing of each token. This is especially useful if a converter is not really a converter
130             but a projector which uses the stream to I the slides on the fly.
131            
132             This second model of fine grained control is supported as well. The appropriate method (used
133             as an alternative of I) is I.
134            
135            
136             =head2 Stream navigaton
137            
138             Usually a stream is processed from the beginning to its end, but it is possible to set up an
139             arbitrary sequence of chapters as well. (This is mostly intended for use in projectors.) Two
140             methods are provided to do this: I moves back to the beginning of the entire stream,
141             while I chooses a certain chapter to continue the processing with.
142            
143             Stream navigation works both in callbacks and if walking the stream via I.
144            
145            
146             =head2 The whole picture
147            
148             Modes, the stream processing method and stream navigation can be freely combined. If the defaults
149             are used as shown in the I, a backend object works in headline mode and processes the
150             stream by I, usually without further navigation. But this is no rule. Make use of the
151             features as it is necessary to build the converter you want!
152            
153            
154             =head1 METHODS
155            
156             =cut
157            
158            
159             # declare package
160             package PerlPoint::Backend;
161            
162             # declare version
163             $VERSION=$VERSION=0.15;
164            
165             # pragmata
166 34     34   1126363 use strict;
  34         90  
  34         2326  
167            
168             # declare class members
169 34         240 use fields qw(
170             data
171             display
172             flags
173             generator
174             handler
175             hide
176             ignoredDirectives
177             name
178             processingHeadline
179             statistics
180             stream
181             streamControl
182             trace
183             vis
184 34     34   34211 );
  34         79269  
185            
186             # load modules
187 34     34   5075 use Carp;
  34         87  
  34         3145  
188 34     34   43398 use Storable qw(dclone);
  34         120901  
  34         3596  
189 34     34   26100 use PerlPoint::Constants 0.19 qw(:DEFAULT :stream);
  34         1199  
  34         209784  
190            
191            
192             =pod
193            
194             =head2 new()
195            
196             The constructor builds and prepares a new backend object. You may
197             have more than one object at a certain time, they work independently.
198            
199             B
200             All parameters except of the I parameter are named (pass them by hash).
201            
202             =over 4
203            
204             =item class
205            
206             The class name.
207            
208             =item name
209            
210             Because there can be more than exactly one backend object, your object
211             should be named. This is not necessarily a need but helpful reading traces.
212            
213             =item trace
214            
215             This parameter is optional. It is intended to activate trace code while the
216             object methods run. You may pass any of the "TRACE_..." constants declared
217             in B, combined by addition as in the following example:
218            
219             trace => TRACE_NOTHING+TRACE_BACKEND,
220            
221             In fact, only I and I take effect to backend
222             objects.
223            
224             If you omit this parameter or pass TRACE_NOTHING, no traces will be displayed.
225            
226             =item display
227            
228             This parameter is optional. It controls the display of runtime messages
229             like informations or warnings in all object methods. By default, all
230             messages are displayed. You can suppress these informations partially
231             or completely by passing one or more of the "DISPLAY_..." variables
232             declared in B.
233            
234             Constants can be combined by addition.
235            
236             =item vispro
237            
238             activates "process visualization" which simply means that a user will see
239             progress messages while the backend processes the stream. The I
240             value of this setting determines how often the progress message shall be
241             updated by a I:
242            
243             # inform every five chapters
244             vispro => 5,
245            
246             Process visualization is automatically suppressed unless STDERR is
247             connected to a terminal, if this option is omitted, I was set
248             to C or backend Is are activated.
249            
250             =item generator
251            
252             This is an internal interface, to make backends work together with
253             C objects. If you build a backend manually,
254             you do not have to care for this, just ignore it. If you build
255             a C application, just pass the generator
256             object.
257            
258             Note: Generator handling is in alpha state, so manual usage is
259             standard and traditional.
260            
261             =back
262            
263             B
264             the new object.
265            
266             B
267            
268             my ($backend)=new PerlPoint::Backend(name=>'example');
269            
270             =cut
271             sub new
272             {
273             # get parameters
274 110     110 1 6847 my ($class, @pars)=@_;
275            
276             # build parameter hash
277 110 50       506 confess "[BUG] The number of parameters should be even - use named parameters, please.\n" if @pars%2;
278 110         733 my %pars=@pars;
279            
280             # check parameters
281 110 50       404 confess "[BUG] Missing class name.\n" unless $class;
282 110 50       599 confess "[BUG] Missing name parameter.\n" unless exists $pars{name};
283            
284             # build object
285 110         1468 my $me=fields::new($class);
286            
287             # init object
288 110         21923 @{$me}{qw(handler hide ignoredDirectives name stream)}=({}, 0, [], $pars{name}, STREAM_TOKENS);
  110         538  
289            
290             # store trace and display settings
291 110 50       566 $me->{trace}=defined $pars{trace} ? $pars{trace} : TRACE_NOTHING;
292 110 50       639 $me->{display}=defined $pars{display} ? $pars{display} : DISPLAY_ALL;
293 110 50 0     815 $me->{vis}=(
294             defined $pars{vispro}
295             and not $me->{display} & &DISPLAY_NOINFO
296             and not $me->{trace}>TRACE_NOTHING
297             and -t STDERR
298             ) ? $pars{vispro} : 0;
299 110 50       552 $me->{generator}=exists $pars{generator} ? $pars{generator} : '';
300            
301             # reply the new object
302 110         1064 $me;
303             }
304            
305            
306            
307             =pod
308            
309             =head2 register()
310            
311             After building a new object by I the object can be prepared
312             by calls of the register method.
313            
314             If the object walks through the data stream generated by B,
315             it will find several directives. A directive is a data struture flagging
316             that a certain document part (or even formatting) starts or is completed.
317             E.g. a headline is represented by headline start directive followed by
318             tokens for the headline contents followed by a headline completion directive.
319            
320             By using this method, you can register directive specific functions which
321             should be called when the related directives are discovered. The idea is
322             that such a function can produce a target language construct representing
323             exactly the same document token that is modelled by the directive. E.g. if
324             your target language is HTML and you register a headline handler and a
325             headline start is found, this handler can generate a "" tag. This
326             is quite simple.
327            
328             According to this design, the object will pass the following data to
329             a registered function:
330            
331             =over 4
332            
333             =item directive
334            
335             the directive detected, this should be the same the function was
336             registered for. See B for a list of directives.
337            
338             =item start/stop flag
339            
340             The document stream generated by the parser is strictly synchronous.
341             Everything except of plain strings is represented by an open directive
342             and a close directive, which may embed other parts of the document.
343             A headline begins, something is in, then it is complete. It's the
344             same for every tag or paragraph and even for the whole document.
345            
346             So well, because of this structure, a handler registered for a certain
347             directive is called for opening directives as well as for closing
348             directives. To decide which case is true, a callback receives this
349             parameter. It's always one of the constants DIRECTIVE_START or
350             DIRECTIVE_COMPLETED.
351            
352             For simple strings (words, spaces etc.) and line number hints, the
353             callback will always (and only) be called with DIRECTIVE_START.
354            
355             =item directive values, if available
356            
357             Certain directives provide additional data such as the headline level or the
358             original documents name which are passed to their callbacks additionally.
359             See the following list:
360            
361             =over 4
362            
363             =item Documents
364            
365             transfer the I of the original ASCII document being parsed;
366            
367             =item Headlines
368            
369             transfer the headline level;
370            
371             =item Ordered list points
372            
373             optionally transfer a fix point number;
374            
375             =item Tags
376            
377             transfer the tag name ("I", "B" etc.).
378            
379             =back
380            
381             =back
382            
383             To express this by a prototype, all registered functions should have
384             an interface of "$$:@".
385            
386             B
387            
388             =over 4
389            
390             =item object
391            
392             a backend object as made by I;
393            
394             =item directive
395            
396             the directive this handler is registered for. See B for a
397             list of directives.
398            
399             =item handler
400            
401             the function to be called if a pointed directive is entered while the
402             I method walks through the document stream.
403            
404             =back
405            
406             B
407             no certain value;
408            
409             B
410            
411             $backend->register(DIRECTIVE_HEADLINE, \&handleHeadline);
412            
413             where handleHeadline could be something like
414            
415             sub handleDocument
416             {
417             my ($directive, $startStop, $level)=@_;
418             confess "Something is wrong\n"
419             unless $directive==DIRECTIVE_HEADLINE;
420             if ($startStop==DIRECTIVE_START)
421             {print "";}
422             else
423             {print "";}
424             }
425            
426             If I handler is registered, detected items will be ignored by default except
427             of I, which will be I by default.
428            
429             =cut
430             sub register
431             {
432             # get and check parameters
433 686     686 1 339436 ((my __PACKAGE__ $me), my ($directive, $handler))=@_;
434 686 50       1831 confess "[BUG] Missing object parameter.\n" unless $me;
435 686 50 33     3569 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
436 686 50       1311 confess "[BUG] Missing directive parameter.\n" unless defined $directive;
437 686 50       1624 confess "[BUG] Invalid directive parameter, use one of the directive constants.\n" unless $directive<=DIRECTIVE_SIMPLE;
438 686 50       2379 confess "[BUG] Missing handler parameter.\n" unless $handler;
439 686 50 33     3269 confess "[BUG] Handler parameter is no code reference.\n" unless ref($handler) and ref($handler) eq 'CODE';
440            
441             # check for an already existing handler
442 686 50 33     2620 warn "[Trace] Removing earlier handler setting (for directive $directive).\n" if $me->{trace} & TRACE_BACKEND and exists $me->{handler}{$directive};
443            
444             # well, all right, store the handler
445 686         2327 $me->{handler}{$directive}=$handler;
446 686 50       2822 warn "[Trace] Stored new handler (for directive $directive).\n" if $me->{trace} & TRACE_BACKEND;
447             }
448            
449             =pod
450            
451             =head2 mode()
452            
453             Switches the way an object inspects stream tokens. The new behaviour comes into action
454             with the I supplied token - either within I or by invokation of I.
455            
456             "Inspecting tokens" means how the object reads stream data to invoke registered handlers.
457            
458             B
459            
460             =over 4
461            
462             =item object
463            
464             An object as built by I.
465            
466             =item new mode
467            
468             All modes are declared by B constants in C (import
469             these constants by using the ":stream" tag).
470            
471             =over 4
472            
473             =item STREAM_TOKENS
474            
475             The default mode. All stream tokens are inspected which takes time but enables a complete
476             document processing.
477            
478             =item STREAM_HEADLINES
479            
480             In headline mode the object only inspects headlines, which means opening and closing
481             headline directives and everything between. Headline mode is less complete but obviously
482             faster because all tokens outside headlines are ignored and headlines usually claim only
483             a small percentage of a document. This mode is useful to get informed about the structure
484             of a document, to build tables of contents or the like.
485            
486             =back
487            
488             =back
489            
490             B
491            
492             the new mode.
493            
494             B
495            
496             $backend->mode(STREAM_HEADLINES);
497            
498             =cut
499             sub mode
500             {
501             # get parameters
502 41     41 1 265967 ((my __PACKAGE__ $me), my $mode)=@_;
503            
504             # and check parameters
505 41 50       204 confess "[BUG] Missing object parameter.\n" unless $me;
506 41 50 33     1232 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
507 41 50       139 confess "[BUG] Missing mode parameter.\n" unless $mode;
508 41 50 66     517 confess "[BUG] Invalid mode parameter $mode.\n" unless $mode eq STREAM_TOKENS or $mode eq STREAM_HEADLINES;
509            
510             # adapt internal data as necessary
511 41 100 66     514 unless (defined $me->{data})
    100 33        
    50          
    0          
512             {
513             # there is no stream associated with the object yet,
514             # so we do not have to set its index values
515             }
516             elsif ($me->{stream}==STREAM_TOKENS and $mode==STREAM_HEADLINES)
517             {
518             # Switching from token to headline handling, we have to
519             # update the headline index - we have to find the current
520             # headline entry. This is easy because this must be the
521             # last headline entry containing a token number lower than
522             # (or equal to) the current one.
523 38         472 $me->{streamControl}{headlineIndex}++
524 38   66     126 while $me->{streamControl}{headlineIndex} < $#{$me->{data}[STREAM_HEADLINES]}
525             and $me->{data}[STREAM_HEADLINES][$me->{streamControl}{headlineIndex}+1]
526             <= $me->{streamControl}{tokenIndex};
527             }
528             elsif ($me->{stream}==STREAM_HEADLINES and $mode==STREAM_TOKENS)
529             {
530             # switching from headline to token handling - no index
531             # has to be adapted because the token index keeps always
532             # up to date in headline mode
533             }
534             elsif ($me->{stream}==$mode)
535             {
536             # nothing to adapt
537             }
538             else
539             {
540             # oops
541 0         0 die "[BUG] Unhandled case.";
542             }
543            
544             # store new mode
545 41         276 $me->{stream}=$mode;
546             }
547            
548             =pod
549            
550             =head2 run()
551            
552             The stream processor. The method walks through the data stream and inspects its tokens according
553             to the current mode (see I) (which may be changed on the way). For each token, C
554             detects the appropriate type and checks if there is a callback registered for this type (see
555             C). If so, the callback is invoked to handle the token. If no handler is registered,
556             the token will be ignored except in the case of simple tokens, which will be printed to C
557             by default.
558            
559             If all (mode according) stream data are handled finishs.
560            
561             The model of this method is to perform stream data processing by an enclosing loop which is
562             in control and knows of callbacks to handle "events" (occurences of certainly typed data).
563             There is an alternative model using I to give the I control of when to process
564             the next token.
565            
566             B
567            
568             =over 4
569            
570             =item object
571            
572             An object as built by I.
573            
574             =item stream data
575            
576             A reference to the stream data produced by a C call. Stream data are not
577             stored in an object (yet?), but nevertheless nothing but a data structure as supplied by the
578             parser will be accepted.
579            
580             =back
581            
582             B
583            
584             nothing specific.
585            
586             B
587            
588             $backend->run($streamData);
589            
590             =cut
591             sub run
592             {
593             # get parameters
594 45     45 1 2603 ((my __PACKAGE__ $me), my $stream)=@_;
595            
596             # and check them
597 45 50       197 confess "[BUG] Missing object parameter.\n" unless $me;
598 45 50 33     864 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
599 45 50       176 confess "[BUG] Missing stream parameter.\n" unless $stream;
600 45 50 33     735 confess "[BUG] Stream parameter is no PerlPoint stream data structure.\n" unless ref($stream) and ref($stream) eq 'ARRAY' and $stream->[STREAM_IDENT] eq '__PerlPoint_stream__';
      33        
601            
602             # welcome user
603 45 50       352 warn "[Info] Perl Point backend \"$me->{name}\" starts.\n" unless $me->{display} & DISPLAY_NOINFO;
604            
605             # declare variables
606 45         454 my ($started)=(time);
607            
608             # init counter
609 45         287 $me->{statistics}{&DIRECTIVE_HEADLINE}=0;
610            
611             # bind to the stream
612 45         221 $me->bind($stream);
613            
614             # now start your walk
615 45 100       130 while ($me->{streamControl}{tokenIndex} < $#{$stream->[STREAM_TOKENS]})
  3047         8067  
  3004         6883  
616             {last unless $me->_next($stream);}
617            
618             # we are done with this stream for now
619 45         245 $me->unbind;
620            
621             # inform user, if necessary
622 45 0       380 warn(
    50          
623             ($me->{vis} ? "\n" : ''), " Stream processed in ", time-$started, " seconds.\n\n",
624             "[Info] Backend \"$me->{name}\" is ready.\n\n"
625             ) unless $me->{display} & DISPLAY_NOINFO;
626             }
627            
628            
629             =pod
630            
631             =head2 next()
632            
633             This is an alternative stream data processing method to I. While I processes
634             all data completely, C handles exactly I token. The most important difference
635             of these two approaches is that with C a caller is in full control of what happens.
636             This enables to move freely between chapters, to switch modes or to abort processing dependend
637             on current needs which might be expressed by a users input. In fact, C was introduced
638             to enable the implementation of projectors working on base of the token stream data directly.
639            
640             Processing a I works equally to I by type detection and handler invokation,
641             see there for details.
642            
643             Please note that different to I a stream must be bound to a backend object before using
644             C. This is necessary to store processing states between various C calls and is
645             done by I. After processing all data, I may be used to detach the stream.
646            
647             To avoid confusion, C cannot be called from a callback invoked by I. In other
648             words, both approaches cannot be mixed.
649            
650             B
651            
652             =over 4
653            
654             =item object
655            
656             An object as built by I.
657            
658             =back
659            
660             B
661            
662             A true value if there is more to process, a false value otherwise. It is up to the caller
663             to handle these cases appropriately.
664            
665             B
666            
667             # This example emulates run() by next().
668             $backend->bind($streamData);
669             {redo while $backend->next;}
670             $backend->unbind;
671            
672             =cut
673             sub next
674             {
675             # get parameters
676 102     102 1 807 (my __PACKAGE__ $me)=@_;
677            
678             # and check them
679 102 50       399 confess "[BUG] Missing object parameter.\n" unless $me;
680 102 50 33     2633 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
681            
682             # data already provided?
683 102 50       328 confess "[BUG] Please use bind() first to associate data.\n" unless defined $me->{data};
684            
685             # perform next step, supply the "there may be more" result code
686             # so a user can check it (and call unbind() if he prefers)
687 102         281 $me->_next($me->{data});
688             }
689            
690             # intended for internal use - walk one step in stream
691             sub _next
692             {
693             # get parameters (do not check them for reasons of performance - this function
694             # is intended to be called internally *only* (quite often))
695 3661     3661   5456 ((my __PACKAGE__ $me), my $stream)=@_;
696            
697             # flag that we are invoked
698 3661         6142 $me->{flags}{_nextInvokation}++;
699            
700             # check invokation level
701 3661 50       11946 confess "[BUG] Method next() was called from a backend callback.\n" if $me->{flags}{_nextInvokation}>1;
702            
703             {
704             # declare variables
705 3661         4351 my ($token)=(0);
  3661         5006  
706            
707             # update counters
708 3661 100 66     13525 if (
    50 66        
709             $me->{stream}==STREAM_TOKENS
710             or ($me->{stream}==STREAM_HEADLINES and $me->{processingHeadline})
711             )
712             {
713             # we might have handled all tokens
714 3478         9756 $me->{flags}{_nextInvokation}--, return 0
715 3478 100       5436 if $me->{streamControl}{tokenIndex}==$#{$stream->[STREAM_TOKENS]};
716            
717             # update token index (headline index is handled later)
718 3475         7462 $me->{streamControl}{tokenIndex}++;
719             }
720             elsif ($me->{stream}==STREAM_HEADLINES)
721             {
722             # we might have handled all headlines
723 183         834 $me->{flags}{_nextInvokation}--, return 0
724 183 100       322 if $me->{streamControl}{headlineIndex}==$#{$stream->[STREAM_HEADLINES]};
725            
726             # update headline index
727 147         295 $me->{streamControl}{headlineIndex}++;
728            
729             # update token index
730 147         357 $me->{streamControl}{tokenIndex}=$stream->[STREAM_HEADLINES][$me->{streamControl}{headlineIndex}];
731             }
732             else
733             {
734             # oops!
735 0         0 die "[BUG] Unhandled case.\n";
736             }
737            
738             # get token
739 3622         8604 $token=$stream->[STREAM_TOKENS][$me->{streamControl}{tokenIndex}];
740            
741             # should this token be skipped?
742 3622 50 33     9498 if ($me->{hide} or @{$me->{ignoredDirectives}})
  3622         14187  
743             {
744             # Directive? This could finish skipping.
745 0 0       0 if (ref($token))
746             {
747             # Is this the finishing token? (Note that the final token is skipped as well.)
748             # Check "hide all" before "ignore certain tokens" because the first is of higher precedence.
749 0 0 0     0 $me->{hide}=0, redo if $me->{hide} and $token->[STREAM_DIR_HINTS]{nr}==$me->{hide};
750 0 0 0     0 pop(@{$me->{ignoredDirectives}}), redo if @{$me->{ignoredDirectives}} and $token->[STREAM_DIR_HINTS]{nr}==$me->{ignoredDirectives}[-1];
  0         0  
  0         0  
751             }
752            
753             # whatever token this is, it has to be hidden in hiding mode
754 0 0       0 redo if $me->{hide};
755             }
756            
757             # check token type
758 3622 100       7326 unless (ref($token))
759             {
760             # trace, if necessary
761 1792 50       4152 warn "[Trace] Token $me->{streamControl}{tokenIndex} is a simple string.\n" if $me->{trace} & TRACE_BACKEND;
762            
763             # dummy tokens are ignored, all other tokens are processed
764 1792 100       3913 unless ($token eq DUMMY_TOKEN)
765             {
766             # now check if there was a handler declared
767 1789 50       4586 if (exists $me->{handler}{DIRECTIVE_SIMPLE()})
768             {
769             # trace, if necessary
770 1789 50       5948 warn "[Trace] Using user defined handler.\n" if $me->{trace} & TRACE_BACKEND;
771            
772             # call the handler passing the string
773 1789 50       3489 &{$me->{handler}{DIRECTIVE_SIMPLE()}}($me->{generator} ? $me->{generator} : (), DIRECTIVE_SIMPLE, DIRECTIVE_START, $token);
  1789         5066  
774             }
775             else
776             {
777             # trace, if necessary
778 0 0       0 warn "[Trace] Using default handler.\n" if $me->{trace} & TRACE_BACKEND;
779            
780             # well, the default is to just print it out
781 0         0 print $token;
782             }
783             }
784             }
785             else
786             {
787             # trace, if necessary
788 1830 50       4431 warn "[Trace] Token $me->{streamControl}{tokenIndex} is a directive (", $token->[STREAM_DIR_TYPE], ").\n" if $me->{trace} & TRACE_BACKEND;
789            
790             # process parser hints, if any
791 1830 50       4912 push(@{$me->{ignoredDirectives}}, $token->[STREAM_DIR_HINTS]{nr}), redo
  0         0  
792             if exists $token->[STREAM_DIR_HINTS]{ignore};
793 1830 50       4227 $me->{hide}=$token->[STREAM_DIR_HINTS]{nr}, redo
794             if exists $token->[STREAM_DIR_HINTS]{hide};
795            
796             # headline?
797 1830 100       4961 if ($token->[STREAM_DIR_TYPE]==DIRECTIVE_HEADLINE)
798             {
799 492 100       1024 if ($token->[STREAM_DIR_STATE]==DIRECTIVE_START)
800             {
801             # update headline index, if necessary
802 250 100       756 $me->{streamControl}{headlineIndex}++ if $me->{stream}==STREAM_TOKENS;
803            
804             # update "statistics"
805 250 50       1033 $me->{statistics}{&DIRECTIVE_HEADLINE}++ if $token->[STREAM_DIR_TYPE]==DIRECTIVE_HEADLINE;
806            
807             # let the user know that something is going on
808 250 50 33     886 print STDERR "\r", ' ' x length('[Info] '), '... ', $me->{statistics}{&DIRECTIVE_HEADLINE}, " chapters processed."
809             if $me->{vis} and not $me->{statistics}{&DIRECTIVE_HEADLINE} % $me->{vis};
810            
811             # update headline flag
812 250         454 $me->{processingHeadline}=1;
813             }
814             else
815             {
816             # update headline flag
817 242         560 $me->{processingHeadline}=0;
818             }
819             }
820            
821             # call the general handler, if any
822 1830 0       4644 &{$me->{handler}{DIRECTIVE_EVERY()}}($me->{generator} ? $me->{generator} : (), @{$token}[1..$#{$token}]) if exists $me->{handler}{DIRECTIVE_EVERY()};
  0 50       0  
  0         0  
  0         0  
823            
824             # now check if there was a handler declared
825 1830 100       4449 if (exists $me->{handler}{$token->[STREAM_DIR_TYPE]})
826             {
827             # trace, if necessary
828 1764 50       4305 warn "[Trace] Using user defined handler.\n" if $me->{trace} & TRACE_BACKEND;
829            
830             # call the handler passing additional informations, if any
831 1764 50       3793 &{$me->{handler}{$token->[STREAM_DIR_TYPE]}}($me->{generator} ? $me->{generator} : (), @{$token}[1..$#{$token}]);
  1764         38910  
  1764         2845  
  1764         4249  
832             }
833             else
834             {
835             # trace, if necessary
836 66 50       217 warn "[Trace] Acting by default (ignoring token).\n" if $me->{trace} & TRACE_BACKEND;
837            
838             # well, the default is to ignore it
839             }
840             }
841             }
842            
843             # update invokation level
844 3622         24552 $me->{flags}{_nextInvokation}--;
845            
846             # flag that there's still more to process probably
847 3622         12297 1;
848             }
849            
850             =pod
851            
852             =head2 bind()
853            
854             Binds a stream data structure to a backend object. If I is used to process a stream,
855             there is no need to use C because it is called by C implicitly.
856            
857             If there was already a stream connected to the backend object, the new connection will replace
858             the old one.
859            
860             Binding a stream I stream processing (see I). I
861             from a handler unless you know exactly what is going on.>
862            
863             B
864            
865             =over 4
866            
867             =item object
868            
869             An object as built by I.
870            
871             =item stream data
872            
873             A reference to the stream data produced by a C call. Stream data are not
874             stored in an object (yet?), but nevertheless nothing but a data structure as supplied by the
875             parser will be accepted.
876            
877             =back
878            
879             B
880            
881             nothing significant.
882            
883             B
884            
885             $backend->bind($streamData);
886            
887             =cut
888             sub bind
889             {
890             # get parameters
891 123     123 1 584264 ((my __PACKAGE__ $me), my $stream)=@_;
892            
893             # and check them
894 123 50       374 confess "[BUG] Missing object parameter.\n" unless $me;
895 123 50 33     1000 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
896 123 50       333 confess "[BUG] Missing stream parameter.\n" unless $stream;
897 123 50 33     1806 confess "[BUG] Stream parameter is no PerlPoint stream data structure.\n" unless ref($stream) and ref($stream) eq 'ARRAY' and $stream->[STREAM_IDENT] eq '__PerlPoint_stream__';
      33        
898            
899             # store data reference to make it accessible by other methods
900 123         367 $me->{data}=$stream;
901            
902             # reset stream processing
903 123         594 $me->reset;
904             }
905            
906             =pod
907            
908             =head2 unbind()
909            
910             Detaches a stream data structure bound to the backend object.
911            
912             Unbinding a stream I stream processing (see I) - if the stream is rebound
913             to the object and furtherly processed, it will be processed from its beginning.
914            
915             I
916            
917             B
918            
919             =over 4
920            
921             =item object
922            
923             An object as built by I.
924            
925             =back
926            
927             B
928            
929             nothing significant.
930            
931             B
932            
933             $backend->unbind();
934            
935             =cut
936             sub unbind
937             {
938             # get parameters
939 48     48 1 138 (my __PACKAGE__ $me)=@_;
940            
941             # and check them
942 48 50       312 confess "[BUG] Missing object parameter.\n" unless $me;
943 48 50 33     688 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
944            
945             # reset stream processing, detach data
946 48         185 $me->reset;
947 48         160 $me->{data}=$me->{streamControl}=undef;
948             }
949            
950             # METHODS INTENDED TO BE CALLED FROM HANDLERS. ################################################
951            
952             =pod
953            
954             =head2 reset()
955            
956             Resets processing of a stream associated with (or bound to) the backend object. This means
957             that further processing will start with the very first token matching the current mode (see
958             I).
959            
960             B
961            
962             =over 4
963            
964             =item object
965            
966             An object as built by I.
967            
968             =back
969            
970             B
971            
972             nothing significant.
973            
974             B
975            
976             $backend->reset;
977            
978             =cut
979             sub reset
980             {
981             # get parameters
982 171     171 1 290 (my __PACKAGE__ $me)=@_;
983            
984             # and check them
985 171 50       472 confess "[BUG] Missing object parameter.\n" unless $me;
986 171 50 33     1721 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
987            
988             # reset stream, if necessary
989 171 50       713 @{$me->{streamControl}}{qw(tokenIndex headlineIndex)}=(-1, -1) if defined $me->{data};
  171         1025  
990             }
991            
992            
993             =pod
994            
995             =head2 move2chapter()
996            
997             Causes stream processing to continue with a certain chapter.
998            
999             B
1000            
1001             =over 4
1002            
1003             =item object
1004            
1005             An object as built by I.
1006            
1007             =item chapter
1008            
1009             The number of the target chapter to process next. This is an I number - the first
1010             headline is headline B<1>, the second B<2> etc., regardless of headline hierachies. The highest
1011             valid number is equal to the result of I.
1012            
1013             =back
1014            
1015             B
1016            
1017             nothing significant.
1018            
1019             B
1020            
1021             $backend->move2chapter(15);
1022            
1023             =cut
1024             sub move2chapter
1025             {
1026             # get parameters
1027 57     57 1 199 ((my __PACKAGE__ $me), my $chapter)=@_;
1028            
1029             # and check them
1030 57 50       180 confess "[BUG] Missing object parameter.\n" unless $me;
1031 57 50 33     516 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1032 57 50       187 confess "[BUG] There is no stream associated to this backend object yet, use bind() or run().\n" unless defined $me->{data};
1033 57 50       160 confess "[BUG] Missing chapter parameter.\n" unless $chapter;
1034 57 50       747 confess "[BUG] Chapter parameter \"$chapter\" is no (valid) number.\n" unless $chapter=~/^\d+$/;
1035 57 50 33     309 confess "[BUG] Chapter parameter \"$chapter\" exceeds chapter range.\n" unless $chapter>0 and $chapter<=@{$me->{data}[STREAM_HEADLINES]};
  57         315  
1036            
1037             # reset headline flag (if we are currently processing a headline)
1038 57         133 $me->{processingHeadline}=0;
1039            
1040             # go to the headline stream entry right before the wished one (run() will increment
1041             # first assuming it processed straight forward) - note that for reasons of convenience,
1042             # we allow the user to provide a chapter *number* (beginning with 1), while we have to
1043             # use an index (beginning with 0), so the final decreasing value is 2
1044 57         547 $me->{streamControl}{headlineIndex}=$chapter-2;
1045            
1046             # go to the last token *before* the new chapter
1047 57         218 $me->{streamControl}{tokenIndex}=$me->{data}[STREAM_HEADLINES][$chapter-1]-1;
1048             }
1049            
1050            
1051            
1052             =pod
1053            
1054             =head2 headlineNr()
1055            
1056             Replies the number of headlines in the stream associated with the object. If no stream is
1057             associated, an undefined value is supplied.
1058            
1059             B
1060            
1061             =over 4
1062            
1063             =item object
1064            
1065             An object as built by I.
1066            
1067             =back
1068            
1069             B
1070            
1071             The number of headlines in the stream if a stream is associated, an undefined value otherwise.
1072            
1073             B
1074            
1075             $backend->headlineNr;
1076            
1077             =cut
1078             sub headlineNr
1079             {
1080             # get parameters
1081 1     1 1 6 (my __PACKAGE__ $me)=@_;
1082            
1083             # and check them
1084 1 50       5 confess "[BUG] Missing object parameter.\n" unless $me;
1085 1 50 33     9 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1086            
1087             # provide number of headlines, if possible
1088 1 50       4 defined $me->{data} ? scalar(@{$me->{data}[STREAM_HEADLINES]}) : undef;
  1         18  
1089             }
1090            
1091            
1092             =pod
1093            
1094             =head2 headlineIds2Data()
1095            
1096            
1097             B
1098            
1099             =over 4
1100            
1101             =item object
1102            
1103             An object as built by I.
1104            
1105             =item list of headline ids
1106            
1107             A list of ids. An id is an I headline number, starting with 1.
1108            
1109             =back
1110            
1111             B
1112            
1113             The number of headlines in the stream if a stream is associated, an undefined value otherwise.
1114            
1115             B
1116            
1117             $backend->headlineIds2Data;
1118            
1119             =cut
1120             sub headlineIds2Data
1121             {
1122             # get parameters
1123 0     0 1 0 ((my __PACKAGE__ $me), my $ids)=@_;
1124            
1125             # and check them
1126 0 0       0 confess "[BUG] Missing object parameter.\n" unless $me;
1127 0 0 0     0 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1128 0 0       0 confess "[BUG] Missing headline id parameter.\n" unless $ids;
1129 0 0 0     0 confess "[BUG] Headline id parameter is no array reference.\n" unless ref $ids and ref $ids eq 'ARRAY';
1130            
1131             # data already provided?
1132 0 0       0 confess "[BUG] Please use bind() first to associate data.\n" unless defined $me->{data};
1133            
1134             # declare variables
1135 0         0 my (@results);
1136            
1137             # handle all ids
1138 0         0 foreach my $id (@$ids)
1139             {
1140             # check id
1141 0 0 0     0 confess qq([BUG] Invalid id "$id".\n) unless $id=~/^\d+$/ and $id>0 and $id<=@{$me->{data}[STREAM_HEADLINES]};
  0   0     0  
1142            
1143             # get data
1144 0         0 push(@results, $me->{data}[STREAM_TOKENS][$me->{data}[STREAM_HEADLINES][$id-1]]);
1145             }
1146            
1147             # supply results
1148 0         0 \@results;
1149             }
1150            
1151            
1152             =pod
1153            
1154             =head2 currentChapterNr()
1155            
1156             Replies the number of the currently processed chapter - in the stream associated with the object.
1157             If no stream is associated, an undefined value is supplied.
1158            
1159             B
1160            
1161             =over 4
1162            
1163             =item object
1164            
1165             An object as built by I.
1166            
1167             =back
1168            
1169             B
1170            
1171             The number of the currently handled headline in the stream if a stream is associated, an
1172             undefined value otherwise.
1173            
1174             B
1175            
1176             $backend->currentChapterNr;
1177            
1178             =cut
1179             sub currentChapterNr
1180             {
1181             # get parameters
1182 6     6 1 7 (my __PACKAGE__ $me)=@_;
1183            
1184             # and check them
1185 6 50       16 confess "[BUG] Missing object parameter.\n" unless $me;
1186 6 50 33     37 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1187            
1188             # provide number of headlines, if possible
1189             # (provide an incremented number for reasons of convenience)
1190 6 50       25 defined $me->{data} ? $me->{streamControl}{headlineIndex}+1 : undef;
1191             }
1192            
1193            
1194             =pod
1195            
1196             =head2 toc()
1197            
1198             This method provides a convenient way to get a list of subchapters related
1199             to a certain "parent" chapter. More, it can be used to get a complete table of
1200             contents as well. Each subchapter is presented by its headline (hierarchy)
1201             level and its title in plain text.
1202            
1203             B
1204            
1205             =over 4
1206            
1207             =item object
1208            
1209             An object as built by I.
1210            
1211             =item chapter of interest
1212            
1213             This is an absolute number as used in various other methods as well. The first
1214             headline in the document is number 1, the next headline number 2 and so on.
1215             (The number of the chapter currently processed is always provided by
1216             I.)
1217            
1218             If this parameter is omitted or 0, the whole documents hierarchy will be reported.
1219            
1220             =item result depth
1221            
1222             There may be a deep hierarchy of subchapters. If only a certain depth is of
1223             interest, supply it here. If this parameter is omitted or set to 0, I
1224             subchapters will be reported.
1225            
1226             =back
1227            
1228             B
1229            
1230             a reference to an array of arrays, where each entry describes a subchapter by
1231             its headline level and its title (as plain text - tags etc. are stripped off).
1232            
1233             B
1234            
1235             $subchapters=$backend->toc(5, 2);
1236            
1237             =cut
1238             sub toc
1239             {
1240             # get parameters
1241 41     41 1 2362 ((my __PACKAGE__ $me), my ($start, $depth))=@_;
1242            
1243             # and check them
1244 41 50       178 confess "[BUG] Missing object parameter.\n" unless $me;
1245 41 50 33     467 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1246 41 50       257 confess "[BUG] There is no stream associated to this backend object yet, use bind() or run().\n" unless defined $me->{data};
1247 41 50 66     234 confess "[BUG] Start parameter \"$start\" is no (valid) number.\n" if defined $start and $start!~/^\d+$/;
1248 41 50 66     226 confess "[BUG] Start parameter \"$start\" exceeds chapter range.\n" if defined $start and $start>@{$me->{data}[STREAM_HEADLINES]};
  4         29  
1249 41 50 66     213 confess "[BUG] Depth parameter \"$depth\" is no (valid) number.\n" if $depth and $depth!~/^\d+$/;
1250            
1251             # by default, we process the complete document
1252 41 100       200 $start=0 unless $start;
1253            
1254             # anything to do?
1255 41         802 return [] unless @{$me->{data}[STREAM_HEADLINES]}
  36         670  
1256 41 100 66     141 and $start{data}[STREAM_HEADLINES]});
1257            
1258             # declare variables
1259 36         292 my ($c, $completed, $results)=(-1, 0, []);
1260            
1261             # get startup headline level
1262 36 100       148 my $startupLevel=$start ? $me->{data}[STREAM_TOKENS][$me->{data}[STREAM_HEADLINES][$start-1]][3] : 0;
1263            
1264             # make a simple helper object
1265 36         169 my $helper=new(
1266             __PACKAGE__,
1267             name => 'helper backend',
1268             display => DISPLAY_NOINFO+DISPLAY_NOWARN,
1269             trace => TRACE_NOTHING,
1270             );
1271            
1272             # register headline handler
1273             $helper->register(DIRECTIVE_HEADLINE,
1274             sub
1275             {
1276             # get parameters
1277 278     278   478 my ($opcode, $mode, $level)=@_;
1278            
1279             # act mode dependend
1280 278 100       944 if ($mode==DIRECTIVE_START)
1281             {
1282             # check headline level
1283 143 100 100     721 if ($level<=$startupLevel)
    100          
1284             {
1285             # task completed, stop handling
1286 2         5 $completed=1;
1287             }
1288             elsif ($depth and $level>$startupLevel+$depth)
1289             {
1290             # immediately jump to the next chapter, if any
1291 6         17 my $ccn=$helper->currentChapterNr;
1292 6 50       9 if ($ccn==@{$me->{data}[STREAM_HEADLINES]})
  6         19  
  0         0  
1293 6         16 {$completed=1;}
1294             else
1295             {$helper->move2chapter($ccn+1);}
1296             }
1297             else
1298             {
1299             # increment buffer index, store headline level
1300 135         491 $results->[++$c][0]=$level;
1301             }
1302             }
1303             },
1304 36         723 );
1305            
1306             # register plain text handler to get the headlines text
1307             $helper->register(DIRECTIVE_SIMPLE,
1308             sub
1309             {
1310             # get parameters
1311 185     185   392 my ($opcode, $mode, @contents)=@_;
1312            
1313             # update headline string (use of .= operator avoids warnings)
1314 185         901 $results->[$c][1].=join('', @contents)
1315             }
1316 36         809 );
1317            
1318             # switch helper object into headline mode, move behind the startup
1319             # headline and run it (it will stop automatically when it will have
1320             # been handled all subchapters)
1321 36         137 $helper->bind($me->{data});
1322 36         358 $helper->mode(STREAM_HEADLINES);
1323 36         228 $helper->move2chapter($start+1);
1324 36   100     57 {redo while not $completed and $helper->_next($helper->{data});}
  557         2185  
1325            
1326             # supply result
1327 36         1209 $results;
1328             }
1329            
1330            
1331             =pod
1332            
1333             =head2 docstreams()
1334            
1335             Supplies the names of all document streams in the data stream.
1336             A data streams needs to be bound to the object.
1337            
1338             B
1339            
1340             =over 4
1341            
1342             =item object
1343            
1344             An object as built by I.
1345            
1346             =back
1347            
1348             B
1349            
1350             A list of document stream titles in list context, the number of document
1351             streams in scalar context.
1352            
1353             B
1354            
1355             @docstreams=$backend->docstreams;
1356            
1357             =cut
1358             sub docstreams
1359             {
1360             # get parameters
1361 1     1 1 6 (my __PACKAGE__ $me)=@_;
1362            
1363             # and check them
1364 1 50       5 confess "[BUG] Missing object parameter.\n" unless $me;
1365 1 50 33     13 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and ref $me eq __PACKAGE__;
1366 1 50       5 confess "[BUG] There is no stream associated to this backend object yet, use bind() or run().\n" unless defined $me->{data};
1367            
1368             # build an array of docstream titles
1369 1         1 my @docstreams=keys %{$me->{data}[STREAM_DOCSTREAMS]};
  1         5  
1370            
1371             # supply result as wished
1372 1 50       11 wantarray ? @docstreams : scalar(@docstreams);
1373             }
1374            
1375            
1376             1;
1377            
1378            
1379             # = POD TRAILER SECTION =================================================================
1380            
1381             =pod
1382            
1383             =head1 SEE ALSO
1384            
1385             =over 4
1386            
1387             =item B
1388            
1389             A parser for Perl Point ASCII texts.
1390            
1391             =item B
1392            
1393             Public PerlPoint::... module constants.
1394            
1395             =back
1396            
1397            
1398             =head1 SUPPORT
1399            
1400             A PerlPoint mailing list is set up to discuss usage, ideas,
1401             bugs, suggestions and translator development. To subscribe,
1402             please send an empty message to perlpoint-subscribe@perl.org.
1403            
1404             If you prefer, you can contact me via perl@jochen-stenzel.de
1405             as well.
1406            
1407             =head1 AUTHOR
1408            
1409             Copyright (c) Jochen Stenzel (perl@jochen-stenzel.de), 1999-2002.
1410             All rights reserved.
1411            
1412             This module is free software, you can redistribute it and/or modify it
1413             under the terms of the Artistic License distributed with Perl version
1414             5.003 or (at your option) any later version. Please refer to the
1415             Artistic License that came with your Perl distribution for more
1416             details.
1417            
1418             The Artistic License should have been included in your distribution of
1419             Perl. It resides in the file named "Artistic" at the top-level of the
1420             Perl source tree (where Perl was downloaded/unpacked - ask your
1421             system administrator if you dont know where this is). Alternatively,
1422             the current version of the Artistic License distributed with Perl can
1423             be viewed on-line on the World-Wide Web (WWW) from the following URL:
1424             http://www.perl.com/perl/misc/Artistic.html
1425            
1426            
1427             =head1 DISCLAIMER
1428            
1429             This software is distributed in the hope that it will be useful, but
1430             is provided "AS IS" WITHOUT WARRANTY OF ANY KIND, either expressed or
1431             implied, INCLUDING, without limitation, the implied warranties of
1432             MERCHANTABILITY and FITNESS FOR A PARTICULAR PURPOSE.
1433            
1434             The ENTIRE RISK as to the quality and performance of the software
1435             IS WITH YOU (the holder of the software). Should the software prove
1436             defective, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
1437             CORRECTION.
1438            
1439             IN NO EVENT WILL ANY COPYRIGHT HOLDER OR ANY OTHER PARTY WHO MAY CREATE,
1440             MODIFY, OR DISTRIBUTE THE SOFTWARE BE LIABLE OR RESPONSIBLE TO YOU OR TO
1441             ANY OTHER ENTITY FOR ANY KIND OF DAMAGES (no matter how awful - not even
1442             if they arise from known or unknown flaws in the software).
1443            
1444             Please refer to the Artistic License that came with your Perl
1445             distribution for more details.
1446            
1447             =cut