Re: Read/Write file, break lines at 256 (or more) but NOT elements

Liam R E Quin <[email protected]> Tue, 22 Mar 2011 00:17:28 +0100
Newsgroups gmane.comp.lang.perl.xml
Organization W3C - World Wide Web Consortium
Message-ID <[email protected]>
On Mon, 2011-03-21 at 19:34 +0100, Michael Ludwig wrote:
> You replied off-list; please keep replies on-list.
[...]
> > I have thought about using XSLT but this Perl script is to run on a
> > Un*x platform and IT won't install a XSLT processor like Saxon.
Most GNU/Linux[tm] systems already come with "xsltproc" installed,
which uses libxml.

> > Can what I want be easily done with just Perl?
"easy" is relative.

I'd say that if you need to ask, the answer is "no" :-)

Right now the problem is underspecified.  What do you want to do in the
cases where (1) a single tag is longer than 256 characters, and (2)
there is a line longer than 256 characters with no spaces?

One way would be to replace the tags with place-holders that were the
same length but did not have spaces in them. I'll append some code that
does that; I've tried to write it in a way that's easy to modify.  

Another way would be to wrap the text only between tags, e.g.
$_ =~ s{>([^<>]+)<}{">" . wrap("", "", $1) . "<"}ge;
but this would not work if you have mixed content that you want to wrap,
such as HTML paragraphs.

Liam
#! /usr/bin/perl
# wrap long XML lines
# usage: thisfile input
# or,
# thisfile input > output
# or,
# thisfile < input > output ......

use warnings;
use strict;
use Text::Wrap qw(wrap $columns $huge);
$columns = 25;
$Text::Wrap::huge = 'overflow';

my %placeholders;
sub makeplaceholder($)
{
    my ($tag) = @_;
    if (exists $placeholders{$tag}) {
        return $placeholders{$tag};
    }

    my $n = scalar keys %placeholders; # number of items stored
    my $key = $n . ":" x (length($tag) - length($n));
    # now key is e.g. 0, padded out with : characters for the
    # width of the original tag
    $placeholders{$n} = $tag;
    return $key;
}

my $input;
{
    local $/;
    $input = <>; # read whole file
}
# replace tags, including multiplien ones, with placeholders
$input =~ s{<([^/][^>]*)>}{"<" . makeplaceholder($1) . ">"}ge;
$input = wrap("", "", $input);
$input =~ s{<(\d+):*>}{"<" . $placeholders{$1} . ">"}ge;
print $input;



-- 
Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/
Pictures from old books: http://www.fromoldbooks.org/
Occasional blog: http://www.barefootliam.org/
The barefoot typographer



_______________________________________________
Perl-XML mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs