Tuesday, December 1, 2009

How to force wrap of long strings for mobile display

One problem I came across a while back while developing scripts that generate pages to be viewed by mobile devices was that long continuous strings of characters would not wrap 'correctly' (at all). This was made more noticable since I tend to use width defined html tags. For example, url's you want to show directly in html may often be wider than the screen that will be viewing them. Now you might say, so what. They just extend past the current viewing window. With mobile devices, this is not an optimum situation for efficient browsing.

When designing a mobile site, it is best not to make the user scroll any more than they have to. And not making the user scroll horizontally is even more important. I believe some browsers don't even allow it, (newer mobile browsers are more capable). And this problem actually happens quite often when you output url or file path strings from within your scripts. Especially when outputing strings for debugging or error reporting.

So what to do?

Well, I wrote some Perl code to force breaks in long strings of characters or in certain long words within paragraphs of text which wouldn't wrap to my liking.

Here is the code:

sub clean_breaks {
# -----------------------------

my $string = shift;
my $cl_break = shift;
my $filter = shift || '\W';
my $line = 0;
my $word = '';
my @words = ();

@words = split / /, $string;

foreach $word (@words) {

my $more_word = '';
my @more_words = ();

if(length $word > $cl_break) {

$word =~ s/(.{$cl_break})/$1 /g;
@more_words = split / /, $word;
foreach $more_word (@more_words) {

if(length $more_word > ($cl_break/2)) {

$more_word = reverse $more_word;
$more_word =~ s/($filter)/$1>\/ rb</;
$more_word = reverse $more_word;
unless ($more_word =~ m/<br>|<br \/>/) {
$more_word =~ s/^(.{$cl_break})/$1<br \/>/;
}
}
}
$word = join ('', @more_words);
$line = 0;

} else {

$line += length $word;
if ($line > $cl_break ) { $word = '<br />' . $word; $line = 0; }
}
}
join (' ', @words);
}

It works by breaking up long strings of text, base on the screen width of the user's display, times the html tag's % of screen width for that paticular tag (ie: 100%, or 1 for the body tag), divided by the width of each character. I work in pixels, but the units aren't important when the principle is respected.

So what you want is the approximate number of characters per line where normal wraping occurs, for that particular tag. And yes, the user's screen width and character width values will have to be guessed since they will vary by the user's browser, device and user settings. More on that another day.

So, you enter a string of text (or a string of continuous characters) as the first input to the subroutine '&clean_breaks' and then a 'characters per line' integer as the second input. Run the subroutine and voila, you get back your original string but with tags inserted in strategic places to force wraping in the designated tag. And it does work. Here is a link to a working example:


Run the above script in a mobile browser and look at the output. This script reports back the 'user agent' string it detects, as well as some WURFL data inspired strings. These strings represent the 'continuous character' strings I talked about in the beginning of this post. Normally, they wouldn't wrap and they screwed up the look of the outputed page. And here is a link to the actual script (just in case the above doesn't work after copy/paste):


I scanned the web a while back and couldn't find anything else available at the time. If you know of something similar, drop me a line or leave a comment. I'm always on the lookout for improvements.





No comments:

Post a Comment