#!/usr/bin/perl -- # -*- Perl -*-
use
vars
qw(@elements %elements %attlists)
;
use
vars
qw(@entities %entities @notations %notations)
;
use
vars
qw($usage %option %config $fileext $baseid)
;
use
vars
qw($xmldtd $basedir $dtd)
;
use
vars
qw(%ELEMBASE %ENTBASE %NOTBASE %ROOTS)
;
use
vars
qw(%APPEARSIN %EAPPEARSIN %XAPPEARSIN)
;
use
vars
qw(%PARENTS %CHILDREN)
;
use
vars
qw(%ELEMINCL %ELEMEXCL %POSSINCL %POSSEXCL)
;
$VERSION
=
$SGML::DTDParse::VERSION
;
$expanded
=
'expanded'
;
$usage
=
"$0 version $VERSION\nUsage: $0 [ options ] dtd[.xml]\n"
;
%option
= (
'synopsis'
=> 1,
'content-model'
=> 1,
'attributes'
=> 1,
'inclusions'
=> 1,
'exclusions'
=> 1,
'tag-minimization'
=> 1,
'appears-in'
=> 1,
'description'
=> 1,
'attributes'
=> 1,
'parents'
=> 1,
'children'
=> 1,
'examples'
=> 1,
'base-dir'
=>
""
,
'base-id'
=>
undef
,
'debug'
=> 0,
'unexpanded'
=> 1,
'verbose'
=> 1,
'include-sdata'
=> 0,
'include-charent'
=> 0,
'include-ms'
=> 0,
'elements'
=> 1,
'entities'
=> 1,
'notations'
=> 1);
%config
= (
'expanded-element-dir'
=>
'elements'
,
'unexpanded-element-dir'
=>
'dtdelem'
,
'expanded-entity-dir'
=>
'entities'
,
'unexpanded-entity-dir'
=>
'dtdent'
,
'notation-dir'
=>
'notations'
,
'home'
=>
'index'
.
$fileext
,
'expanded-element-index'
=>
"index"
.
$fileext
,
'unexpanded-element-index'
=>
"dtdelem"
.
$fileext
,
'expanded-entity-index'
=>
"entities"
.
$fileext
,
'unexpanded-entity-index'
=>
"dtdent"
.
$fileext
,
'notation-index'
=>
'notations'
.
$fileext
);
my
%opt
= ();
&GetOptions
(\
%opt
,
'html'
,
'refentry'
,
'debug+'
,
'verbose!'
,
'synopsis!'
,
'content-model!'
,
'attributes!'
,
'inclusions!'
,
'exclusions!'
,
'tag-minimization!'
,
'include-sdata!'
,
'include-charent!'
,
'include-ms!'
,
'appears-in!'
,
'description!'
,
'attributes!'
,
'parents!'
,
'chilren!'
,
'examples!'
,
'library=s@'
,
'unexpanded!'
,
'base-dir=s'
,
'base-id=s'
,
'elements!'
,
'entities!'
,
'notations!'
,
@SGML::DTDParse::CommonOptions
) || SGML::DTDParse::usage(
-verbose
=> 0,
-exitval
=> 1);
SGML::DTDParse::process_common_options(\
%opt
);
if
(
$opt
{
'html'
} &&
$opt
{
'refentry'
}) {
die
"Error: You can't specify both --html and --refentry.\n"
;
}
if
(!
$opt
{
'html'
} && !
$opt
{
'refentry'
}) {
if
($0 =~ /html$/) {
$opt
{
'html'
} = 1;
}
elsif
($0 =~ /refentry$/ || $0 =~ /man$/) {
$opt
{
'refentry'
} = 1;
}
else
{
die
"Error: You must specify either --html or --refentry.\n"
;
}
}
if
(
$opt
{
'html'
}) {
&status
(
"Formatting HTML."
,1);
require
'SGML/DTDParse/Format/html.pl'
;
}
elsif
(
$opt
{
'refentry'
}) {
&status
(
"Formating DocBook RefEntrys."
,1);
require
'SGML/DTDParse/Format/refentry.pl'
;
}
my
@libraries
=
exists
(
$opt
{
'library'
}) ? @{
$opt
{
'library'
}} : ();
if
(
@libraries
) {
foreach
my
$userlib
(
@libraries
) {
require
$userlib
;
}
}
else
{
my
$plain
=
"SGML/DTDParse/Format/plain.pl"
;
&status
(
"Using plain library."
,1);
require
$plain
;
}
foreach
my
$key
(
keys
%option
) {
$option
{
$key
} =
$opt
{
$key
}
if
exists
$opt
{
$key
};
}
if
(!
defined
(
$option
{
'base-id'
})) {
$baseid
=
"dtdparse"
;
if
(
$opt
{
'refentry'
}) {
&status
(
"No base-id specified, \"$baseid\" will be used."
,1);
}
}
else
{
$baseid
=
$option
{
'base-id'
};
}
select
(STDOUT); $| = 1;
$xmldtd
=
shift
@ARGV
||
die
$usage
;
$xmldtd
.=
".xml"
if
(
$xmldtd
=~ /\.dtd$/) && -f
$xmldtd
.
".xml"
;
if
(! -f
$xmldtd
) {
$xmldtd
.=
".xml"
if
-f
$xmldtd
.
".xml"
;
die
"$0: cannot load $xmldtd\[.xml\].\n"
if
! -f
$xmldtd
;
}
if
(
$option
{
'base-dir'
} ne
""
) {
$basedir
=
$option
{
'base-dir'
};
}
else
{
$basedir
=
$xmldtd
;
$basedir
=~ s/\\/\//g;
$basedir
=~ s/^.*\/([^\/]+)$/$1/;
$basedir
=~ s/^([^\.]+).*$/$1/;
$option
{
'base-dir'
} =
$basedir
;
}
my
$parser
= new XML::DOM::Parser (
NoExpand
=> 0);
&status
(
"Loading $xmldtd..."
);
$dtd
=
$parser
->parsefile(
$xmldtd
);
foreach
my
$opt
(
'namecase-general'
,
'namecase-entity'
,
'unexpanded'
,
'xml'
) {
$option
{
$opt
} =
$dtd
->getDocumentElement()->getAttribute(
$opt
);
}
&createDir
(
$basedir
, 0755)
if
! -d
$basedir
;
&checkDir
(
$basedir
);
foreach
my
$key
(
'expanded-element-dir'
,
'expanded-entity-dir'
,
'notation-dir'
) {
my
$dir
=
$basedir
.
"/"
.
$config
{
$key
};
&createDir
(
$dir
, 0755)
if
! -d
$dir
;
&checkDir
(
$dir
);
}
if
(
$option
{
'unexpanded'
}) {
foreach
my
$key
(
'unexpanded-element-dir'
,
'unexpanded-entity-dir'
) {
my
$dir
=
$basedir
.
"/"
.
$config
{
$key
};
&createDir
(
$dir
, 0755)
if
! -d
$dir
;
&checkDir
(
$dir
);
}
}
my
$elemnodelist
=
$dtd
->getElementsByTagName(
"element"
);
%elements
= ();
for
(
my
$count
= 0;
$count
<
$elemnodelist
->getLength();
$count
++) {
my
$element
=
$elemnodelist
->item(
$count
);
my
$name
=
$element
->getAttribute(
'name'
);
$name
=
lc
(
$name
)
if
$option
{
'namecase-general'
};
$elements
{
$name
} =
$element
;
}
@elements
=
sort
{
uc
(
$a
) cmp
uc
(
$b
) }
keys
%elements
;
%ELEMBASE
=
&basenames
(
@elements
);
my
$entnodelist
=
$dtd
->getElementsByTagName(
"entity"
);
%entities
= ();
for
(
my
$count
= 0;
$count
<
$entnodelist
->getLength();
$count
++) {
my
$entity
=
$entnodelist
->item(
$count
);
my
$name
=
$entity
->getAttribute(
'name'
);
$name
=
lc
(
$name
)
if
$option
{
'namecase-entity'
};
$entities
{
$name
} =
$entity
;
}
@entities
=
sort
{
uc
(
$a
) cmp
uc
(
$b
) }
keys
%entities
;
%ENTBASE
=
&basenames
(
@entities
);
my
$notnodelist
=
$dtd
->getElementsByTagName(
"notation"
);
%notations
= ();
for
(
my
$count
= 0;
$count
<
$notnodelist
->getLength();
$count
++) {
my
$notation
=
$notnodelist
->item(
$count
);
my
$name
=
$notation
->getAttribute(
'name'
);
$notations
{
$name
} =
$notation
;
}
@notations
=
sort
{
uc
(
$a
) cmp
uc
(
$b
) }
keys
%notations
;
%NOTBASE
=
&basenames
(
@notations
);
&status
(
"Calculating parents and children..."
);
%PARENTS
= ();
%CHILDREN
= ();
%ELEMINCL
= ();
%ELEMEXCL
= ();
%POSSINCL
= ();
%POSSEXCL
= ();
foreach
my
$element
(
values
%elements
) {
my
$cm
=
$element
->getElementsByTagName(
'content-model-expanded'
);
my
$incl
=
$element
->getElementsByTagName(
'inclusions'
);
my
$excl
=
$element
->getElementsByTagName(
'exclusions'
);
my
$chlist
=
$cm
->item(0)->getElementsByTagName(
'element-name'
);
my
$pname
=
$element
->getAttribute(
'name'
);
$pname
=
lc
(
$pname
)
if
$option
{
'namecase-general'
};
for
(
my
$chcount
= 0;
$chcount
<
$chlist
->getLength();
$chcount
++) {
my
$child
=
$chlist
->item(
$chcount
);
my
$cname
=
$child
->getAttribute(
'name'
);
$cname
=
lc
(
$cname
)
if
$option
{
'namecase-general'
};
$PARENTS
{
$cname
} = {}
if
!
exists
(
$PARENTS
{
$cname
});
$PARENTS
{
$cname
}->{
$pname
} = 0
if
!
exists
(
$PARENTS
{
$cname
}->{
$pname
});
$PARENTS
{
$cname
}->{
$pname
}++;
$CHILDREN
{
$pname
} = {}
if
!
exists
(
$CHILDREN
{
$pname
});
$CHILDREN
{
$pname
}->{
$cname
} = 0
if
!
exists
(
$CHILDREN
{
$pname
}->{
$cname
});
$CHILDREN
{
$pname
}->{
$cname
}++;
}
if
(
$incl
&&
$incl
->getLength() > 0) {
$chlist
=
$incl
->item(0)->getElementsByTagName(
'element-name'
);
for
(
my
$chcount
= 0;
$chcount
<
$chlist
->getLength();
$chcount
++) {
my
$child
=
$chlist
->item(
$chcount
);
my
$cname
=
$child
->getAttribute(
'name'
);
$cname
=
lc
(
$cname
)
if
$option
{
'namecase-general'
};
$ELEMINCL
{
$pname
} = {}
if
!
exists
(
$ELEMINCL
{
$pname
});
$ELEMINCL
{
$pname
}->{
$cname
} = 1;
}
}
if
(
$excl
&&
$excl
->getLength() > 0) {
$chlist
=
$excl
->item(0)->getElementsByTagName(
'element-name'
);
for
(
my
$chcount
= 0;
$chcount
<
$chlist
->getLength();
$chcount
++) {
my
$child
=
$chlist
->item(
$chcount
);
my
$cname
=
$child
->getAttribute(
'name'
);
$cname
=
lc
(
$cname
)
if
$option
{
'namecase-general'
};
$ELEMEXCL
{
$pname
} = {}
if
!
exists
(
$ELEMEXCL
{
$pname
});
$ELEMEXCL
{
$pname
}->{
$cname
} = 1;
}
}
}
&status
(
"Propagating inclusions and exclusions..."
);
&propagateInclExcl
();
%ROOTS
= ();
foreach
my
$element
(
values
%elements
) {
my
$pname
=
$element
->getAttribute(
'name'
);
$pname
=
lc
(
$pname
)
if
$option
{
'namecase-general'
};
$ROOTS
{
$pname
} =
$element
if
!
exists
(
$PARENTS
{
$pname
});
}
my
%allincl
= ();
foreach
my
$element
(
keys
%POSSINCL
) {
my
%incl
= %{
$POSSINCL
{
$element
}};
foreach
my
$key
(
keys
%incl
) {
$allincl
{
$key
} = 1;
}
}
foreach
my
$element
(
keys
%allincl
) {
delete
$ROOTS
{
$element
}
if
exists
$ROOTS
{
$element
};
}
&status
(
"Finding Attribute Lists..."
);
%attlists
= ();
my
$attlistnodelist
=
$dtd
->getElementsByTagName(
"attlist"
);
for
(
my
$count
= 0;
$count
<
$attlistnodelist
->getLength();
$count
++) {
my
$node
=
$attlistnodelist
->item(
$count
);
my
$name
=
$node
->getAttribute(
'name'
);
$name
=
lc
(
$name
)
if
$option
{
'namecase-general'
};
$attlists
{
$name
} =
$node
;
}
%APPEARSIN
= ();
%EAPPEARSIN
= ();
%XAPPEARSIN
= ();
if
(
$option
{
'appears-in'
}) {
&status
(
"Calculating appears-in..."
);
&calculateAppearsIn
();
&calculateEntityAppearsIn
();
}
&status
(
"Writing Index Pages..."
);
&writeElementIndexes
(
$basedir
);
&writeEntityIndexes
(
$basedir
);
&writeNotationIndexes
(
$basedir
);
&writeIndex
(
$basedir
);
if
(
$option
{
'unexpanded'
}) {
$expanded
=
'unexpanded'
;
&writeElementIndexes
(
$basedir
);
&writeEntityIndexes
(
$basedir
);
$expanded
=
'expanded'
;
}
&status
(
"Writing Elements..."
,1);
for
(
my
$count
= 0;
$option
{
'elements'
} && (
$count
<=
$#elements
);
$count
++) {
my
$name
=
$elements
[
$count
];
my
$element
=
$elements
{
$name
};
my
$path
=
$basedir
.
"/"
.
$config
{
'expanded-element-dir'
};
my
$basename
=
$ELEMBASE
{
$name
};
my
$html
=
""
;
&status
(
$element
->getAttribute(
'name'
));
$expanded
=
'expanded'
;
$html
=
&formatElement
(
$count
);
&writeElement
(
$count
,
$path
,
$basename
,
$fileext
,
$html
);
if
(
$option
{
'unexpanded'
}) {
$expanded
=
'unexpanded'
;
$path
=
$basedir
.
"/"
.
$config
{
'unexpanded-element-dir'
};
$html
=
&formatElement
(
$count
);
&writeElement
(
$count
,
$path
,
$basename
,
$fileext
,
$html
);
}
}
&status
(
"Writing Entities..."
,1);
for
(
my
$count
= 0;
$option
{
'entities'
} && (
$count
<=
$#entities
);
$count
++) {
my
$name
=
$entities
[
$count
];
my
$entity
=
$entities
{
$name
};
my
$etype
=
&entityType
(
$entity
);
my
$path
=
$basedir
.
"/"
.
$config
{
'expanded-entity-dir'
};
my
$basename
=
$ENTBASE
{
$name
};
my
$html
=
""
;
&status
(
$entity
->getAttribute(
'name'
));
$expanded
=
'expanded'
;
$html
=
""
;
if
(
$etype
eq
'sdata'
) {
$html
=
&formatEntity
(
$count
)
if
$option
{
'include-sdata'
};
}
elsif
(
$etype
eq
'msparam'
) {
$html
=
&formatEntity
(
$count
)
if
$option
{
'include-ms'
};
}
elsif
(
$etype
eq
'charent'
) {
$html
=
&formatEntity
(
$count
)
if
$option
{
'include-charent'
};
}
else
{
$html
=
&formatEntity
(
$count
);
}
&writeEntity
(
$count
,
$path
,
$basename
,
$fileext
,
$html
);
if
(
$option
{
'unexpanded'
}) {
$expanded
=
'unexpanded'
;
$path
=
$basedir
.
"/"
.
$config
{
'unexpanded-entity-dir'
};
$html
=
""
;
if
(
$etype
eq
'sdata'
) {
$html
=
&formatEntity
(
$count
)
if
$option
{
'include-sdata'
};
}
elsif
(
$etype
eq
'msparam'
) {
$html
=
&formatEntity
(
$count
)
if
$option
{
'include-ms'
};
}
else
{
$html
=
&formatEntity
(
$count
);
}
&writeEntity
(
$count
,
$path
,
$basename
,
$fileext
,
$html
);
}
}
&status
(
"Writing Notations..."
,1);
$expanded
=
'expanded'
;
for
(
my
$count
= 0;
$option
{
'notations'
} && (
$count
<=
$#notations
);
$count
++) {
my
$name
=
$notations
[
$count
];
my
$notation
=
$notations
{
$name
};
my
$path
=
$basedir
.
"/"
.
$config
{
'notation-dir'
};
my
$basename
=
$NOTBASE
{
$name
};
my
$html
=
""
;
&status
(
$notation
->getAttribute(
'name'
));
$html
=
&formatNotation
(
$count
);
&writeNotation
(
$count
,
$path
,
$basename
,
$fileext
,
$html
);
}
&status
(
"Done."
,1);
print
"\n"
;
exit
;
sub
createDir {
my
$dir
=
shift
;
my
$mode
=
shift
;
mkdir
(
$dir
,
$mode
);
}
sub
checkDir {
my
$dir
=
shift
;
die
"$0: Failed to create $dir.\n"
if
! -d
$dir
;
}
sub
writeElement {
my
$count
=
shift
;
my
$path
=
shift
;
my
$basename
=
shift
;
my
$fileext
=
shift
;
my
$html
=
shift
;
open
(F,
">$path/"
.
$basename
.
$fileext
);
print
F
$html
;
close
(F);
}
sub
writeEntity {
my
$count
=
shift
;
my
$path
=
shift
;
my
$basename
=
shift
;
my
$fileext
=
shift
;
my
$html
=
shift
;
open
(F,
">$path/"
.
$basename
.
$fileext
);
print
F
$html
;
close
(F);
}
sub
writeNotation {
my
$count
=
shift
;
my
$path
=
shift
;
my
$basename
=
shift
;
my
$fileext
=
shift
;
my
$html
=
shift
;
open
(F,
">$path/"
.
$basename
.
$fileext
);
print
F
$html
;
close
(F);
}
sub
basenames {
my
@names
=
@_
;
my
%basename
= ();
my
%usedname
= ();
foreach
my
$name
(
@names
) {
my
$count
= 2;
my
$bname
=
lc
(
$name
);
if
(
$usedname
{
$bname
}) {
$bname
=
lc
(
$name
) .
$count
;
while
(
$usedname
{
$bname
}) {
$bname
++;
}
}
$basename
{
$name
} =
$bname
;
$usedname
{
$name
} = 1;
}
return
%basename
;
}
sub
entityType {
my
$ent
=
shift
;
my
$textnl
=
$ent
->getElementsByTagName(
"text"
);
my
$text
=
$textnl
->item(0);
my
$type
=
$ent
->getAttribute(
'type'
);
if
(
$type
eq
'param'
) {
if
(
$ent
->getAttribute(
'system'
) ||
$ent
->getAttribute(
'public'
)) {
$type
=
'paramext'
;
}
elsif
(
$text
&&
$text
->getFirstChild()) {
my
$data
=
$text
->getFirstChild()->getData();
if
(
$data
eq
'INCLUDE'
||
$data
eq
'IGNORE'
) {
$type
=
'msparam'
;
}
}
}
elsif
((
$type
eq
'gen'
) || (
$type
eq
'cdata'
)) {
if
(
$text
&&
$text
->getFirstChild()) {
my
$data
=
$text
->getFirstChild()->getData();
if
(
$data
=~ /^\&\
||
$data
=~ /^\&\
$type
=
'charent'
;
}
}
}
return
$type
;
}
sub
propagateInclExcl {
my
$totelem
=
$#elements
+1;
my
$count
= 0;
foreach
my
$name
(
@elements
) {
my
%children
= ();
my
%checked
= ();
my
@tocheck
= ();
my
%excl
= ();
my
%incl
= ();
%children
= %{
$CHILDREN
{
$name
}}
if
exists
$CHILDREN
{
$name
};
&status
(
sprintf
(
"Propagating inclusions and exclusions: %5.1f%%"
,
$count
/
$totelem
* 100.0));
$count
++;
@tocheck
=
keys
%{
$PARENTS
{
$name
}}
if
exists
$PARENTS
{
$name
};
while
(
@tocheck
) {
my
$parent
=
shift
@tocheck
;
if
(
exists
$ELEMINCL
{
$parent
}) {
foreach
my
$element
(
keys
%{
$ELEMINCL
{
$parent
}}) {
$incl
{
$element
} = 1;
}
}
if
(
exists
$ELEMEXCL
{
$parent
}) {
foreach
my
$element
(
keys
%{
$ELEMEXCL
{
$parent
}}) {
$excl
{
$element
} = 1;
}
}
if
(
exists
$PARENTS
{
$parent
}) {
foreach
my
$element
(
keys
%{
$PARENTS
{
$parent
}}) {
push
(
@tocheck
,
$element
)
unless
$checked
{
$element
};
$checked
{
$element
} = 1;
}
}
}
foreach
my
$element
(
keys
%excl
) {
delete
$excl
{
$element
}
if
!
exists
$children
{
$element
};
}
if
(
%excl
) {
$POSSEXCL
{
$name
} = {};
%{
$POSSEXCL
{
$name
}} =
%excl
;
}
if
(
exists
$ELEMEXCL
{
$name
}) {
foreach
my
$element
(
keys
%incl
) {
delete
$incl
{
$element
}
if
exists
$ELEMEXCL
{
$name
}->{
$element
};
}
}
if
(
%incl
) {
$POSSINCL
{
$name
} = {};
%{
$POSSINCL
{
$name
}} =
%incl
;
}
}
}
sub
calculateAppearsIn {
my
$totent
=
$#entities
+ 1;
my
$count
= 0;
foreach
my
$entname
(
@entities
) {
my
$entity
=
$entities
{
$entname
};
my
$expnl
=
$entity
->getElementsByTagName(
"text-expanded"
);
my
$uexpnl
=
$entity
->getElementsByTagName(
"text"
);
my
$node
=
undef
;
my
$cnode
=
undef
;
my
$text
=
undef
;
&status
(
sprintf
(
"Calculating appears-in: %5.1f%%"
,
$count
/
$totent
* 100.0));
$count
++;
$node
=
$expnl
->item(0)
if
$expnl
;
$cnode
=
$node
->getFirstChild()
if
$node
;
$text
=
$cnode
->getData()
if
$cnode
;
if
(
&cmFragment
(
$text
)) {
while
(
$text
=~ /[-a-z0-9.:_]+/is) {
my
$pre
= $`;
my
$match
= $&;
$text
= $';
my
$name
=
$match
;
$name
=
lc
(
$name
)
if
$option
{
'namecase-general'
};
$APPEARSIN
{
$name
} = {}
if
!
exists
$APPEARSIN
{
$name
};
$APPEARSIN
{
$name
}->{
$entname
} = 1;
}
}
$text
=
undef
;
$node
=
$uexpnl
->item(0)
if
$uexpnl
;
$cnode
=
$node
->getFirstChild()
if
$node
;
$text
=
$cnode
->getData()
if
$cnode
;
while
(
$text
=~ /\%([^\s;]+);?/is) {
my
$pre
= $`;
my
$match
= $1;
$text
= $';
my
$name
=
"%$match"
;
$APPEARSIN
{
$name
} = {}
if
!
exists
$APPEARSIN
{
$name
};
$APPEARSIN
{
$name
}->{
$entname
} = 1;
}
}
}
sub
calculateEntityAppearsIn {
my
$totelem
=
$#elements
+ 1;
my
$count
= 0;
foreach
my
$elemname
(
@elements
) {
my
$element
=
$elements
{
$elemname
};
my
$cmlist
=
$element
->getElementsByTagName(
'content-model'
);
&status
(
sprintf
(
"Calculating entity appears-in: %5.1f%%"
,
$count
/
$totelem
* 100.0));
$count
++;
if
(
$cmlist
->getLength() > 0) {
my
$cm
=
$cmlist
->item(0);
my
$pelist
=
$cm
->getElementsByTagName(
'parament-name'
);
for
(
my
$cnt
= 0;
$cnt
<
$pelist
->getLength();
$cnt
++) {
my
$pename
=
$pelist
->item(
$cnt
);
my
$name
=
$pename
->getAttribute(
'name'
);
if
(!
exists
(
$EAPPEARSIN
{
"%$name"
})) {
$EAPPEARSIN
{
"%$name"
} = {};
}
$EAPPEARSIN
{
"%$name"
}->{
$elemname
} = 1;
}
}
my
$attlist
=
$attlists
{
$elemname
};
if
(
defined
(
$attlist
)) {
my
$adlist
=
$attlist
->getElementsByTagName(
'attdecl'
);
if
(
$adlist
->getLength() > 0) {
my
$attdecl
=
$adlist
->item(0);
my
$cnode
=
$attdecl
->getFirstChild();
my
$text
=
$cnode
->getData()
if
$cnode
;
while
(
$text
=~ /%([^\s;]+);?/is) {
my
$pe
= $1;
$text
= $';
$EAPPEARSIN
{
"%$pe"
} = {}
if
!
exists
(
$EAPPEARSIN
{
"%$pe"
});
$EAPPEARSIN
{
"%$pe"
}->{
$elemname
} = 1;
}
}
}
}
my
$totent
=
$#entities
+ 1;
$count
= 0;
foreach
my
$name
(
@entities
) {
&status
(
sprintf
(
"Calculating extended entity appears-in: %5.1f%%"
,
$count
/
$totent
* 100.0));
$count
++;
foreach
my
$elemname
(
keys
%{
$EAPPEARSIN
{
"%$name"
}}) {
$XAPPEARSIN
{
"%$name"
} = {}
if
!
exists
$XAPPEARSIN
{
"%$name"
};
$XAPPEARSIN
{
"%$name"
}->{
$elemname
} = 1;
}
next
if
!
$APPEARSIN
{
"%$name"
};
my
%toinspect
= %{
$APPEARSIN
{
"%$name"
}};
my
%inspected
= ();
while
(
%toinspect
) {
my
$pe
= (
keys
%toinspect
)[0];
$inspected
{
$pe
} = 1;
delete
(
$toinspect
{
$pe
});
if
(
exists
(
$EAPPEARSIN
{
"%$pe"
})) {
foreach
my
$elemname
(
keys
%{
$EAPPEARSIN
{
"%$pe"
}}) {
$XAPPEARSIN
{
"%$name"
} = {}
if
!
exists
$XAPPEARSIN
{
"%$name"
};
$XAPPEARSIN
{
"%$name"
}->{
$elemname
} = 1;
}
}
if
(
$APPEARSIN
{
"%$pe"
}) {
foreach
my
$entname
(
keys
%{
$APPEARSIN
{
"%$pe"
}}) {
$toinspect
{
$entname
} = 1
if
!
$inspected
{
$entname
};
}
}
}
}
}
sub
cmFragment {
my
$text
=
shift
;
my
$cmfragment
= 1;
$cmfragment
= 0
if
$text
=~ /\
$text
=~ s/\
$cmfragment
= 0
if
$text
=~ /[^\sa-z0-9_\|\,\&\(\)\*\?\+\-]/is;
return
$cmfragment
;
}
my
$lastmsglen
= 0;
my
$persist
= 0;
sub
status {
my
$msg
=
shift
;
my
$shouldpersist
=
shift
||
$opt
{
'debug'
};
return
if
!
$option
{
'verbose'
};
if
(
$persist
) {
print
"\n"
;
$persist
= 0;
}
else
{
print
"\r"
;
print
" "
x
$lastmsglen
;
print
"\r"
;
}
print
$msg
;
$lastmsglen
=
length
(
$msg
);
$persist
= 1
if
$shouldpersist
|| (
length
(
$msg
) > 78);
}