use
vars
qw(@ISA %GOOD_HEADER)
;
BEGIN {
if
($@ ne
''
) {
croak
"Need Pod::Tex version > 2.0"
if
$Pod::Text::VERSION
< 2.0;
@ISA
=
qw(Pod::Text Pod::Parser WAIT::Parse::Base)
;
}
else
{
@ISA
=
qw(Pod::PText Pod::Parser WAIT::Parse::Base)
;
}
}
%GOOD_HEADER
= (
name
=> 1,
synopsis
=> 1,
options
=> 1,
description
=> 1,
author
=> 1,
example
=> 1,
bugs
=> 1,
text
=> 1,
see
=> 1,
environment
=> 1,
);
sub
default_indent () {4};
my
$CODE
= {
text
=> 1,
_c
=> 1};
my
$BOLD
= {
text
=> 1,
_b
=> 1};
my
$ITALIC
= {
text
=> 1,
_i
=> 1};
my
$PLAIN
= {
text
=> 1};
sub
new {
my
$this
=
shift
;
my
$class
=
ref
(
$this
) ||
$this
;
my
$self
=
$this
->SUPER::new(
@_
);
bless
$self
,
$class
;
}
sub
begin_input {
my
$self
=
shift
;
$self
->indent(default_indent);
$self
->{TAGS} = {};
$self
->{OUT} = [];
}
sub
indent {
my
$self
=
shift
;
if
(
@_
) {
$self
->{INDENT} =
shift
;
}
$self
->{INDENT};
}
sub
interpolate {
my
$self
=
shift
;
my
(
$text
,
$end_re
) =
@_
;
$text
=
''
unless
(
defined
$text
);
$end_re
=
"\$"
unless
((
defined
$end_re
) && (
$end_re
ne
''
));
local
(
$_
) =
$text
;
my
@result
;
my
(
$seq_cmd
,
$seq_arg
,
$end
) = (
''
,
''
,
undef
);
while
((
$_
ne
''
) && /([A-Z])<|(
$end_re
)/) {
$_
= $';
push
@result
,
$self
->{TAGS}, $`;
(
$seq_cmd
,
$end
) = ($1, $2);
last
if
(
defined
$end
);
if
(
$seq_cmd
=~ /^([FBIC])/) {
my
$tag
=
'_'
.
lc
$1;
my
$tags
=
$self
->{TAGS};
my
%tags
= (%{
$tags
},
$tag
=> 1);
$self
->{TAGS} = \
%tags
;
push
@result
,
$self
->interpolate(
$_
,
'>'
);
$self
->{TAGS} =
$tags
;
}
else
{
my
@seq_arg
=
$self
->interpolate(
$_
,
'>'
);
my
$i
;
for
(
$i
=1;
$i
<=
@seq_arg
;
$i
+=2) {
push
@result
,
$seq_arg
[
$i
-1],
$self
->interior_sequence(
$seq_cmd
,
$seq_arg
[
$i
]);
}
}
}
unless
((
defined
$end
) && (
$end_re
ne
"\$"
)) {
push
@result
,
$self
->{TAGS},
$_
;
$_
=
''
;
}
$_
[0] =
$_
;
return
@result
;
}
sub
textblock {
my
(
$self
,
$text
) =
@_
;
$self
->output(
$self
->interpolate(
$self
->wrap(
$text
)),
$PLAIN
,
"\n\n"
);
}
sub
output {
my
(
$self
) =
shift
;
while
(
@_
) {
my
$tags
=
shift
;
my
$text
=
shift
;
croak
"Bad tags parameter: '$tags'"
unless
ref
(
$tags
);
push
@{
$self
->{OUT}},
$tags
,
$text
;
}
}
sub
verbatim {
my
(
$self
,
$text
) =
@_
;
my
$indent
=
$self
->indent() + default_indent;
$text
= expand(
$text
);
my
(
$prefix
) = (
$text
=~ /^(\s+)/);
if
(
length
(
$prefix
) <
$indent
) {
my
$add
=
' '
x (
$indent
-
length
(
$prefix
));
$text
=~ s/^/
$add
/gm;
}
elsif
(
length
(
$prefix
) >
$indent
) {
my
$sub
=
' '
x (
length
(
$prefix
) -
$indent
);
$text
=~ s/^
$sub
//gm;
}
$self
->output(
$CODE
,
$text
);
}
sub
command {
my
(
$self
,
$cmd
,
$arg
,
$sep
) =
@_
;
if
(
$cmd
=~ /^head(\d)/) {
my
$indent
= $1-1;
my
$tags
=
$self
->{TAGS};
$self
->{TAGS} =
$BOLD
;
$self
->output(
$self
->interpolate(
$self
->wrap(
$arg
,
$indent
*default_indent
).
"\n\n"
));
if
(
$indent
) {
$self
->{TAGS} =
$tags
;
}
else
{
my
$sarg
=
lc
$arg
;
$sarg
=~ s/\s.*//g;
if
(
$GOOD_HEADER
{
$sarg
}) {
$self
->{TAGS} = {
lc
$sarg
=> 1}
}
else
{
$self
->{TAGS} = {
text
=> 1}
}
}
}
elsif
(
$cmd
=~ /^back/) {
$self
->indent(default_indent);
}
elsif
(
$cmd
=~ /^over/) {
my
$indent
= ((
$arg
)?
$arg
:default_indent) + default_indent;
$self
->indent(
$indent
);
}
elsif
(
$cmd
=~ /^item/) {
$self
->output(
$self
->interpolate(
$self
->wrap(
$arg
,default_indent).
"\n\n"
))
}
else
{
$self
->output(
$self
->{TAGS},
$arg
);
}
}
sub
wrap {
my
(
$self
,
$t
,
$indent
) =
@_
;
$indent
=
$self
->indent
unless
defined
$indent
;
my
$columns
= 76 -
$indent
;
my
$ll
=
$columns
;
my
$prefix
=
' '
x
$indent
;
my
$result
=
$prefix
;
my
$length
;
$t
=~ s/([EL])<(.*?)>/
$self
->interior_sequence($1,$2)/eg;
$t
=~ s/\s+/ /g;
while
(
$t
=~ s/^(\S+)\s?//o) {
my
$word
= $1;
my
$dummy
=
$word
;
$dummy
=~ s/[A-Z]<(.*?)>/$1/og;
$length
=
length
(
$dummy
);
if
(
$length
<
$ll
) {
$result
.=
$word
.
' '
;
$ll
-=
$length
+ 1;
}
else
{
$result
=~ s/ $/\n/;
$result
.=
$prefix
.
$word
.
' '
;
$ll
=
$columns
-
$length
- 1;
}
}
return
$result
;
}
sub
parse_from_string {
my
$self
=
shift
;
local
(
$_
);
$self
->{CUTTING} = 1;
$self
->begin_input();
my
$paragraph
=
''
;
for
(
split
/\n\s*\n/,
$_
[0]) {
$self
->parse_paragraph(
$_
.
"\n\n"
);
}
$self
->end_input();
}
sub
tag {
my
$self
=
shift
;
$self
->begin_input;
$self
->parse_from_string(
@_
);
my
$result
=
$self
->{OUT};
delete
$self
->{OUT};
delete
$self
->{TAGS};
@{
$result
};
}