зеркало из https://github.com/mozilla/pjs.git
Initial add of APIDOC api documentation script. a=leaf
This commit is contained in:
Родитель
08212e4ea0
Коммит
4406893998
|
@ -0,0 +1,27 @@
|
|||
|
||||
FILES:
|
||||
|
||||
===* parse_devedge_doc.pl
|
||||
Requires:
|
||||
nothing.
|
||||
|
||||
Description:
|
||||
Parses the nasty devedge document (jsref.htm) into somewhat nicer xml.
|
||||
|
||||
Syntax:
|
||||
perl parse_devedge_doc.pl < jsref.htm > jsref.xml
|
||||
|
||||
===* parse_apidoc.pl
|
||||
Requires:
|
||||
XML::Parser (http://search.cpan.org/search?dist=XML-Parser)
|
||||
|
||||
Description:
|
||||
Parses apidoc xml files, producing html output for viewing in normal browsers.
|
||||
Output will be placed in the specified directory, or ./apidocs if none is
|
||||
specified. Output pages with content will refer to api-content.css, table
|
||||
of content pages will refer to api-toc.css.
|
||||
|
||||
Syntax:
|
||||
perl parse_apidoc.pl jsref.xml [<output-directory>]
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
body {
|
||||
background: #F9F1D1;
|
||||
}
|
||||
|
||||
.api-entry {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.entry-heading {
|
||||
background: lightgrey;
|
||||
}
|
||||
|
||||
.entry-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.entry-type {
|
||||
background: black;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.entry-deprecated {
|
||||
font-weight: bold;
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.entry-summary {
|
||||
}
|
||||
|
||||
.entry-syntax {
|
||||
background: #EEEEEE;
|
||||
}
|
||||
|
||||
.param-list-head {
|
||||
background: lightgrey;
|
||||
}
|
||||
|
||||
.param-row-even {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.entry-description {
|
||||
}
|
||||
|
||||
.entry-example {
|
||||
}
|
||||
|
||||
.entry-notes {
|
||||
}
|
||||
|
||||
.entry-seealso {
|
||||
background: #EEEEEE;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
body {
|
||||
background: #F9F1D1;
|
||||
}
|
||||
|
||||
a {
|
||||
/* text-decoration: none;*/
|
||||
}
|
||||
|
||||
.toc-title {
|
||||
background: lightgrey;
|
||||
}
|
||||
|
||||
.toc-abc,
|
||||
.toc-group-even {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.toc-group-odd {
|
||||
background: #EEEEEE;
|
||||
}
|
||||
|
||||
.toc-entry-deprecated {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toc-ind-deprecated {
|
||||
font-weight: bold;
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<frameset name='doc-frameset' cols='25%,*'>
|
||||
<frame name='toc-container' src='apidocs/complete-toc.html'>
|
||||
<frame name='content-container' src='apidocs/complete.html'>
|
||||
</frameset>
|
||||
</html>
|
|
@ -0,0 +1,877 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla WebTools.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Ginda <rginda@netscape.com>, Initial development.
|
||||
#
|
||||
use strict;
|
||||
use XML::Parser;
|
||||
|
||||
my $file = shift;
|
||||
my $outdir = shift || "apidocs";
|
||||
my $c;
|
||||
my $tagname;
|
||||
my $pending_param;
|
||||
my $pending_text;
|
||||
my %pending_attrs;
|
||||
my %groups;
|
||||
my %externals;
|
||||
my %toc_externals;
|
||||
my $user_foot;
|
||||
my $user_head;
|
||||
my @tag_stack;
|
||||
my @text_stack;
|
||||
my @attr_stack;
|
||||
my $inited = 0;
|
||||
my %entries;
|
||||
my $apiid;
|
||||
|
||||
my $API = 0;
|
||||
my $ENTRY = 1;
|
||||
my $TYPE = 2;
|
||||
my $SUMMARY = 3;
|
||||
my $SYNTAX = 4;
|
||||
my $PARAM = 5;
|
||||
my $RETVAL = 6;
|
||||
my $DESCRIPTION = 7;
|
||||
my $EXAMPLE = 8;
|
||||
my $NOTE = 9;
|
||||
my $SEE_ALSO = 10;
|
||||
my $DEPRECATED = 11;
|
||||
my $EXTERNALREF = 12;
|
||||
my $GROUP = 13;
|
||||
my $C = 14;
|
||||
my $P = 15;
|
||||
my $BR = 16;
|
||||
my $B = 17;
|
||||
my $I = 18;
|
||||
my $S = 19;
|
||||
my $FOOT = 20;
|
||||
my $HEAD = 21;
|
||||
my $COMPLETED = 22;
|
||||
my @TAGS = ("API", "ENTRY", "TYPE", "SUMMARY", "SYNTAX", "PARAM", "RETVAL",
|
||||
"DESCRIPTION", "EXAMPLE", "NOTE", "SEEALSO", "DEPRECATED",
|
||||
"EXTERNALREF", "GROUP", "C", "P", "BR", "B", "I", "S", "FOOT",
|
||||
"HEAD");
|
||||
my @CDATA_TAGS = ($TAGS[$SUMMARY], $TAGS[$SYNTAX], $TAGS[$DESCRIPTION],
|
||||
$TAGS[$EXAMPLE], $TAGS[$NOTE], $TAGS[$PARAM], $TAGS[$C],
|
||||
$TAGS[$B], $TAGS[$I], $TAGS[$S], $TAGS[$FOOT], $TAGS[$HEAD]);
|
||||
my @FORMATTING_TAGS = ($TAGS[$P], $TAGS[$C], $TAGS[$B], $TAGS[$I], $TAGS[$BR],
|
||||
$TAGS[$BR], $TAGS[$S]);
|
||||
my @FORMAT_CONTAINERS = ($TAGS[$SUMMARY], $TAGS[$PARAM], $TAGS[$RETVAL],
|
||||
$TAGS[$DESCRIPTION], $TAGS[$NOTE], $TAGS[$C],
|
||||
$TAGS[$B], $TAGS[$I], $TAGS[$FOOT], $TAGS[$HEAD]);
|
||||
my @CODE_TAGS = ($TAGS[$SYNTAX], $TAGS[$EXAMPLE]);
|
||||
|
||||
my $URLVAR_ENTRY = "{e}";
|
||||
|
||||
my $footstr = "<center>This page was generated by " .
|
||||
"<a href='www.mozilla.org/projects/apidoc'><b>APIDOC</b></a>" .
|
||||
"</center>\n</body></html>";
|
||||
|
||||
my $JS_COMPLETE = ("\n<script>\n" .
|
||||
"function navToEntry(entry) {\n" .
|
||||
" window.document.location.hash=entry;\n" .
|
||||
"}\n" .
|
||||
"function navToGroup(group) {\n" .
|
||||
" var f = top.frames['toc-container'];\n" .
|
||||
" if (!f)\n".
|
||||
" window.open ('complete-toc.html#' + group, " .
|
||||
"'toc_container');\n" .
|
||||
" else {\n" .
|
||||
" f.document.location.href = 'complete-toc.html';\n" .
|
||||
" f.document.location.hash = group;\n" .
|
||||
" }\n" .
|
||||
"}\n" .
|
||||
"</script>\n");
|
||||
|
||||
my $JS_SPARSE = ("\n<script>\n" .
|
||||
"function navToEntry(entry) {\n" .
|
||||
" window.document.location.href='api-' + entry + '.html';\n" .
|
||||
"}\n" .
|
||||
"function navToGroup(group) {\n" .
|
||||
" var f = top.frames['toc-container'];\n" .
|
||||
" if (!f)\n".
|
||||
" window.open ('sparse-toc.html#' + group, " .
|
||||
"'toc_container');\n" .
|
||||
" else {\n" .
|
||||
" f.document.location.href = 'sparse-toc.html';\n" .
|
||||
" f.document.location.hash = group;\n" .
|
||||
" }\n" .
|
||||
"}\n" .
|
||||
"</script>\n");
|
||||
|
||||
open (COMPLETE, ">" . $outdir . "/complete.html") ||
|
||||
die ("Couldn't open $outdir/complete.html.\n");
|
||||
open (COMPLETE_TOC, ">" . $outdir . "/complete-toc.html") ||
|
||||
die ("Couldn't open $outdir/complete-toc.html.\n");
|
||||
open (SPARSE_TOC, ">" . $outdir . "/sparse-toc.html") ||
|
||||
die ("Couldn't open $outdir/sparse-toc.html.\n");
|
||||
|
||||
&main();
|
||||
|
||||
sub main {
|
||||
my $parser = new XML::Parser(ErrorContext => 2);
|
||||
|
||||
# pass 1, scan all <ENTRY> tags.
|
||||
$parser->setHandlers(Start => \&p1_Start, End => \&p1_End);
|
||||
$parser->parsefile($file);
|
||||
|
||||
# sanity check the tag stack from p1
|
||||
if ($#tag_stack != -1) {
|
||||
die ("OOPS: p1 left the tag stack in a bad state.\n");
|
||||
}
|
||||
|
||||
# pass 2, populate the $entries hash.
|
||||
$parser = new XML::Parser(Style => "Stream", ErrorContext => 2);
|
||||
$parser->parsefile ($file);
|
||||
|
||||
# finally, write it all out.
|
||||
&init_files();
|
||||
|
||||
my $k;
|
||||
my $html;
|
||||
|
||||
for $k (sort (keys(%entries))) {
|
||||
$c = $entries{$k};
|
||||
$html = &get_entry_html();
|
||||
&add_entry_complete($html);
|
||||
&add_entry_sparse($html);
|
||||
&add_toc_complete();
|
||||
&add_toc_sparse();
|
||||
#&debug_write_entry();
|
||||
}
|
||||
|
||||
&write_toc_groups();
|
||||
|
||||
&close_files();
|
||||
|
||||
}
|
||||
|
||||
sub p1_Start {
|
||||
# pass 1, find all <ENTRY/>, <EXTERNALREF/>, and <GROUP/> tags
|
||||
# (as well as groups implied by <TYPE/> and <DEPRECATED/> tags), so we
|
||||
# can do things like auto link <C/> tags that refer to entrys,
|
||||
# and validate <S/> tags in pass 2.
|
||||
my $expat = shift;
|
||||
my $lasttagname = $tagname;
|
||||
my $n;
|
||||
my %pending_attrs;
|
||||
|
||||
push (@tag_stack, $lasttagname);
|
||||
$tagname = shift;
|
||||
|
||||
while ($n = shift) {
|
||||
$pending_attrs{$n} = shift;
|
||||
}
|
||||
|
||||
my $value = $pending_attrs{"value"};
|
||||
my $id = $pending_attrs{"id"};
|
||||
|
||||
if ($tagname eq $TAGS[$ENTRY]) {
|
||||
if ($id) {
|
||||
$c = $entries{$id} = {$TAGS[$ENTRY] => $id};
|
||||
} else {
|
||||
&croak_attr ($expat, $tagname, "id");
|
||||
}
|
||||
} elsif ($tagname eq $TAGS[$TYPE]) {
|
||||
if (!$value) {
|
||||
&croak_attr ($expat, $tagname, "value");
|
||||
}
|
||||
$c->{$tagname} = $value;
|
||||
push (@{$groups{$value}}, $c->{$TAGS[$ENTRY]});
|
||||
push (@{$c->{$TAGS[$GROUP]}}, $value);
|
||||
} elsif ($tagname eq $TAGS[$DEPRECATED]) {
|
||||
$c->{$tagname} = 1;
|
||||
push (@{$groups{"Deprecated"}}, $c->{$TAGS[$ENTRY]});
|
||||
push (@{$c->{$TAGS[$GROUP]}}, "Deprecated");
|
||||
} elsif ($tagname eq $TAGS[$GROUP]) {
|
||||
if (($lasttagname ne $TAGS[$API]) &&
|
||||
($lasttagname ne $TAGS[$ENTRY])) {
|
||||
$expat->xpcroak ("Tag $tagname can only be contained by ".
|
||||
"an '" . $TAGS[$API] . "' or '" .
|
||||
$TAGS[$ENTRY] . "' tag");
|
||||
}
|
||||
my $name = $pending_attrs{"name"};
|
||||
if (!$name) {
|
||||
&croak_attr ($expat, $tagname, "name");
|
||||
}
|
||||
if ($lasttagname ne $TAGS[$ENTRY]) {
|
||||
if (!$value) {
|
||||
&croak_attr ($expat, $tagname, "value");
|
||||
}
|
||||
} else {
|
||||
$value = $c->{$TAGS[$ENTRY]};
|
||||
}
|
||||
if (!grep (/^$value$/, @{$groups{$name}})) {
|
||||
# if it isn't already there, add it
|
||||
push (@{$groups{$name}}, $value);
|
||||
push (@{$entries{$value}->{$TAGS[$GROUP]}}, $name);
|
||||
}
|
||||
} elsif ($tagname eq $TAGS[$EXTERNALREF]) {
|
||||
my $name = $pending_attrs{"name"};
|
||||
my $value = $pending_attrs{"value"};
|
||||
if (!$name) {
|
||||
&croak_attr ($expat, $tagname, "name");
|
||||
}
|
||||
if (!$value) {
|
||||
&croak_attr ($expat, $tagname, "value");
|
||||
}
|
||||
if ($lasttagname eq $TAGS[$API]) {
|
||||
# if the externalref is a child of the API tag
|
||||
if ($value =~ /$URLVAR_ENTRY/) {
|
||||
# and it has a placeholder for the entry id,
|
||||
# then attach it to every entry
|
||||
$externals{$name} = $value;
|
||||
} else {
|
||||
# otherwise, just put it in the toc.
|
||||
$toc_externals{$name} = $value;
|
||||
}
|
||||
} elsif ($lasttagname eq $TAGS[$ENTRY]) {
|
||||
# if the externalref is a child of the ENTRY tag
|
||||
# only attach it to this entry
|
||||
$c->{$TAGS[$EXTERNALREF]}{$name} = $value;
|
||||
} else {
|
||||
$expat->xpcroak ("Tag $tagname can only be contained by ".
|
||||
"an '" . $TAGS[$API] . "' or '" .
|
||||
$TAGS[$ENTRY] . "' tag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub p1_End {
|
||||
$tagname = pop (@tag_stack);
|
||||
}
|
||||
|
||||
sub StartTag {
|
||||
my ($expat) = @_;
|
||||
$_ =~ /<([^\s>]*)/;
|
||||
my $lasttagname = $tagname;
|
||||
$tagname = $1;
|
||||
|
||||
push (@tag_stack, $lasttagname);
|
||||
push (@text_stack, $pending_text);
|
||||
my $s = $#attr_stack + 1;
|
||||
$attr_stack[$s]{"foo"} = "bar";
|
||||
for (keys (%pending_attrs)) {
|
||||
$attr_stack[$s]{$_} = $pending_attrs{$_};
|
||||
}
|
||||
|
||||
$pending_text = "";
|
||||
%pending_attrs = %_;
|
||||
|
||||
if (!grep(/^$tagname$/, @TAGS)) {
|
||||
$expat->xpcroak ("Unknown tag '$tagname'");
|
||||
}
|
||||
|
||||
# print ("opening: ");
|
||||
# &debug_dump_c();
|
||||
|
||||
my $value = $pending_attrs{"value"};
|
||||
my $id = $pending_attrs{"id"};
|
||||
|
||||
if ($tagname eq $TAGS[$API]) {
|
||||
if ($inited) {
|
||||
$expat->xpcroak ("Only one '$tagname' tag allowed");
|
||||
}
|
||||
if (!$id) {
|
||||
&croak_attr ($expat, $tagname, "id");
|
||||
}
|
||||
$apiid = $id;
|
||||
$inited = 1;
|
||||
} elsif ($inited) {
|
||||
if ($tagname eq $TAGS[$ENTRY]) {
|
||||
if (!$id) {
|
||||
&croak_attr ($expat, $tagname, "id");
|
||||
}
|
||||
$c = $entries{$id};
|
||||
} elsif ($tagname eq $TAGS[$SEE_ALSO]) {
|
||||
if (!$value) {
|
||||
&croak_attr ($expat, $tagname, "value");
|
||||
} elsif (!$entries{$value}) {
|
||||
$expat->xpcroak ("Undefined SEEALSO reference, '$value'");
|
||||
}
|
||||
if (!grep (/^$value$/, @{$c->{$TAGS[$SEE_ALSO]}})) {
|
||||
push (@{$c->{$TAGS[$SEE_ALSO]}}, $value);
|
||||
}
|
||||
} elsif (grep(/^$tagname$/, @FORMATTING_TAGS)) {
|
||||
if (!grep(/^$lasttagname$/, @FORMAT_CONTAINERS)) {
|
||||
$expat->xpcroak ("Tag $lasttagname cannot contain formatting " .
|
||||
"tags");
|
||||
}
|
||||
} elsif (($tagname eq $TAGS[$PARAM]) || ($tagname eq $TAGS[$RETVAL])) {
|
||||
if ($lasttagname ne $TAGS[$SYNTAX]) {
|
||||
$expat->xpcroak ("Tag $tagname can only be contained by a '" .
|
||||
$TAGS[$SYNTAX] . "' tag");
|
||||
}
|
||||
if (!$pending_attrs{"name"}) {
|
||||
if ($tagname eq $TAGS[$RETVAL]) {
|
||||
$pending_attrs{"name"} = "Return Value";
|
||||
} else {
|
||||
&croak_attr ($expat, $tagname, "name");
|
||||
}
|
||||
}
|
||||
if (!$pending_attrs{"type"}) {
|
||||
$pending_attrs{"type"} = " ";
|
||||
# &croak_attr ($expat, $tagname, "type");
|
||||
}
|
||||
} elsif ((($tagname eq $TAGS[$HEAD]) || ($tagname eq $TAGS[$HEAD])) &&
|
||||
($lasttagname ne $TAGS[$API])) {
|
||||
$expat->xpcroak ("Tag $tagname can only be contained by ".
|
||||
"an '" . $TAGS[$API] . "' tag");
|
||||
}
|
||||
} else {
|
||||
$expat->xpcroak ("Tag '$tagname' must be contained in an '" .
|
||||
$TAGS[$API] . " tag");
|
||||
}
|
||||
}
|
||||
|
||||
sub EndTag {
|
||||
my ($expat) = @_;
|
||||
my $iscontainer = 0;
|
||||
$_ =~ /<\/([^\s>]*)/;
|
||||
$tagname = $1;
|
||||
|
||||
# print ("closing: ");
|
||||
# &debug_dump_c();
|
||||
|
||||
if (grep(/^$tagname$/, @CDATA_TAGS)) {
|
||||
$iscontainer = 1;
|
||||
if ($pending_text eq "") {
|
||||
$expat->xpcroak ("Empty container '$tagname'.");
|
||||
}
|
||||
}
|
||||
|
||||
if (grep(/^$tagname$/, @FORMATTING_TAGS)) {
|
||||
if ($iscontainer) {
|
||||
if ($tagname eq $TAGS[$C]) {
|
||||
# code tag
|
||||
if (($pending_text ne $c->{$TAGS[$ENTRY]}) &&
|
||||
($entries{$pending_text})) {
|
||||
# if the contents are a valid entry
|
||||
# add it to the SEEALSO, in case it's not already there
|
||||
if (!grep (/^$pending_text$/, @{$c->{$TAGS[$SEE_ALSO]}})) {
|
||||
push (@{$c->{$TAGS[$SEE_ALSO]}}, $pending_text);
|
||||
}
|
||||
# and make it a link
|
||||
$pending_text = &get_link($pending_text);
|
||||
}
|
||||
$pending_text = "<code>$pending_text</code>";
|
||||
} elsif ($tagname eq $TAGS[$S]) {
|
||||
# seealso reference
|
||||
my $value;
|
||||
if (($value = $entries{$pending_text}) ||
|
||||
($value = $toc_externals{$pending_text}) ||
|
||||
($value = $c->{$TAGS[$EXTERNALREF]}{$pending_text})) {
|
||||
# it's a valid external reference
|
||||
# put it in this entry's external references incase it isn't
|
||||
# already there.
|
||||
$c->{$TAGS[$EXTERNALREF]}{$pending_text} = $value;
|
||||
$_ = $value;
|
||||
s/$URLVAR_ENTRY/$c->{$TAGS[$ENTRY]}/g;
|
||||
$pending_text =
|
||||
"<a href='$_' target='other_window'>" .
|
||||
"$pending_text</a>";
|
||||
} elsif ($value = $groups{$pending_text}) {
|
||||
# it's a valid group
|
||||
# put it in this entry's group references incase it isn't
|
||||
# already there.
|
||||
if ((!$c->{$TAGS[$GROUP]}) ||
|
||||
(!grep (/^$pending_text$/, @{$c->{$TAGS[$GROUP]}}))) {
|
||||
push (@{$c->{$TAGS[$GROUP]}}, $pending_text);
|
||||
}
|
||||
$pending_text ="<a href='javascript:" .
|
||||
"navToGroup(\"GROUP_$pending_text\")'>$pending_text</a>";
|
||||
} else {
|
||||
# it's just not valid
|
||||
$expat->xpcroak ("Unknown reference in '" . $TAGS[$S] .
|
||||
"' tag");
|
||||
}
|
||||
} elsif ($tagname eq $TAGS[$B]) {
|
||||
# bold
|
||||
$pending_text = "<b>$pending_text</b>";
|
||||
} elsif ($tagname eq $TAGS[$I]) {
|
||||
# italic
|
||||
$pending_text = "<i>$pending_text</i>";
|
||||
} else {
|
||||
expat->xpcroak
|
||||
("OOPS: Unhandled container formatting tag '$tagname'");
|
||||
}
|
||||
} else {
|
||||
if ($tagname eq $TAGS[$P]) {
|
||||
# paragraph
|
||||
$pending_text = "<P>";
|
||||
} elsif ($tagname eq $TAGS[$BR]) {
|
||||
# br
|
||||
$pending_text = "<BR>";
|
||||
} else {
|
||||
expat->xpcroak
|
||||
("OOPS: Unhandled non-container formatting tag '$tagname'");
|
||||
}
|
||||
}
|
||||
# combine with previous pendingtext
|
||||
$pending_text = pop(@text_stack) . $pending_text;
|
||||
} elsif ($iscontainer) {
|
||||
# not a formatting tag, store the accumulated pendingtext in the
|
||||
# right place, after some whitespace trimming
|
||||
my @lines = split ("\n", $pending_text);
|
||||
my $iscode = grep (/^$tagname$/, @CODE_TAGS);
|
||||
my $i;
|
||||
my $line;
|
||||
my $result_text = "";
|
||||
|
||||
for $i (0 ... $#lines) {
|
||||
$line = $lines[$i];
|
||||
if ((($i != 0) && ($i != $#lines)) || ($line =~ /[\S\N]/)) {
|
||||
if ($iscode) {
|
||||
$line = &add_leading_nbsp($line);
|
||||
} else {
|
||||
$_ = $line;
|
||||
s/\.\s\s(.)/\.\ \ $1/g;
|
||||
$line = $_;
|
||||
}
|
||||
$line =~ /^[\s\n]*(.*)[\s\n]*/;
|
||||
$result_text .= $1 . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$_ = $result_text;
|
||||
# s/\n/<br>/g;
|
||||
$result_text = $_;
|
||||
|
||||
if (($tagname eq $TAGS[$PARAM]) || ($tagname eq $TAGS[$RETVAL])) {
|
||||
# parameter block
|
||||
my $name = $pending_attrs{"name"};
|
||||
my $type = $pending_attrs{"type"};
|
||||
my $html = ("<td class='param-name'><code>$name</code></td>" .
|
||||
"<td class='param-type'><code>$type</code></td>" .
|
||||
"<td class='param-desc'>$result_text</td>\n");
|
||||
push (@{$c->{$TAGS[$PARAM]}}, $html);
|
||||
} elsif ($tagname eq $TAGS[$EXAMPLE]) {
|
||||
$c->{$tagname . "_DESC"} = $pending_attrs{"desc"};
|
||||
$c->{$tagname} = $result_text;
|
||||
} elsif ($tagname eq $TAGS[$HEAD]) {
|
||||
$user_head .= $result_text;
|
||||
} elsif ($tagname eq $TAGS[$FOOT]) {
|
||||
$user_foot .= $result_text;
|
||||
} else {
|
||||
$c->{$tagname} = $result_text;
|
||||
}
|
||||
|
||||
$pending_text = pop (@text_stack);
|
||||
} else {
|
||||
$pending_text = pop (@text_stack);
|
||||
}
|
||||
|
||||
%pending_attrs = %{pop (@attr_stack)};
|
||||
$tagname = pop (@tag_stack);
|
||||
|
||||
# print ("popped: ");
|
||||
# &debug_dump_c();
|
||||
|
||||
}
|
||||
|
||||
sub Text {
|
||||
my ($expat) = @_;
|
||||
|
||||
if (/^[\s\n]+$/) {
|
||||
return;
|
||||
}
|
||||
if (!grep(/^$tagname$/, @CDATA_TAGS)) {
|
||||
$expat->xpcroak ("Tag '$tagname' cannot contain text");
|
||||
}
|
||||
|
||||
$pending_text .= $_;
|
||||
|
||||
}
|
||||
|
||||
sub EndDocument {
|
||||
}
|
||||
|
||||
sub get_entry_html {
|
||||
my $html = "";
|
||||
$c->{$TAGS[$ENTRY]} =~ /\.?(.*)/;
|
||||
my $id = $1;
|
||||
$html = "<center><table class='api-entry' width='100%' cellspacing='0'" .
|
||||
"border='1' cellpadding='10'>\n";
|
||||
$html .= "<tr><td class='entry-heading'>\n";
|
||||
|
||||
$html .= "<table class='entry-heading-table' width='100%' cellpadding='5'" .
|
||||
"cellspacing='0'><tr>\n";
|
||||
$html .= "<td class='entry-title' valign='center'><font size='+5'>" .
|
||||
$id . "</font></td>\n";
|
||||
$html .= "<td class='entry-type' align='center' width='25%'>" .
|
||||
$c->{$TAGS[$TYPE]} . "</td>\n";
|
||||
if ($c->{$TAGS[$DEPRECATED]}) {
|
||||
$html .= "<td class='entry-deprecated' align='center' width='25%'>" .
|
||||
"Deprecated</td>\n";
|
||||
}
|
||||
$html .= "</tr></table>\n";
|
||||
|
||||
$html .= "</td></tr>\n";
|
||||
|
||||
if ($c->{$TAGS[$SUMMARY]}) {
|
||||
$html .= "<tr><td class='entry-summary'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>Summary</h4>\n";
|
||||
$html .= $c->{$TAGS[$SUMMARY]};
|
||||
$html .= "</td></tr>\n";
|
||||
}
|
||||
if ($c->{$TAGS[$SYNTAX]}) {
|
||||
$html .= "<tr><td class='entry-syntax'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>Syntax</h4><pre>\n";
|
||||
$html .= $c->{$TAGS[$SYNTAX]};
|
||||
$html .= "</pre>\n";
|
||||
if ($c->{$TAGS[$PARAM]}) {
|
||||
$html .= "<center><table class='param-list' border='1' " .
|
||||
"cellpadding='3' cellspacing='1'>";
|
||||
$html .= "<tr class='param-list-head'>";
|
||||
$html .= "<th>Name</th><th>Type</th><th>Description</th></tr>\n";
|
||||
my $param = shift (@{$c->{$TAGS[$PARAM]}});
|
||||
my $even = 1;
|
||||
while ($param) {
|
||||
$_ = $param;
|
||||
if ($even == 1) {
|
||||
$html .= "<tr class='param-row-even'>";
|
||||
} else {
|
||||
$html .= "<tr class='param-row-odd'>";
|
||||
}
|
||||
$param = $_;
|
||||
$even *= -1;
|
||||
$html .= $param . "</tr>\n";
|
||||
$param = shift (@{$c->{$TAGS[$PARAM]}});
|
||||
}
|
||||
$html .= "</table></center>\n"
|
||||
}
|
||||
$html .= "</td></tr>\n";
|
||||
}
|
||||
if ($c->{$TAGS[$DESCRIPTION]}) {
|
||||
$html .= "<tr><td class='entry-description'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>Description</h4>\n";
|
||||
$html .= $c->{$TAGS[$DESCRIPTION]};
|
||||
$html .= "</td></tr>\n";
|
||||
}
|
||||
if ($c->{$TAGS[$EXAMPLE]}) {
|
||||
$html .= "<tr><td class='entry-example'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>Example</h4>\n";
|
||||
if ($c->{$TAGS[$EXAMPLE] . "_DESC"}) {
|
||||
$html .= $c->{$TAGS[$EXAMPLE] . "_DESC"} . "<br>";
|
||||
}
|
||||
$html .= "<pre>" . $c->{$TAGS[$EXAMPLE]};
|
||||
$html .= "</pre></td></tr>\n";
|
||||
}
|
||||
if ($c->{$TAGS[$NOTE]}) {
|
||||
$html .= "<tr><td class='entry-notes'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>Notes</h4>\n";
|
||||
$html .= $c->{$TAGS[$NOTE]};
|
||||
$html .= "</td></tr>\n";
|
||||
}
|
||||
|
||||
my $sa = get_seealso();
|
||||
if ($sa) {
|
||||
$html .= "<tr><td class='entry-seealso'>\n";
|
||||
$html .= "<h4 class='entry-subhead'>See Also</h4>\n";
|
||||
$html .= $sa;
|
||||
$html .= "</td></tr>\n";
|
||||
}
|
||||
|
||||
$html .= "</table></center><br>\n";
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
sub get_seealso {
|
||||
my @links;
|
||||
my $k;
|
||||
my $i;
|
||||
my $html = "";
|
||||
|
||||
for (@{$c->{$TAGS[$GROUP]}}) {
|
||||
push (@links, "<a href='javascript:navToGroup(\"GROUP_$_\")'>$_</a>");
|
||||
}
|
||||
|
||||
if ($#links != -1) {
|
||||
$html .= "<tr class='seealso-groups'><td>Groups</td>\n";
|
||||
$html .= "<td>[ " . join (" | ", sort(@links)) . " ]</td></tr>\n";
|
||||
}
|
||||
|
||||
@links = ();
|
||||
|
||||
# global externals (had a parent tag of <API/>)
|
||||
for $k (keys(%externals)) {
|
||||
$_ = $externals{$k};
|
||||
s/$URLVAR_ENTRY/$c->{$TAGS[$ENTRY]}/g;
|
||||
push (@links, "<a href='$_' target='other_window'>$k</a>");
|
||||
}
|
||||
|
||||
# local externals (parented by <ENTRY/>
|
||||
for $k (keys(%{$c->{$TAGS[$EXTERNALREF]}})) {
|
||||
$_ = $c->{$TAGS[$EXTERNALREF]}{$k};
|
||||
s/$URLVAR_ENTRY/$c->{$TAGS[$ENTRY]}/g;
|
||||
push (@links, "<a href='$_' target='other_window'>$k</a>");
|
||||
}
|
||||
|
||||
if ($#links != -1) {
|
||||
$html .= "<tr class='seealso-externals'><td>Documents</td>\n";
|
||||
$html .= "<td>[ " . join (" | ", sort(@links)) . " ]</td></tr>\n";
|
||||
}
|
||||
|
||||
@links = ();
|
||||
|
||||
for $k (@{$c->{$TAGS[$SEE_ALSO]}}) {
|
||||
push (@links, &get_link($k));
|
||||
}
|
||||
|
||||
if ($#links != -1) {
|
||||
$html .= "<tr class='seealso-internals'><td>Entries</td>\n";
|
||||
$html .= "<td>[ " . join (" | ", sort(@links)) . " ]</td></tr>\n";
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$html = "<table class='seealso-table'>\n" . $html . "\n</table>\n";
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub add_entry_complete {
|
||||
my ($html) = @_;
|
||||
|
||||
print COMPLETE "<a name='" . $c->{$TAGS[$ENTRY]} . "'></a>\n";
|
||||
print COMPLETE $html;
|
||||
|
||||
}
|
||||
|
||||
sub add_entry_sparse {
|
||||
my ($html) = @_;
|
||||
my $outfile = $outdir . "/api-" . $c->{$TAGS[$ENTRY]} . ".html";
|
||||
|
||||
open (SPARSE, ">$outfile") ||
|
||||
die ("Couldn't open $outfile.\n");
|
||||
|
||||
my $headstr = "<html><head><link rel=StyleSheet href='api-content.css' " .
|
||||
"TYPE='text/css' MEDIA='screen'>" .
|
||||
"<title>" . $c->{$TAGS[$ENTRY]} . "</title>" . $JS_SPARSE .
|
||||
"</head><body bgcolor='white'>\n" .
|
||||
"<h1 class='title'>$apiid Reference</h1>\n" . $user_head;
|
||||
|
||||
print SPARSE $headstr;
|
||||
print SPARSE $html;
|
||||
|
||||
print SPARSE $user_foot;
|
||||
print SPARSE $footstr;
|
||||
|
||||
close SPARSE;
|
||||
}
|
||||
|
||||
sub write_toc_groups {
|
||||
my @groups = sort(keys (%groups));
|
||||
my $g;
|
||||
my $even = 1;
|
||||
my $head = "</table></center></td></tr>\n" .
|
||||
"<tr class='toc-title'><th><br><h3>Grouped Listing</h3></th>" .
|
||||
"</tr>\n";
|
||||
|
||||
print COMPLETE_TOC $head;
|
||||
print SPARSE_TOC $head;
|
||||
|
||||
for $g (@groups) {
|
||||
$head = "<tr><td class='";
|
||||
if ($even == 1) {
|
||||
$head .= "toc-group-even";
|
||||
} else {
|
||||
$head .= "toc-group-odd";
|
||||
}
|
||||
$head .= "'><center><table border='0' cellspacing='0' cellpading='0' " .
|
||||
"width='100%'>\n";
|
||||
$head .= "<tr><th><a name='GROUP_$g'>$g</a></th><td> </td></tr>\n";
|
||||
print COMPLETE_TOC $head;
|
||||
print SPARSE_TOC $head;
|
||||
my $e;
|
||||
for $e (sort(@{$groups{$g}})) {
|
||||
$c = $entries{$e};
|
||||
&add_toc_complete();
|
||||
&add_toc_sparse();
|
||||
}
|
||||
$head = "</table></center><br></td></tr>\n";
|
||||
print COMPLETE_TOC $head;
|
||||
print SPARSE_TOC $head;
|
||||
$even *= -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub add_toc_complete {
|
||||
print COMPLETE_TOC &add_toc(0);
|
||||
}
|
||||
|
||||
sub add_toc_sparse {
|
||||
print SPARSE_TOC &add_toc(1);
|
||||
}
|
||||
|
||||
sub add_toc {
|
||||
my ($is_sparse) = @_;
|
||||
my $html;
|
||||
my $classsuffix = $c->{$TAGS[$DEPRECATED]} ? "-deprecated" : "";
|
||||
|
||||
$html = "<tr><td class='toc-row$classsuffix'>";
|
||||
|
||||
$html .= &get_toc_link($c->{$TAGS[$ENTRY]}, $is_sparse,
|
||||
"toc-entry$classsuffix")
|
||||
. "</td>";
|
||||
|
||||
if ($classsuffix) {
|
||||
$html .= "<td class='toc-ind-deprecated' width='10%' " .
|
||||
"align='center' valign='center'>D</td>";
|
||||
} else {
|
||||
$html .= "<td> </td>";
|
||||
}
|
||||
|
||||
$html .= "</tr>\n";
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
sub get_link {
|
||||
my ($entry) = @_;
|
||||
return ("<a href='javascript:navToEntry(\"$entry\");'>$entry</a>");
|
||||
}
|
||||
|
||||
sub get_toc_link {
|
||||
my ($entry, $is_sparse, $class) = @_;
|
||||
|
||||
if ($is_sparse) {
|
||||
return "<a class='$class' href='api-$entry.html' " .
|
||||
"target='content-container'>$entry</a>\n";
|
||||
} else {
|
||||
return "<a href='complete.html#$entry' class='$class' " .
|
||||
"target='content-container'>$entry</a>";
|
||||
}
|
||||
}
|
||||
|
||||
sub init_files {
|
||||
|
||||
my $headstr = "<html><head><link rel=StyleSheet href='api-content.css' " .
|
||||
"TYPE='text/css' MEDIA='screen'><title>$apiid</title></head>" .
|
||||
$JS_COMPLETE . "<body bgcolor='white'>\n" .
|
||||
"<h1 class='title'>$apiid Reference</h1>\n" . $user_head;
|
||||
|
||||
print COMPLETE $headstr;
|
||||
|
||||
my $tocstr =
|
||||
("<html><head><link rel=StyleSheet href='api-toc.css' " .
|
||||
"TYPE='text/css' MEDIA='screen'>" .
|
||||
"<title>$apiid table of contents</title>" .
|
||||
"</head>\n<body bgcolor='white'>\n" .
|
||||
"<h1 class='title'>$apiid Reference</h1><h4>Table of Contents</h4>\n" .
|
||||
"<center><table class='toc-table' border='1' cellpadding='0' " .
|
||||
"cellspacing='0' width='100%'>\n" .
|
||||
"<tr class='toc-title'><th><br><h3>Alphabetical Listing</h3></th>" .
|
||||
"</tr>\n<tr><td>\n" .
|
||||
"<center><table class='toc-abc' border='0' cellspacing='0' " .
|
||||
"cellpadding='0' width='100%'>\n");
|
||||
|
||||
print COMPLETE_TOC $tocstr;
|
||||
|
||||
print SPARSE_TOC $tocstr;
|
||||
|
||||
}
|
||||
|
||||
sub close_files {
|
||||
|
||||
print COMPLETE $user_foot;
|
||||
print COMPLETE $footstr;
|
||||
close COMPLETE;
|
||||
|
||||
print COMPLETE_TOC "</table></center>" . $user_foot;
|
||||
print COMPLETE_TOC $footstr;
|
||||
close COMPLETE_TOC;
|
||||
|
||||
print SPARSE_TOC "</table></center>" . $user_foot;
|
||||
print SPARSE_TOC $footstr;
|
||||
close SPARSE_TOC;
|
||||
|
||||
}
|
||||
|
||||
sub add_leading_nbsp {
|
||||
my ($str) = @_;
|
||||
my $i;
|
||||
my $pfx = "";
|
||||
|
||||
if (!($str =~ /^(\s+)/)) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
my $len = length($1);
|
||||
for $i (0 .. $len) {
|
||||
$pfx .= " ";
|
||||
}
|
||||
|
||||
substr ($str, 0, $len) = $pfx;
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
sub debug_dump_c {
|
||||
|
||||
print ("tag: $tagname, attrs: " .
|
||||
join (", ", keys (%pending_attrs)) .
|
||||
", stacks: " . $#text_stack . ", " . $#tag_stack . ", " .
|
||||
$#attr_stack . "\n");
|
||||
|
||||
for (0 ... $#attr_stack) {
|
||||
print ("attribs at $_: " . join (", ", keys (%{$attr_stack[$_]})) .
|
||||
"\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub debug_write_entry {
|
||||
my $i;
|
||||
|
||||
for $i (keys(%{$c})) {
|
||||
my $str = "";
|
||||
if (($i eq $TAGS[$SEE_ALSO]) || ($i eq ($TAGS[$PARAM]))) {
|
||||
$str = join (", ", @{$c->{$i}});
|
||||
} else {
|
||||
$str = $c->{$i};
|
||||
}
|
||||
|
||||
print ("$i : $str\n");
|
||||
}
|
||||
print ("===\n");
|
||||
}
|
||||
|
||||
sub croak_attr {
|
||||
my ($expat, $tagname, $attr) = @_;
|
||||
|
||||
$expat->xpcroak ("Tag $tagname needs an $attr attribute");
|
||||
}
|
|
@ -0,0 +1,393 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is JavaScript Core Tests.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1997-1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above.
|
||||
# If you wish to allow use of your version of this file only
|
||||
# under the terms of the GPL and not to allow others to use your
|
||||
# version of this file under the NPL, indicate your decision by
|
||||
# deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this
|
||||
# file under either the NPL or the GPL.
|
||||
#
|
||||
|
||||
my $API = 0;
|
||||
my $ENTRY = 1;
|
||||
my $TYPE = 2;
|
||||
my $SUMMARY = 3;
|
||||
my $SYNTAX = 4;
|
||||
my $PARAM = 5;
|
||||
my $RETVAL = 6;
|
||||
my $DESCRIPTION = 7;
|
||||
my $EXAMPLE = 8;
|
||||
my $NOTE = 9;
|
||||
my $SEE_ALSO = 10;
|
||||
my $DEPRECATED = 11;
|
||||
my $EXTERNALREF = 12;
|
||||
my $GROUP = 13;
|
||||
my $C = 14;
|
||||
my $P = 15;
|
||||
my $B = 16;
|
||||
my $I = 17;
|
||||
my $COMPLETED = 18;
|
||||
my @TAGS = ("API", "ENTRY", "TYPE", "SUMMARY", "SYNTAX", "PARAM", "RETVAL",
|
||||
"DESCRIPTION", "EXAMPLE", "NOTE", "SEEALSO", "DEPRECATED",
|
||||
"EXTERNALREF", "GROUP", "C", "P", "B", "I");
|
||||
|
||||
my $NAMESPACE = ""; # "APIDOC";
|
||||
|
||||
my $TAB = " ";
|
||||
my $indent_pfx = "";
|
||||
|
||||
&parse_old_doc ();
|
||||
|
||||
sub parse_old_doc {
|
||||
my $done = 0;
|
||||
|
||||
&output ("<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>");
|
||||
&output ("<!DOCTYPE api>");
|
||||
&open_container ($TAGS[$API], "id", "JavaScript-1.5");
|
||||
&tag ($TAGS[$EXTERNALREF], "name", "LXR ID Search", "value",
|
||||
"http://lxr.mozilla.org/seamonkey/ident?i={e}");
|
||||
my $line = <>;
|
||||
|
||||
while (!$done) {
|
||||
if ($line =~ /\<H1\>\<A NAME\=\"(.*)\"\>\<\/A\>/i) {
|
||||
# beginning of a new API entry
|
||||
$line = &parse_entry ($1);
|
||||
} else {
|
||||
$line = "";
|
||||
}
|
||||
if ($line eq "") {
|
||||
$line = <> or $done = 1;
|
||||
}
|
||||
}
|
||||
&close_container ($TAGS[$API]);
|
||||
}
|
||||
|
||||
sub parse_entry {
|
||||
my $deprecated = 0;
|
||||
my ($name) = @_;
|
||||
my $line, $partialline = "";
|
||||
my $mode = $ENTRY, $submode = 0;
|
||||
|
||||
&open_container ($TAGS[$mode], "id", $name);
|
||||
|
||||
while ($mode != $COMPLETED) {
|
||||
if ($partialline) {
|
||||
$line = $partialline;
|
||||
$partialline = "";
|
||||
} else {
|
||||
$line = <>;
|
||||
}
|
||||
|
||||
if ($line =~ /\<H1\>\<A NAME\=\"(.*)\"\>\<\/A\>/i) {
|
||||
# oops, somehow we're at the next entry
|
||||
# stop what we're doing and
|
||||
# return this line to the caller
|
||||
&close_container ($TAGS[$mode]);
|
||||
$partialline = $line;
|
||||
$mode = $COMPLETED;
|
||||
} elsif ($mode == $ENTRY) {
|
||||
if ($line =~ /\<\/A\>\<\/H1\>/i) {
|
||||
$mode = $TYPE;
|
||||
}
|
||||
} elsif ($mode == $TYPE) {
|
||||
if ($line =~ /\<A NAME=\"\d+\"\>/i) {
|
||||
# useless line
|
||||
} elsif ($line =~ /([^\.]+).\s+(.*)/) {
|
||||
&tag ($TAGS[$mode], "value", $1);
|
||||
if ($2) {
|
||||
$mode = $SUMMARY;
|
||||
&open_container ($TAGS[$mode]);
|
||||
$partialline = $2;
|
||||
}
|
||||
if ($line =~ /deprecated/i) {
|
||||
$deprecated = 1;
|
||||
}
|
||||
}
|
||||
} elsif ($mode == $SUMMARY) {
|
||||
if ($line =~ /deprecated/i) {
|
||||
$deprecated = 1;
|
||||
}
|
||||
if ($line =~ /(.*)?(\<\/A\>\<\/P\>)$/) {
|
||||
&output (&fixup($1));
|
||||
# if line ended with </A></P>, we're at the end of the summary
|
||||
&close_container ($TAGS[$mode]);
|
||||
$mode = $SYNTAX;
|
||||
} else {
|
||||
&output ($line);
|
||||
}
|
||||
} elsif (($mode == $SYNTAX) || ($mode == $DESCRIPTION) ||
|
||||
($mode == $EXAMPLE) || ($mode == $NOTE)) {
|
||||
if ($submode == 0) {
|
||||
if ($line =~ /\<\/A\>\<\/H4\>/) {
|
||||
if ($mode == $EXAMPLE) {
|
||||
$line = <>;
|
||||
$line = <>; # eat two useless lines
|
||||
$line = <>; # next is the description
|
||||
&open_container ($TAGS[$mode], "desc",
|
||||
&fixup_all($line));
|
||||
# are you having fun yet?
|
||||
} else {
|
||||
&open_container ($TAGS[$mode]);
|
||||
}
|
||||
$submode = 1;
|
||||
}
|
||||
} elsif ($submode == 1) {
|
||||
if ($line =~ /<H4><A NAME="Head3;"><\/A>/) {
|
||||
#start of a new section
|
||||
&close_container ($TAGS[$mode]);
|
||||
$submode = 0;
|
||||
$line = <>;
|
||||
$mode = $COMPLETED;
|
||||
if ($line =~ /\<A NAME\=\"\d+\">/) {
|
||||
$line = <>;
|
||||
if ($line =~ /(description|example|note|see also)/i) {
|
||||
if (lc($1) eq "description") {
|
||||
$mode = $DESCRIPTION;
|
||||
} elsif (lc($1) eq "example") {
|
||||
$mode = $EXAMPLE;
|
||||
} elsif (lc($1) eq "note") {
|
||||
$mode = $NOTE;
|
||||
} else {
|
||||
$mode = $SEE_ALSO;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elsif ($line =~ /<BLOCKQUOTE><B>NOTE:/) {
|
||||
# note embedded in description section
|
||||
&close_container ($TAGS[$mode]);
|
||||
$mode = $NOTE;
|
||||
&open_container ($TAGS[$mode]);
|
||||
} elsif (($mode == $NOTE) && ($line =~ /<\/BLOCKQUOTE>/)) {
|
||||
# note over
|
||||
$partialline = '<H4><A NAME="Head3;"></A>';
|
||||
# dirty little hack to get it to execute the
|
||||
# 'figure out next mode' logic above.
|
||||
} elsif (($mode == $SYNTAX) || ($mode == $EXAMPLE)) {
|
||||
if (($mode == $SYNTAX) &&
|
||||
($line =~ /(.*)<TABLE BORDER="0">/)) {
|
||||
# syntax parameter table start
|
||||
$line = $1;
|
||||
$submode = 2;
|
||||
}
|
||||
$_ = $line;
|
||||
s/<br>/\n/ig;
|
||||
s/<[^>]*>//g;
|
||||
s/^\s*//g;
|
||||
s/\s*$//g;
|
||||
s/ / /g;
|
||||
if (/[\S\N]/) {
|
||||
print ("$_\n");
|
||||
}
|
||||
} elsif ($line =~ /(.*)<TABLE BORDER="0">/) {
|
||||
&output (&fixup($1));
|
||||
&output ("<![CDATA[");
|
||||
&output ('<TABLE BORDER="0">');
|
||||
$submode = 2;
|
||||
} elsif ($line =~ /<ul><P><LI>/) {
|
||||
&output ("<![CDATA[");
|
||||
&output (&fixup_cdata($line));
|
||||
$submode = 2;
|
||||
} else {
|
||||
# if all else f[l]ails, just print it.
|
||||
&output (&fixup($line));
|
||||
}
|
||||
} elsif (($mode == $SYNTAX) && ($submode == 2)) {
|
||||
# inside parameter list table
|
||||
my $col = 0;
|
||||
my $name, $type, $desc = "";
|
||||
$line = <>;
|
||||
while (!($line =~ /<\/TABLE>/)) {
|
||||
if ((($col == 0) || ($col == 1)) &&
|
||||
($line =~ /(.*)<\/A><\/P>/)) {
|
||||
$1 =~ /<CODE>(.*)<\/CODE>/;
|
||||
if ($col == 0) {
|
||||
$name = $1;
|
||||
$col = 1;
|
||||
} else {
|
||||
$type = $1;
|
||||
$col = 2;
|
||||
}
|
||||
} elsif (($col == 2) &&
|
||||
(!($line =~
|
||||
/<TR><TD VALIGN=baseline ALIGN=left>/))) {
|
||||
$desc .= &fixup_more ($line);
|
||||
} elsif ($col == 2) {
|
||||
&open_container ($TAGS[$PARAM], "name", $name,
|
||||
"type", $type);
|
||||
&output ($desc);
|
||||
&close_container ($TAGS[$PARAM]);
|
||||
$name = "";
|
||||
$type = "";
|
||||
$desc = "";
|
||||
$col = 0;
|
||||
}
|
||||
$line = <>;
|
||||
}
|
||||
&open_container ($TAGS[$PARAM], "name", $name,
|
||||
"type", $type);
|
||||
&output ($desc);
|
||||
&close_container ($TAGS[$PARAM]);
|
||||
$submode = 1;
|
||||
} elsif ($submode == 2) {
|
||||
if (($line =~ /<\/TABLE>/) || ($line =~ /<\/ul>/)) {
|
||||
&output (&fixup_cdata ($line));
|
||||
&output ("]]>");
|
||||
$submode = 1;
|
||||
} else {
|
||||
&output (&fixup_cdata ($line));
|
||||
}
|
||||
}
|
||||
} elsif ($mode == $SEE_ALSO) {
|
||||
if ($line =~ /(.*)<\/P>/) {
|
||||
my $list = &fixup ($1);
|
||||
my @refs = split(/,\s*/, $list);
|
||||
for (@refs) {
|
||||
if ($_) {
|
||||
&tag ($TAGS[$mode], "value", $_);
|
||||
}
|
||||
}
|
||||
$mode = $COMPLETED;
|
||||
}
|
||||
} else {
|
||||
die ("Unknown mode '$mode' encountered.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode != $COMPLETED) {
|
||||
die ("Bad state");
|
||||
}
|
||||
|
||||
if ($deprecated) {
|
||||
&tag ($TAGS[$DEPRECATED]);
|
||||
}
|
||||
&close_container ($TAGS[$ENTRY]);
|
||||
|
||||
return $partialline;
|
||||
|
||||
}
|
||||
|
||||
sub output {
|
||||
my ($line) = @_;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
if (!($line =~ /^\n*$/)) {
|
||||
$_ = $line;
|
||||
s/\n*$//;
|
||||
s/^\s*\n*//;
|
||||
if (/[\S\N]/) {
|
||||
print $indent_pfx . $_ . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub fixup_all {
|
||||
# wipe out ALL markup
|
||||
($_) = @_;
|
||||
s/<[^>]*>//g;
|
||||
s/\n//g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub fixup_more {
|
||||
# all fixups, plus paragraph->br
|
||||
($_) = @_;
|
||||
$_ = &fixup($_);
|
||||
s/<P\/>/<BR\/>/g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub fixup {
|
||||
# clean up all markup, and change HTML tags to XML tags
|
||||
($_) = @_;
|
||||
|
||||
s/<CODE>/<C>/g;
|
||||
s/<\/CODE>/<\/C>/g;
|
||||
s/<BR>//ig;
|
||||
s/<\/P>|<P>/<P\/>/g;
|
||||
s/(<P\/>)+/<P\/>/g;
|
||||
return &fixup_cdata($_);
|
||||
}
|
||||
|
||||
sub fixup_cdata {
|
||||
# clean up markup for use in <![CDATA[ tags
|
||||
($_) = @_;
|
||||
s/<TD VALIGN=(.*) ALIGN=([^>]*)>/<TD VALIGN='$1' ALIGN='$2'\>/g;
|
||||
s/<TR><TD VALIGN='baseline' ALIGN='left'><P>/<\/TD><\/TR><TR> <TD VALIGN='baseline' ALIGN='left'><P>/g;
|
||||
s/<\/B><\/A><TD VALIGN='baseline' ALIGN='left'>/<\/B><\/TD><TD VALIGN='baseline' ALIGN='left'>/ig;
|
||||
s/<\/P><TD VALIGN='baseline' ALIGN='left'>/<\/TD><TD VALIGN='baseline' ALIGN='left'>/g;
|
||||
s/<\/TABLE>/<\/TD><\/TR><\/TABLE >/g;
|
||||
s/<PRE>|<\/PRE>//g;
|
||||
s/<BR>/<BR\/>/ig;
|
||||
s/\<A[^\>]+\>//g;
|
||||
s/\<\/A\>//g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub open_container {
|
||||
my ($tag_name) = @_;
|
||||
&open_tag (1, @_);
|
||||
$indent_pfx .= $TAB;
|
||||
}
|
||||
|
||||
sub tag {
|
||||
&open_tag (0, @_);
|
||||
}
|
||||
|
||||
sub open_tag {
|
||||
my $iscontainer = shift(@_);
|
||||
my $tagname = shift(@_);
|
||||
my @attrs = @_;
|
||||
my $attrname;
|
||||
my $tag = "";
|
||||
|
||||
$tag .= "<";
|
||||
|
||||
if ($NAMESPACE) {
|
||||
$tag .= "$NAMESPACE:";
|
||||
}
|
||||
|
||||
$tag .= $tagname;
|
||||
|
||||
while ($attrname = shift(@attrs)) {
|
||||
$tag .= " $attrname='" . shift (@attrs) . "'";
|
||||
}
|
||||
|
||||
if (!$iscontainer) {
|
||||
$tag .= "/";
|
||||
}
|
||||
|
||||
$tag .= ">";
|
||||
&output ($tag);
|
||||
}
|
||||
|
||||
sub close_container {
|
||||
my ($tag_name) = @_;
|
||||
|
||||
substr($indent_pfx, 0, length($TAB)) = "";
|
||||
my $tag = "</";
|
||||
if ($NAMESPACE) {
|
||||
$tag .= "$NAMESPACE:";
|
||||
}
|
||||
&output ($tag . "$tag_name>");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<frameset name='doc-frameset' cols='30%,*'>
|
||||
<frame name='toc-container' src='apidocs/sparse-toc.html'>
|
||||
<frame name='content-container' src='about:blank'>
|
||||
</frameset>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
|
||||
<!DOCTYPE api>
|
||||
<API id='basic test 1'>
|
||||
<HEAD>
|
||||
This is the heading.
|
||||
</HEAD>
|
||||
<FOOT>
|
||||
Don't look here!
|
||||
</FOOT>
|
||||
<EXTERNALREF name="LXR ID Lookup" value="http://lxr.mozilla.org/mozilla/ident?i={e}"/>
|
||||
<ENTRY id="foo">
|
||||
<TYPE value="Function"/>
|
||||
<SUMMARY>
|
||||
<C>foo</C> is cool.
|
||||
</SUMMARY>
|
||||
<DESCRIPTION>
|
||||
<C>foo</C> is the function you want to use. Other functions
|
||||
like <C>bar</C> and <C>baz</C> aren't half as good as foo.
|
||||
The <S>JSBot page</S> is badly out of date. The <S>Function</S>
|
||||
group has other functions in this api.
|
||||
</DESCRIPTION>
|
||||
<SYNTAX>
|
||||
void foo(int x, float y)
|
||||
<PARAM name="x" type="int">
|
||||
Does what x does.
|
||||
</PARAM>
|
||||
<PARAM name="y" type="float">
|
||||
Does what y does, better than x.
|
||||
</PARAM>
|
||||
</SYNTAX>
|
||||
<EXAMPLE desc="Do it like this or you will suffer!">
|
||||
foo (1, 2) /* calls foo */
|
||||
foo (3, 4) /* calls foo with better arguments*/
|
||||
</EXAMPLE>
|
||||
<EXTERNALREF name="JSBot page" value="http://www.ndcico.com/jsbot"/>
|
||||
<SEEALSO value="bar"/>
|
||||
</ENTRY>
|
||||
|
||||
<ENTRY id="bar">
|
||||
<DEPRECATED/>
|
||||
<TYPE value="Function"/>
|
||||
<SUMMARY>
|
||||
<C>bar</C> is lame.
|
||||
</SUMMARY>
|
||||
<DESCRIPTION>
|
||||
<C>bar</C> is less than half as good as <C>foo</C>.
|
||||
</DESCRIPTION>
|
||||
<SYNTAX>
|
||||
void bar(int x, float y)
|
||||
<PARAM name="x" type="int">
|
||||
Does what x does.
|
||||
</PARAM>
|
||||
<PARAM name="y" type="float">
|
||||
Does what y does, better than x.
|
||||
</PARAM>
|
||||
</SYNTAX>
|
||||
<EXAMPLE desc="Do it like this or you will suffer!">
|
||||
bar (1, 2) /* calls bar */
|
||||
bar (3, 4) /* calls bar with worser arguments*/
|
||||
</EXAMPLE>
|
||||
<GROUP name="Useless Functions"/>
|
||||
</ENTRY>
|
||||
|
||||
<GROUP name="Useless Functions" value="bar"/>
|
||||
<GROUP name="Cool Functions" value="foo"/>
|
||||
|
||||
</API>
|
Загрузка…
Ссылка в новой задаче