Bundle-PBib
view release on metacpan or search on metacpan
lib/Biblio/bp/lib/bp-p-cs.pl view on Meta::CPAN
# string. This allows multiple character approximations.
#
# XXXXX Think about C3's idea of multiple approximations.
#
# A map of 0000 means that it maps to the null string -- our "approximation"
# is to get rid of it. This is what we can do if it isn't terribly harmful
# to remove it.
sub meta_approx {
local($orig) = @_;
require "${glb_bpprefix}p-cstab.pl" unless defined %bib'mapprox_tab;
if (defined $mapprox_tab{$orig}) {
return '' if $mapprox_tab{$orig} eq '0000';
return "${bib'cs_meta}$mapprox_tab{$orig}";
}
undef;
}
sub unicode_approx {
local($orig) = @_;
# XXXXX Should we warn them that they're getting an approx?
require "${glb_bpprefix}p-cstab.pl" unless defined %bib'uapprox_tab;
$uapprox_tab{$orig};
}
######
#
# Font change checker. Verifies and tries to correct font changes.
#
# After fonts are converted in your tocanon routine, call this. In your
# fromcanon routine, you can assume this has been called.
#
# XXXXX Should we call this in bp.pl's conversion routines? That would
# guarantee that it has been run. Right now, we let each module
# decide when and if it needs to be run.
#
# It takes a string that has font changes in it and makes sure they always
# match up and that there isn't an odd number (more starts than ends, more
# ends than starts).
#
sub font_check {
local($_) = @_;
# XXXXX Ought to read meta information from 00 or as input.
return $_ unless /${bib'cs_meta}01[01]/;
local(@fontstack) = ();
local($fontsmatch, $font, $pfont);
# Check for this special occurance: They don't have end fonts (or don't
# use them). They just make everything a begin font (troff often does this).
# Solution: Try to fix it up by replacing each begin after the first with
# an endprevious / begin pair. Then remove the last begin.
if (!/${bib'cs_meta}011/) {
local($pos) = $[;
local($lpos) = 0;
local($distance) = length($bib'cs_meta) + 3;
local($n) = 0;
while (($pos = index($_, "${bib'cs_meta}010", $pos)) >= $[) {
$n++;
if ($n == 1) {
$lpos = $pos;
$pfont = substr($_, $pos + $distance, 1);
$pos++;
next;
}
$lpos = $pos;
$font = substr($_, $pos + $distance, 1);
substr($_, $pos, 0) = "${bib'cs_meta}0110";
$pos += ($distance*2); # need to skip over the one we just put in.
}
if ($n > 1) {
# now remove the last begin
substr($_, $lpos + $distance + 1, $distance + 1) = '';
} elsif ($n == 1) {
# only one begin? Add a previous to the end.
$_ .= "${bib'cs_meta}0110";
} else {
&panic("Bug in font_check, file bp-p-cs.");
}
#print STDERR "F: end of troff: $_\n";
# XXXXX XXF return $_;
}
do {
# We assume that everything is ok until something goes wrong.
$fontsmatch = 1;
while (/${bib'cs_meta}01(.)(.)/g) {
$font = $2;
if ($1 eq '0') { # font begin
#print STDERR "F: check begin font $font\n";
if ($font eq '0') {
&bib'gotwarn("Someone used default font begin. Naughty.");
s/${bib'cs_meta}0100/${bib'cs_meta}0110/go;
$fontsmatch = 0;
last;
}
push(@fontstack, $font);
} else { # font end
#print STDERR "F: check end font $font\n";
if (@fontstack) {
$pfont = pop(@fontstack);
next if $font eq '0'; # previous font. We don't care what it was.
if ($pfont ne $font) {
# _____ ended font that wasn't equal to the last begin
&bib'gotwarn("Nesting problem. Ended $font after $pfont");
# just make it end the previous one.
if ($] >= 5.000) {
s/(${bib'cs_meta}010$pfont)(.*?)${bib'cs_meta}011$font/$1$2{bib'cs_meta}011$pfont/;
} else {
s/(${bib'cs_meta}010$pfont)(.*)${bib'cs_meta}011$font/$1$2{bib'cs_meta}011$pfont/;
}
$fontsmatch = 0;
last;
}
} else {
# _____ end font used without a begin
&bib'gotwarn("Ended font $font before begin seen");
# This is really lousy, but without pulling the whole string apart,
( run in 0.808 second using v1.01-cache-2.11-cpan-364913b4093 )