summaryrefslogtreecommitdiff
path: root/examples/includes/HTML-Toc-0.91/TocInsertor.pm
diff options
context:
space:
mode:
Diffstat (limited to 'examples/includes/HTML-Toc-0.91/TocInsertor.pm')
-rw-r--r--examples/includes/HTML-Toc-0.91/TocInsertor.pm1066
1 files changed, 1066 insertions, 0 deletions
diff --git a/examples/includes/HTML-Toc-0.91/TocInsertor.pm b/examples/includes/HTML-Toc-0.91/TocInsertor.pm
new file mode 100644
index 000000000..b554870cc
--- /dev/null
+++ b/examples/includes/HTML-Toc-0.91/TocInsertor.pm
@@ -0,0 +1,1066 @@
+#--- TocInsertor.pm -----------------------------------------------------------
+# function: Insert Table of Contents HTML::Toc, generated by
+# HTML::TocGenerator.
+# note: - The term 'propagate' is used as a shortcut for the process of
+# both generating and inserting a ToC at the same time.
+# - 'TIP' is an abbreviation of 'Toc Insertion Point'.
+
+
+package HTML::TocInsertor;
+
+
+use strict;
+use FileHandle;
+use HTML::TocGenerator;
+
+
+BEGIN {
+ use vars qw(@ISA $VERSION);
+
+ $VERSION = '0.91';
+
+ @ISA = qw(HTML::TocGenerator);
+}
+
+ # TocInsertionPoint (TIP) constants
+
+use constant TIP_PREPOSITION_REPLACE => 'replace';
+use constant TIP_PREPOSITION_BEFORE => 'before';
+use constant TIP_PREPOSITION_AFTER => 'after';
+
+use constant TIP_TOKEN_ID => 0;
+use constant TIP_PREPOSITION => 1;
+use constant TIP_INCLUDE_ATTRIBUTES => 2;
+use constant TIP_EXCLUDE_ATTRIBUTES => 3;
+use constant TIP_TOC => 4;
+
+use constant MODE_DO_NOTHING => 0; # 0b00
+use constant MODE_DO_INSERT => 1; # 0b01
+use constant MODE_DO_PROPAGATE => 3; # 0b11
+
+END {}
+
+
+#--- HTML::TocInsertor::new() -------------------------------------------------
+# function: Constructor.
+
+sub new {
+ # Get arguments
+ my ($aType) = @_;
+ my $self = $aType->SUPER::new;
+ # TRUE if insertion point token must be output, FALSE if not
+ $self->{_doOutputInsertionPointToken} = 1;
+ # Reset batch variables
+ $self->_resetBatchVariables;
+ # Bias to not insert ToC
+ $self->{hti__Mode} = MODE_DO_NOTHING;
+
+ # TODO: Initialize output
+
+ return $self;
+} # new()
+
+
+#--- HTML::TocInsertor::_deinitializeOutput() ---------------------------------
+# function: Deinitialize output.
+
+sub _deinitializeOutput {
+ # Get arguments
+ my ($self) = @_;
+ # Filehandle is defined?
+ if (defined($self->{_outputFileHandle})) {
+ # Yes, filehandle is defined;
+ # Restore selected filehandle
+ select($self->{_oldFileHandle});
+ # Undefine filehandle, closing it automatically
+ undef $self->{_outputFileHandle};
+ }
+} # _deinitializeOutput()
+
+
+#--- HTML::TocInsertor::_initializeOutput() -----------------------------------
+# function: Initialize output.
+
+sub _initializeOutput {
+ # Get arguments
+ my ($self) = @_;
+ # Bias to write to outputfile
+ my $doOutputToFile = 1;
+
+ # Is output specified?
+ if (defined($self->{options}{'output'})) {
+ # Yes, output is specified;
+ # Indicate to not output to outputfile
+ $doOutputToFile = 0;
+ # Alias output reference
+ $self->{_output} = $self->{options}{'output'};
+ # Clear output
+ ${$self->{_output}} = "";
+ }
+
+ # Is output file specified?
+ if (defined($self->{options}{'outputFile'})) {
+ # Yes, output file is specified;
+ # Indicate to output to outputfile
+ $doOutputToFile = 1;
+ # Open file
+ $self->{_outputFileHandle} =
+ new FileHandle ">" . $self->{options}{'outputFile'};
+
+ # Backup currently selected filehandle
+ $self->{_oldFileHandle} = select;
+ # Set new default filehandle
+ select($self->{_outputFileHandle});
+ }
+
+ # Alias output-to-file indicator
+ $self->{_doOutputToFile} = $doOutputToFile;
+} # _initializeOutput()
+
+
+#--- HTML::TocInsertor::_deinitializeInsertorBatch() --------------------------
+# function: Deinitialize insertor batch.
+
+sub _deinitializeInsertorBatch {
+ # Get arguments
+ my ($self) = @_;
+ # Indicate ToC insertion has finished
+ $self->{_isTocInsertionPointPassed} = 0;
+ # Write buffered output
+ $self->_writeBufferedOutput();
+ # Propagate?
+ if ($self->{hti__Mode} == MODE_DO_PROPAGATE) {
+ # Yes, propagate;
+ # Deinitialize generator batch
+ $self->_deinitializeGeneratorBatch();
+ }
+ else {
+ # No, insert only;
+ # Do general batch deinitialization
+ $self->_deinitializeBatch();
+ }
+ # Deinitialize output
+ $self->_deinitializeOutput();
+ # Indicate end of batch
+ $self->{hti__Mode} = MODE_DO_NOTHING;
+ # Reset batch variables
+ $self->_resetBatchVariables();
+} # _deinitializeInsertorBatch()
+
+
+#--- HTML::TocInsertor::_initializeInsertorBatch() ----------------------------
+# function: Initialize insertor batch.
+# args: - $aTocs: Reference to array of tocs.
+# - $aOptions: optional options
+
+sub _initializeInsertorBatch {
+ # Get arguments
+ my ($self, $aTocs, $aOptions) = @_;
+ # Add invocation options
+ $self->setOptions($aOptions);
+ # Option 'doGenerateToc' specified?
+ if (!defined($self->{options}{'doGenerateToc'})) {
+ # No, options 'doGenerateToc' not specified;
+ # Default to 'doGenerateToc'
+ $self->{options}{'doGenerateToc'} = 1;
+ }
+ # Propagate?
+ if ($self->{options}{'doGenerateToc'}) {
+ # Yes, propagate;
+ # Indicate mode
+ $self->{hti__Mode} = MODE_DO_PROPAGATE;
+ # Initialize generator batch
+ # NOTE: This method takes care of calling '_initializeBatch()'
+ $self->_initializeGeneratorBatch($aTocs);
+ }
+ else {
+ # No, insert;
+ # Indicate mode
+ $self->{hti__Mode} = MODE_DO_INSERT;
+ # Do general batch initialization
+ $self->_initializeBatch($aTocs);
+ }
+ # Initialize output
+ $self->_initializeOutput();
+ # Parse ToC insertion points
+ $self->_parseTocInsertionPoints();
+} # _initializeInsertorBatch()
+
+
+#--- HTML::TocInsertor::_insert() ---------------------------------------------
+# function: Insert ToC in string.
+# args: - $aString: Reference to string to parse.
+# note: Used internally.
+
+sub _insert {
+ # Get arguments
+ my ($self, $aString) = @_;
+ # Propagate?
+ if ($self->{options}{'doGenerateToc'}) {
+ # Yes, propagate;
+ # Generate & insert ToC
+ $self->_generate($aString);
+ }
+ else {
+ # No, just insert ToC
+ # Insert by parsing file
+ $self->parse($aString);
+ # Flush remaining buffered text
+ $self->eof();
+ }
+} # _insert()
+
+
+#--- HTML::TocInsertor::_insertIntoFile() -------------------------------------
+# function: Do insert generated ToCs in file.
+# args: - $aToc: (reference to array of) ToC object(s) to insert.
+# - $aFile: (reference to array of) file(s) to parse for insertion
+# points.
+# - $aOptions: optional insertor options
+# note: Used internally.
+
+sub _insertIntoFile {
+ # Get arguments
+ my ($self, $aFile) = @_;
+ # Local variables;
+ my ($file, @files);
+ # Dereference array reference or make array of file specification
+ @files = (ref($aFile) =~ m/ARRAY/) ? @$aFile : ($aFile);
+ # Loop through files
+ foreach $file (@files) {
+ # Propagate?
+ if ($self->{options}{'doGenerateToc'}) {
+ # Yes, propagate;
+ # Generate and insert ToC
+ $self->_generateFromFile($file);
+ }
+ else {
+ # No, just insert ToC
+ # Insert by parsing file
+ $self->parse_file($file);
+ }
+ }
+} # _insertIntoFile()
+
+
+#--- HTML::TocInsertor::_parseTocInsertionPoints() ----------------------------
+# function: Parse ToC insertion point specifier.
+
+sub _parseTocInsertionPoints {
+ # Get arguments
+ my ($self) = @_;
+ # Local variables
+ my ($tipPreposition, $tipToken, $toc, $tokenTipParser);
+ # Create parser for TIP tokens
+ $tokenTipParser = HTML::_TokenTipParser->new(
+ $self->{_tokensTip}
+ );
+ # Loop through ToCs
+ foreach $toc (@{$self->{_tocs}}) {
+ # Split TIP in preposition and token
+ ($tipPreposition, $tipToken) = split(
+ '\s+', $toc->{options}{'insertionPoint'}, 2
+ );
+ # Known preposition?
+ if (
+ ($tipPreposition ne TIP_PREPOSITION_REPLACE) &&
+ ($tipPreposition ne TIP_PREPOSITION_BEFORE) &&
+ ($tipPreposition ne TIP_PREPOSITION_AFTER)
+ ) {
+ # No, unknown preposition;
+ # Use default preposition
+ $tipPreposition = TIP_PREPOSITION_AFTER;
+ # Use entire 'insertionPoint' as token
+ $tipToken = $toc->{options}{'insertionPoint'};
+ }
+ # Indicate current ToC to parser
+ $tokenTipParser->setToc($toc);
+ # Indicate current preposition to parser
+ $tokenTipParser->setPreposition($tipPreposition);
+ # Parse ToC Insertion Point
+ $tokenTipParser->parse($tipToken);
+ # Flush remaining buffered text
+ $tokenTipParser->eof();
+ }
+} # _parseTocInsertionPoints()
+
+
+#--- HTML::TocInsertor::_processTokenAsInsertionPoint() -----------------------
+# function: Check for token being a ToC insertion point (Tip) token and
+# process it accordingly.
+# args: - $aTokenType: type of token: start, end, comment or text.
+# - $aTokenId: token id of currently parsed token
+# - $aTokenAttributes: attributes of currently parsed token
+# - $aOrigText: complete token
+# returns: 1 if successful -- token is processed as insertion point, 0
+# if not.
+
+sub _processTokenAsInsertionPoint {
+ # Get arguments
+ my ($self, $aTokenType, $aTokenId, $aTokenAttributes, $aOrigText) = @_;
+ # Local variables
+ my ($i, $result, $tipToken, $tipTokenId, $tipTokens);
+ # Bias to token not functioning as a ToC insertion point (Tip) token
+ $result = 0;
+ # Alias ToC insertion point (Tip) array of right type
+ $tipTokens = $self->{_tokensTip}[$aTokenType];
+ # Loop through tipTokens
+ $i = 0;
+ while ($i < scalar @{$tipTokens}) {
+ # Aliases
+ $tipToken = $tipTokens->[$i];
+ $tipTokenId = $tipToken->[TIP_TOKEN_ID];
+ # Id & attributes match?
+ if (
+ ($aTokenId =~ m/$tipTokenId/) && (
+ HTML::TocGenerator::_doesHashContainHash(
+ $aTokenAttributes, $tipToken->[TIP_INCLUDE_ATTRIBUTES], 0
+ ) &&
+ HTML::TocGenerator::_doesHashContainHash(
+ $aTokenAttributes, $tipToken->[TIP_EXCLUDE_ATTRIBUTES], 1
+ )
+ )
+ ) {
+ # Yes, id and attributes match;
+ # Process ToC insertion point
+ $self->_processTocInsertionPoint($tipToken);
+ # Indicate token functions as ToC insertion point
+ $result = 1;
+ # Remove Tip token, automatically advancing to next token
+ splice(@$tipTokens, $i, 1);
+ }
+ else {
+ # No, tag doesn't match ToC insertion point
+ # Advance to next start token
+ $i++;
+ }
+ }
+ # Token functions as ToC insertion point?
+ if ($result) {
+ # Yes, token functions as ToC insertion point;
+ # Process insertion point(s)
+ $self->_processTocInsertionPoints($aOrigText);
+ }
+ # Return value
+ return $result;
+} # _processTokenAsInsertionPoint()
+
+
+#--- HTML::TocInsertor::toc() -------------------------------------------------
+# function: Toc processing method. Add toc reference to scenario.
+# args: - $aScenario: Scenario to add ToC reference to.
+# - $aToc: Reference to ToC to insert.
+# note: The ToC hasn't been build yet; only a reference to the ToC to be
+# build is inserted.
+
+sub toc {
+ # Get arguments
+ my ($self, $aScenario, $aToc) = @_;
+ # Add toc to scenario
+ push(@$aScenario, $aToc);
+} # toc()
+
+
+#--- HTML::TocInsertor::_processTocInsertionPoint() ----------------------------
+# function: Process ToC insertion point.
+# args: - $aTipToken: Reference to token array item which matches the ToC
+# insertion point.
+
+sub _processTocInsertionPoint {
+ # Get arguments
+ my ($self, $aTipToken) = @_;
+ # Local variables
+ my ($tipToc, $tipPreposition);
+
+ # Aliases
+ $tipToc = $aTipToken->[TIP_TOC];
+ $tipPreposition = $aTipToken->[TIP_PREPOSITION];
+
+ SWITCH: {
+ # Replace token with ToC?
+ if ($tipPreposition eq TIP_PREPOSITION_REPLACE) {
+ # Yes, replace token;
+ # Indicate ToC insertion point has been passed
+ $self->{_isTocInsertionPointPassed} = 1;
+ # Add ToC reference to scenario reference by calling 'toc' method
+ $self->toc($self->{_scenarioAfterToken}, $tipToc);
+ #push(@{$self->{_scenarioAfterToken}}, $tipTokenToc);
+ # Indicate token itself must not be output
+ $self->{_doOutputInsertionPointToken} = 0;
+ last SWITCH;
+ }
+ # Output ToC before token?
+ if ($tipPreposition eq TIP_PREPOSITION_BEFORE) {
+ # Yes, output ToC before token;
+ # Indicate ToC insertion point has been passed
+ $self->{_isTocInsertionPointPassed} = 1;
+ # Add ToC reference to scenario reference by calling 'toc' method
+ $self->toc($self->{_scenarioBeforeToken}, $tipToc);
+ #push(@{$self->{_scenarioBeforeToken}}, $tipTokenToc);
+ last SWITCH;
+ }
+ # Output ToC after token?
+ if ($tipPreposition eq TIP_PREPOSITION_AFTER) {
+ # Yes, output ToC after token;
+ # Indicate ToC insertion point has been passed
+ $self->{_isTocInsertionPointPassed} = 1;
+ # Add ToC reference to scenario reference by calling 'toc' method
+ $self->toc($self->{_scenarioAfterToken}, $tipToc);
+ #push(@{$self->{_scenarioAfterToken}}, $tipTokenToc);
+ last SWITCH;
+ }
+ }
+} # _processTocInsertionPoint()
+
+
+#--- HTML::TocInsertor::_processTocInsertionPoints() --------------------------
+# function: Process ToC insertion points
+# args: - $aTokenText: Text of token which acts as insertion point for one
+# or multiple ToCs.
+
+sub _processTocInsertionPoints {
+ # Get arguments
+ my ($self, $aTokenText) = @_;
+ # Local variables
+ my ($outputPrefix, $outputSuffix);
+ # Extend scenario
+ push(@{$self->{_scenario}}, @{$self->{_scenarioBeforeToken}});
+
+ if ($outputPrefix = $self->{_outputPrefix}) {
+ push(@{$self->{_scenario}}, \$outputPrefix);
+ $self->{_outputPrefix} = "";
+ }
+
+ # Must insertion point token be output?
+ if ($self->{_doOutputInsertionPointToken}) {
+ # Yes, output insertion point token;
+ push(@{$self->{_scenario}}, \$aTokenText);
+ }
+
+ if ($outputSuffix = $self->{_outputSuffix}) {
+ push(@{$self->{_scenario}}, \$outputSuffix);
+ $self->{_outputSuffix} = "";
+ }
+
+ push(@{$self->{_scenario}}, @{$self->{_scenarioAfterToken}});
+ # Add new act to scenario for output to come
+ my $output = "";
+ push(@{$self->{_scenario}}, \$output);
+ # Write output, processing possible '_outputSuffix'
+ #$self->_writeOrBufferOutput("");
+ # Reset helper scenario's
+ $self->{_scenarioBeforeToken} = [];
+ $self->{_scenarioAfterToken} = [];
+ # Reset bias value to output insertion point token
+ $self->{_doOutputInsertionPointToken} = 1;
+
+} # _processTocInsertionPoints()
+
+
+#--- HTML::Toc::_resetBatchVariables() ----------------------------------------
+# function: Reset batch variables.
+
+sub _resetBatchVariables {
+ my ($self) = @_;
+ # Call ancestor
+ $self->SUPER::_resetBatchVariables();
+ # Array containing references to scalars. This array depicts the order
+ # in which output must be performed after the first ToC Insertion Point
+ # has been passed.
+ $self->{_scenario} = [];
+ # Helper scenario
+ $self->{_scenarioBeforeToken} = [];
+ # Helper scenario
+ $self->{_scenarioAfterToken} = [];
+ # Arrays containing start, end, comment, text & declaration tokens which
+ # must trigger the ToC insertion. Each array element may contain a
+ # reference to an array containing the following elements:
+ $self->{_tokensTip} = [
+ [], # TT_TOKENTYPE_START
+ [], # TT_TOKENTYPE_END
+ [], # TT_TOKENTYPE_COMMENT
+ [], # TT_TOKENTYPE_TEXT
+ [] # TT_TOKENTYPE_DECLARATION
+ ];
+ # 1 if ToC insertion point has been passed, 0 if not
+ $self->{_isTocInsertionPointPassed} = 0;
+ # Tokens after ToC
+ $self->{outputBuffer} = "";
+ # Trailing text after parsed token
+ $self->{_outputSuffix} = "";
+ # Preceding text before parsed token
+ $self->{_outputPrefix} = "";
+} # _resetBatchVariables()
+
+
+#--- HTML::TocInsertor::_writeBufferedOutput() --------------------------------
+# function: Write buffered output to output device(s).
+
+sub _writeBufferedOutput {
+ # Get arguments
+ my ($self) = @_;
+ # Local variables
+ my ($scene);
+ # Must ToC be parsed?
+ if ($self->{options}{'parseToc'}) {
+ # Yes, ToC must be parsed;
+ # Parse ToC
+ #$self->parse($self->{toc});
+ # Output tokens after ToC
+ #$self->_writeOrBufferOutput($self->{outputBuffer});
+ }
+ else {
+ # No, ToC needn't be parsed;
+ # Output scenario
+ foreach $scene (@{$self->{_scenario}}) {
+ # Is scene a reference to a scalar?
+ if (ref($scene) eq "SCALAR") {
+ # Yes, scene is a reference to a scalar;
+ # Output scene
+ $self->_writeOutput($$scene);
+ }
+ else {
+ # No, scene must be reference to HTML::Toc;
+ # Output toc
+ $self->_writeOutput($scene->format());
+ }
+ }
+ }
+} # _writeBufferedOutput()
+
+
+#--- HTML::TocInsertor::_writeOrBufferOutput() --------------------------------
+# function: Write processed HTML to output device(s).
+# args: - aOutput: scalar to write
+# note: If '_isTocInsertionPointPassed' text is buffered before being
+# output because the ToC has to be generated before it can be output.
+# Only after the entire data has been parsed, the ToC and the
+# following text will be output.
+
+sub _writeOrBufferOutput {
+ # Get arguments
+ my ($self, $aOutput) = @_;
+
+ # Add possible output prefix and suffix
+ $aOutput = $self->{_outputPrefix} . $aOutput . $self->{_outputSuffix};
+ # Clear output prefix and suffix
+ $self->{_outputPrefix} = "";
+ $self->{_outputSuffix} = "";
+
+ # Has ToC insertion point been passed?
+ if ($self->{_isTocInsertionPointPassed}) {
+ # Yes, ToC insertion point has been passed;
+ # Buffer output; add output to last '_scenario' item
+ my $index = scalar(@{$self->{_scenario}}) - 1;
+ ${$self->{_scenario}[$index]} .= $aOutput;
+ }
+ else {
+ # No, ToC insertion point hasn't been passed;
+ # Write output
+ $self->_writeOutput($aOutput);
+ }
+} # _writeOrBufferOutput()
+
+
+#--- HTML::TocInsertor::_writeOutput() ----------------------------------------
+# function: Write processed HTML to output device(s).
+# args: - aOutput: scalar to write
+
+sub _writeOutput {
+ # Get arguments
+ my ($self, $aOutput) = @_;
+ # Write output to scalar;
+ ${$self->{_output}} .= $aOutput if (defined($self->{_output}));
+ # Write output to output file
+ print $aOutput if ($self->{_doOutputToFile})
+} # _writeOutput()
+
+
+#--- HTML::TocGenerator::anchorId() -------------------------------------------
+# function: Anchor id processing method.
+# args: - $aAnchorId
+
+sub anchorId {
+ # Get arguments
+ my ($self, $aAnchorId) = @_;
+ # Indicate id must be added to start tag
+ $self->{_doAddAnchorIdToStartTag} = 1;
+ $self->{_anchorId} = $aAnchorId;
+} # anchorId()
+
+
+#--- HTML::TocInsertor::anchorNameBegin() -------------------------------------
+# function: Process anchor name begin, generated by HTML::TocGenerator.
+# args: - $aAnchorNameBegin: Anchor name begin tag to output.
+# - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameBegin {
+ # Get arguments
+ my ($self, $aAnchorNameBegin, $aToc) = @_;
+ # Is another anchorName active?
+ if (defined($self->{_activeAnchorName})) {
+ # Yes, another anchorName is active;
+ # Show warning
+ print "Warn\n";
+ $self->_showWarning(
+ HTML::TocGenerator::WARNING_NESTED_ANCHOR_PS_WITHIN_PS,
+ [$aAnchorNameBegin, $self->{_activeAnchorName}]
+ );
+ }
+ # Store anchor name as output prefix
+ $self->{_outputPrefix} = $aAnchorNameBegin;
+ # Indicate active anchor name
+ $self->{_activeAnchorName} = $aAnchorNameBegin;
+ # Indicate anchor name end must be output
+ $self->{_doOutputAnchorNameEnd} = 1;
+} # anchorNameBegin()
+
+
+#--- HTML::TocInsertor::anchorNameEnd() ---------------------------------------
+# function: Process anchor name end, generated by HTML::TocGenerator.
+# args: - $aAnchorNameEnd: Anchor name end tag to output.
+# - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameEnd {
+ # Get arguments
+ my ($self, $aAnchorNameEnd) = @_;
+ # Store anchor name as output prefix
+ $self->{_outputSuffix} .= $aAnchorNameEnd;
+ # Indicate deactive anchor name
+ $self->{_activeAnchorName} = undef;
+} # anchorNameEnd()
+
+
+#--- HTML::TocInsertor::comment() ---------------------------------------------
+# function: Process comment.
+# args: - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+ # Get arguments
+ my ($self, $aComment) = @_;
+ # Local variables
+ my ($tocInsertionPointToken, $doOutput, $origText);
+ # Allow ancestor to process the comment tag
+ $self->SUPER::comment($aComment);
+ # Assemble original comment
+ $origText = "<!--$aComment-->";
+ # Must ToCs be inserted?
+ if ($self->{hti__Mode} & MODE_DO_INSERT) {
+ # Yes, ToCs must be inserted;
+ # Processing comment as ToC insertion point is successful?
+ if (! $self->_processTokenAsInsertionPoint(
+ HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment, undef, $origText
+ )) {
+ # No, comment isn't a ToC insertion point;
+ # Output comment normally
+ $self->_writeOrBufferOutput($origText);
+ }
+ }
+} # comment()
+
+
+#--- HTML::TocInsertor::declaration() -----------------------------------------
+# function: This function is called every time a declaration is encountered
+# by HTML::Parser.
+
+sub declaration {
+ # Get arguments
+ my ($self, $aDeclaration) = @_;
+ # Allow ancestor to process the declaration tag
+ $self->SUPER::declaration($aDeclaration);
+ # Must ToCs be inserted?
+ if ($self->{hti__Mode} & MODE_DO_INSERT) {
+ # Yes, ToCs must be inserted;
+ # Processing declaration as ToC insertion point is successful?
+ if (! $self->_processTokenAsInsertionPoint(
+ HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration, undef,
+ "<!$aDeclaration>"
+ )) {
+ # No, declaration isn't a ToC insertion point;
+ # Output declaration normally
+ $self->_writeOrBufferOutput("<!$aDeclaration>");
+ }
+ }
+} # declaration()
+
+
+#--- HTML::TocInsertor::end() -------------------------------------------------
+# function: This function is called every time a closing tag is encountered
+# by HTML::Parser.
+# args: - $aTag: tag name (in lower case).
+
+sub end {
+ # Get arguments
+ my ($self, $aTag, $aOrigText) = @_;
+ # Allow ancestor to process the end tag
+ $self->SUPER::end($aTag, $aOrigText);
+ # Must ToCs be inserted?
+ if ($self->{hti__Mode} & MODE_DO_INSERT) {
+ # Yes, ToCs must be inserted;
+ # Processing end tag as ToC insertion point is successful?
+ if (! $self->_processTokenAsInsertionPoint(
+ HTML::TocGenerator::TT_TOKENTYPE_END, $aTag, undef, $aOrigText
+ )) {
+ # No, end tag isn't a ToC insertion point;
+ # Output end tag normally
+ $self->_writeOrBufferOutput($aOrigText);
+ }
+ }
+} # end()
+
+
+#--- HTML::TocInsertor::insert() ----------------------------------------------
+# function: Insert ToC in string.
+# args: - $aToc: (reference to array of) ToC object to insert
+# - $aString: string to insert ToC in
+# - $aOptions: hash reference with optional insertor options
+
+sub insert {
+ # Get arguments
+ my ($self, $aToc, $aString, $aOptions) = @_;
+ # Initialize TocInsertor batch
+ $self->_initializeInsertorBatch($aToc, $aOptions);
+ # Do insert Toc
+ $self->_insert($aString);
+ # Deinitialize TocInsertor batch
+ $self->_deinitializeInsertorBatch();
+} # insert()
+
+
+#--- HTML::TocInsertor::insertIntoFile() --------------------------------------
+# function: Insert ToCs in file.
+# args: - $aToc: (reference to array of) ToC object(s) to insert.
+# - $aFile: (reference to array of) file(s) to parse for insertion
+# points.
+# - $aOptions: optional insertor options
+
+sub insertIntoFile {
+ # Get arguments
+ my ($self, $aToc, $aFile, $aOptions) = @_;
+ # Initialize TocInsertor batch
+ $self->_initializeInsertorBatch($aToc, $aOptions);
+ # Do insert ToCs into file
+ $self->_insertIntoFile($aFile);
+ # Deinitialize TocInsertor batch
+ $self->_deinitializeInsertorBatch();
+} # insertIntoFile()
+
+
+#--- HTML::TocInsertor::number() ----------------------------------------------
+# function: Process heading number generated by HTML::Toc.
+# args: - $aNumber
+
+sub number {
+ # Get arguments
+ my ($self, $aNumber) = @_;
+ # Store heading number as output suffix
+ $self->{_outputSuffix} .= $aNumber;
+} # number()
+
+
+#--- HTML::TocInsertor::propagateFile() ---------------------------------------
+# function: Propagate ToC; generate & insert ToC, using file as input.
+# args: - $aToc: (reference to array of) ToC object to insert
+# - $aFile: (reference to array of) file to parse for insertion
+# points.
+# - $aOptions: optional insertor options
+
+sub propagateFile {
+ # Get arguments
+ my ($self, $aToc, $aFile, $aOptions) = @_;
+ # Local variables;
+ my ($file, @files);
+ # Initialize TocInsertor batch
+ $self->_initializeInsertorBatch($aToc, $aOptions);
+ # Dereference array reference or make array of file specification
+ @files = (ref($aFile) =~ m/ARRAY/) ? @$aFile : ($aFile);
+ # Loop through files
+ foreach $file (@files) {
+ # Generate and insert ToC
+ $self->_generateFromFile($file);
+ }
+ # Deinitialize TocInsertor batch
+ $self->_deinitializeInsertorBatch();
+} # propagateFile()
+
+
+#--- HTML::TocInsertor::start() -----------------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args: - $aTag: tag name (in lower case).
+# - $aAttr: reference to hash containing all tag attributes (in lower
+# case).
+# - $aAttrSeq: reference to array containing all tag attributes (in
+# lower case) in the original order
+# - $aOrigText: the original HTML text
+
+sub start {
+ # Get arguments
+ my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+ # Local variables
+ my ($doOutput, $i, $tocToken, $tag, $anchorId);
+ # Let ancestor process the start tag
+ $self->SUPER::start($aTag, $aAttr, $aAttrSeq, $aOrigText);
+ # Must ToC be inserted?
+ if ($self->{hti__Mode} & MODE_DO_INSERT) {
+ # Yes, ToC must be inserted;
+ # Processing start tag as ToC insertion point is successful?
+ if (! $self->_processTokenAsInsertionPoint(
+ HTML::TocGenerator::TT_TOKENTYPE_START, $aTag, $aAttr, $aOrigText
+ )) {
+ # No, start tag isn't a ToC insertion point;
+ # Add anchor id?
+ if ($self->{_doAddAnchorIdToStartTag}) {
+ # Yes, anchor id must be added;
+ # Reset indicator;
+ $self->{_doAddAnchorIdToStartTag} = 0;
+ # Alias anchor id
+ $anchorId = $self->{_anchorId};
+ # Attribute 'id' already exists?
+ if (defined($aAttr->{id})) {
+ # Yes, attribute 'id' already exists;
+ # Show warning
+ print STDERR "WARNING: Overwriting existing id attribute '" .
+ $aAttr->{id} . "' of tag $aOrigText\n";
+
+ # Add anchor id to start tag
+ $aOrigText =~ s/(id)=\S*([\s>])/$1=$anchorId$2/i;
+ }
+ else {
+ # No, attribute 'id' doesn't exist;
+ # Add anchor id to start tag
+ $aOrigText =~ s/>/ id=$anchorId>/;
+ }
+ }
+ # Output start tag normally
+ $self->_writeOrBufferOutput($aOrigText);
+ }
+ }
+} # start()
+
+
+#--- HTML::TocInsertor::text() ------------------------------------------------
+# function: This function is called every time plain text is encountered.
+# args: - @_: array containing data.
+
+sub text {
+ # Get arguments
+ my ($self, $aText) = @_;
+ # Let ancestor process the text
+ $self->SUPER::text($aText);
+ # Must ToC be inserted?
+ if ($self->{hti__Mode} & MODE_DO_INSERT) {
+ # Yes, ToC must be inserted;
+ # Processing text as ToC insertion point is successful?
+ if (! $self->_processTokenAsInsertionPoint(
+ HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText, undef, $aText
+ )) {
+ # No, text isn't a ToC insertion point;
+ # Output text normally
+ $self->_writeOrBufferOutput($aText);
+ }
+ }
+} # text()
+
+
+
+
+#=== HTML::_TokenTipParser ====================================================
+# function: Parse 'TIP tokens'. 'TIP tokens' mark HTML code which is to be
+# used as the ToC Insertion Point.
+# note: Used internally.
+
+package HTML::_TokenTipParser;
+
+
+BEGIN {
+ use vars qw(@ISA);
+
+ @ISA = qw(HTML::_TokenTocParser);
+}
+
+
+END {}
+
+
+#--- HTML::_TokenTipParser::new() ---------------------------------------------
+# function: Constructor
+
+sub new {
+ # Get arguments
+ my ($aType, $aTokenArray) = @_;
+ # Create instance
+ my $self = $aType->SUPER::new;
+ # Reference token array
+ $self->{tokens} = $aTokenArray;
+ # Reference to last added token
+ $self->{_lastAddedToken} = undef;
+ $self->{_lastAddedTokenType} = undef;
+ # Return instance
+ return $self;
+} # new()
+
+
+#--- HTML::_TokenTipParser::_processAttributes() ------------------------------
+# function: Process attributes.
+# args: - $aAttributes: Attributes to parse.
+
+sub _processAttributes {
+ # Get arguments
+ my ($self, $aAttributes) = @_;
+ # Local variables
+ my (%includeAttributes, %excludeAttributes);
+
+ # Parse attributes
+ $self->_parseAttributes(
+ $aAttributes, \%includeAttributes, \%excludeAttributes
+ );
+ # Include attributes are specified?
+ if (keys(%includeAttributes) > 0) {
+ # Yes, include attributes are specified;
+ # Store include attributes
+ @${$self->{_lastAddedToken}}[
+ HTML::TocInsertor::TIP_INCLUDE_ATTRIBUTES
+ ] = \%includeAttributes;
+ }
+ # Exclude attributes are specified?
+ if (keys(%excludeAttributes) > 0) {
+ # Yes, exclude attributes are specified;
+ # Store exclude attributes
+ @${$self->{_lastAddedToken}}[
+ HTML::TocInsertor::TIP_EXCLUDE_ATTRIBUTES
+ ] = \%excludeAttributes;
+ }
+} # _processAttributes()
+
+
+#--- HTML::_TokenTipParser::_processToken() -----------------------------------
+# function: Process token.
+# args: - $aTokenType: Type of token to process.
+# - $aTag: Tag of token.
+
+sub _processToken {
+ # Get arguments
+ my ($self, $aTokenType, $aTag) = @_;
+ # Local variables
+ my ($tokenArray, $index);
+ # Push element on array of update tokens
+ $index = push(@{$self->{tokens}[$aTokenType]}, []) - 1;
+ # Alias token array to add element to
+ $tokenArray = $self->{tokens}[$aTokenType];
+ # Indicate last updated token array element
+ $self->{_lastAddedTokenType} = $aTokenType;
+ $self->{_lastAddedToken} = \$$tokenArray[$index];
+ # Add fields
+ $$tokenArray[$index][HTML::TocInsertor::TIP_TOC] = $self->{_toc};
+ $$tokenArray[$index][HTML::TocInsertor::TIP_TOKEN_ID] = $aTag;
+ $$tokenArray[$index][HTML::TocInsertor::TIP_PREPOSITION] =
+ $self->{_preposition};
+} # _processToken()
+
+
+#--- HTML::_TokenTipParser::comment() -----------------------------------------
+# function: Process comment.
+# args: - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+ # Get arguments
+ my ($self, $aComment) = @_;
+ # Process token
+ $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment);
+} # comment()
+
+
+#--- HTML::_TokenTipParser::declaration() --------------------------------
+# function: This function is called every time a markup declaration is
+# encountered by HTML::Parser.
+# args: - $aDeclaration: Markup declaration.
+
+sub declaration {
+ # Get arguments
+ my ($self, $aDeclaration) = @_;
+ # Process token
+ $self->_processToken(
+ HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration
+ );
+} # declaration()
+
+
+#--- HTML::_TokenTipParser::end() ----------------------------------------
+# function: This function is called every time a closing tag is encountered
+# by HTML::Parser.
+# args: - $aTag: tag name (in lower case).
+
+sub end {
+ # Get arguments
+ my ($self, $aTag, $aOrigText) = @_;
+ # Process token
+ $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_END, $aTag);
+} # end()
+
+
+#--- HTML::_TokenTipParser->setPreposition() ----------------------------------
+# function: Set current preposition.
+
+sub setPreposition {
+ # Get arguments
+ my ($self, $aPreposition) = @_;
+ # Set current ToC
+ $self->{_preposition} = $aPreposition;
+} # setPreposition()
+
+
+#--- HTML::_TokenTipParser->setToc() ------------------------------------------
+# function: Set current ToC.
+
+sub setToc {
+ # Get arguments
+ my ($self, $aToc) = @_;
+ # Set current ToC
+ $self->{_toc} = $aToc;
+} # setToc()
+
+
+#--- HTML::_TokenTipParser::start() --------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args: - $aTag: tag name (in lower case).
+# - $aAttr: reference to hash containing all tag attributes (in lower
+# case).
+# - $aAttrSeq: reference to array containing all attribute keys (in
+# lower case) in the original order
+# - $aOrigText: the original HTML text
+
+sub start {
+ # Get arguments
+ my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+ # Process token
+ $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_START, $aTag);
+ # Process attributes
+ $self->_processAttributes($aAttr);
+} # start()
+
+
+#--- HTML::_TokenTipParser::text() ---------------------------------------
+# function: This function is called every time plain text is encountered.
+# args: - @_: array containing data.
+
+sub text {
+ # Get arguments
+ my ($self, $aText) = @_;
+ # Was token already created and is last added token of type 'text'?
+ if (
+ defined($self->{_lastAddedToken}) &&
+ $self->{_lastAddedTokenType} == HTML::TocGenerator::TT_TOKENTYPE_TEXT
+ ) {
+ # Yes, token is already created;
+ # Add tag to existing token
+ @${$self->{_lastAddedToken}}[HTML::TocGenerator::TT_TAG_BEGIN] .= $aText;
+ }
+ else {
+ # No, token isn't created;
+ # Process token
+ $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText);
+ }
+} # text()
+
+
+1;