… | |
… | |
1625 | |
1625 | |
1626 | Expand crossfire pod fragments into protocol xml. |
1626 | Expand crossfire pod fragments into protocol xml. |
1627 | |
1627 | |
1628 | =cut |
1628 | =cut |
1629 | |
1629 | |
1630 | use re 'eval'; |
|
|
1631 | |
|
|
1632 | my $group; |
|
|
1633 | my $interior; $interior = qr{ |
|
|
1634 | # match a pod interior sequence sans C<< >> |
|
|
1635 | (?: |
|
|
1636 | \ (.*?)\ (?{ $group = $^N }) |
|
|
1637 | | < (??{$interior}) > |
|
|
1638 | ) |
|
|
1639 | }x; |
|
|
1640 | |
|
|
1641 | sub expand_cfpod { |
1630 | sub expand_cfpod { |
1642 | my ($self, $pod) = @_; |
1631 | my ($self, $pod) = @_; |
1643 | |
1632 | |
|
|
1633 | my @nest = [qr<\G$>, undef, ""]; |
1644 | my $xml; |
1634 | my $xml; |
1645 | |
1635 | |
|
|
1636 | for ($pod) { |
1646 | while () { |
1637 | while () { |
1647 | if ($pod =~ /\G( (?: [^BCGHITU]+ | .(?!<) )+ )/xgcs) { |
1638 | if (/\G( (?: [^BCEGHITUZ&>\n\ ]+ | [BCEGHITUZ](?!<) | \ (?!>) )+ )/xgcs) { |
1648 | $group = $1; |
|
|
1649 | |
|
|
1650 | $group =~ s/&/&/g; |
|
|
1651 | $group =~ s/</</g; |
|
|
1652 | |
|
|
1653 | $xml .= $group; |
1639 | $xml .= $1; |
1654 | } elsif ($pod =~ m%\G |
1640 | } elsif (/\G\n(?=\S)/xgcs) { |
1655 | ([BCGHITU]) |
1641 | $xml .= " "; |
1656 | < |
1642 | } elsif (/\G\n/xgcs) { |
1657 | (?: |
1643 | $xml .= "\n"; |
1658 | ([^<>]*) (?{ $group = $^N }) |
1644 | } elsif (/\G ([BCEGHITUZ]) (< (?: <+\ | (?!<) ) )/xgcs) { |
1659 | | < $interior > |
1645 | my ($code, $delim) = ($1, scalar reverse $2); |
1660 | ) |
1646 | $delim =~ y/</>/; # delim now contains the stop sequence |
1661 | > |
1647 | $delim = qr{\G\Q$delim}; |
1662 | %gcsx |
|
|
1663 | ) { |
|
|
1664 | my ($code, $data) = ($1, $group); |
|
|
1665 | |
1648 | |
|
|
1649 | my $cb; |
|
|
1650 | |
1666 | if ($code eq "B") { |
1651 | if ($code eq "B") { |
1667 | $xml .= "<b>" . expand_cfpod ($self, $data) . "</b>"; |
1652 | $cb = sub { "<b>$_[0]</b>" }; |
1668 | } elsif ($code eq "I") { |
|
|
1669 | $xml .= "<i>" . expand_cfpod ($self, $data) . "</i>"; |
|
|
1670 | } elsif ($code eq "U") { |
|
|
1671 | $xml .= "<u>" . expand_cfpod ($self, $data) . "</u>"; |
|
|
1672 | } elsif ($code eq "C") { |
1653 | } elsif ($code eq "C") { |
1673 | $xml .= "<tt>" . expand_cfpod ($self, $data) . "</tt>"; |
1654 | $cb = sub { "<tt>$_[0]</tt>" }; |
1674 | } elsif ($code eq "T") { |
1655 | } elsif ($code eq "E") { |
1675 | $xml .= "<big><b>" . expand_cfpod ($self, $data) . "</b></big>"; |
1656 | $cb = sub { warn "E<$_[0]>\n";"&$_[0];" }; |
1676 | } elsif ($code eq "G") { |
1657 | } elsif ($code eq "G") { |
|
|
1658 | $cb = sub { |
1677 | my ($male, $female) = split /\|/, $data; |
1659 | my ($male, $female) = split /\|/, $_[0]; |
1678 | $data = $self->gender ? $female : $male; |
1660 | $self->gender ? $female : $male |
1679 | $xml .= expand_cfpod ($self, $data); |
1661 | }; |
1680 | } elsif ($code eq "H") { |
1662 | } elsif ($code eq "H") { |
1681 | $xml .= ("<fg name=\"lightblue\">[" . expand_cfpod ($self, $data) . " (Use hintmode to suppress hints)]</fg>", |
1663 | $cb = sub { |
|
|
1664 | ( |
|
|
1665 | "<fg name=\"lightblue\">[$_[0] (Use hintmode to suppress hints)]</fg>", |
1682 | "<fg name=\"lightblue\">[Hint suppressed, see hintmode]</fg>", |
1666 | "<fg name=\"lightblue\">[Hint suppressed, see hintmode]</fg>", |
1683 | "") |
1667 | "", |
1684 | [$self->{hintmode}]; |
1668 | )[$self->{hintmode}]; |
|
|
1669 | }; |
|
|
1670 | } elsif ($code eq "I") { |
|
|
1671 | $cb = sub { "<i>$_[0]</i>" }; |
|
|
1672 | } elsif ($code eq "T") { |
|
|
1673 | $cb = sub { "<big><b>$_[0]</b></big>" }; |
|
|
1674 | } elsif ($code eq "U") { |
|
|
1675 | $cb = sub { "<u>$_[0]</u>" }; |
|
|
1676 | } elsif ($code eq "Z") { |
|
|
1677 | $cb = sub { }; |
|
|
1678 | } else { |
|
|
1679 | die "FATAL error in expand_cfpod"; |
|
|
1680 | } |
|
|
1681 | |
|
|
1682 | push @nest, [$delim, $cb, $xml]; |
|
|
1683 | undef $xml; |
|
|
1684 | |
|
|
1685 | } elsif ($_ =~ /$nest[-1][0]/gcs) { |
|
|
1686 | my $nest = pop @nest; |
|
|
1687 | |
|
|
1688 | if ($nest->[1]) { |
|
|
1689 | $xml = $nest->[2] . $nest->[1]->($xml); |
|
|
1690 | } else { |
|
|
1691 | last; |
|
|
1692 | } |
|
|
1693 | } elsif (/\G</xgcs) { |
|
|
1694 | $xml .= "<"; |
|
|
1695 | } elsif (/\G&/xgcs) { |
|
|
1696 | $xml .= "&"; |
|
|
1697 | } elsif (/\G>/xgcs) { |
|
|
1698 | $xml .= ">"; |
1685 | } else { |
1699 | } else { |
1686 | $xml .= "error processing '$code($data)' directive"; |
1700 | if ($pod =~ /\G(.+)/xgcs) { |
|
|
1701 | warn "parse error (at $1)($nest[-1][0]) while expanding cfpod:\n$pod"; |
|
|
1702 | last; |
|
|
1703 | } else { |
|
|
1704 | warn "parse error (unclosed interior sequence at end of cfpod) while expanding cfpod:\n$pod"; |
|
|
1705 | return "<b>Sorry, the server encountered an internal error when formatting this message, please report this.</b>"; |
|
|
1706 | } |
1687 | } |
1707 | } |
1688 | } else { |
|
|
1689 | if ($pod =~ /\G(.+)/) { |
|
|
1690 | warn "parse error while expanding $pod (at $1)"; |
|
|
1691 | } |
1708 | } |
1692 | last; |
|
|
1693 | } |
|
|
1694 | } |
|
|
1695 | |
|
|
1696 | for ($xml) { |
|
|
1697 | # create single paragraphs (very hackish) |
|
|
1698 | s/(?<=\S)\n(?=\w)/ /g; |
|
|
1699 | |
|
|
1700 | # compress some whitespace |
|
|
1701 | s/\s+\n/\n/g; # ws line-ends |
|
|
1702 | s/\n\n+/\n/g; # double lines |
|
|
1703 | s/^\n+//; # beginning lines |
|
|
1704 | s/\n+$//; # ending lines |
|
|
1705 | } |
1709 | } |
1706 | |
1710 | |
1707 | $xml |
1711 | $xml |
1708 | } |
1712 | } |
1709 | |
|
|
1710 | no re 'eval'; |
|
|
1711 | |
1713 | |
1712 | sub hintmode { |
1714 | sub hintmode { |
1713 | $_[0]{hintmode} = $_[1] if @_ > 1; |
1715 | $_[0]{hintmode} = $_[1] if @_ > 1; |
1714 | $_[0]{hintmode} |
1716 | $_[0]{hintmode} |
1715 | } |
1717 | } |