shay has asked for the wisdom of the Perl Monks concerning the following question:

This question is possibly a little off-topic in that it doesn't directly concern Perl, but the issue keeps cropping up for me in CGI/mod_perl work with Perl.

I usually have some means of displaying the full text of error messages in the web browser during development, often including pieces of code, e.g. stacktraces. Due to the presence of pieces of code, such messages are usually best displayed in a fixed-width font and benefit from whitespace being preserved rather than crunched as in HTML. The simplest way to achieve this is to use <pre> tags, after first running the message text through something like Apache::Util::escape_html() to escape unsafe HTML characters.

However, the problem with <pre> tags is that the text within them, being interpreted as "pre-formatted", doesn't get wrapped to the web browser window. Using <code> tags instead gives the desired wrapping effect, but then whitespace gets crunched.

I don't see any other HTML tags that would be of use (there is a (non-standard) <xmp> tag for "example" code which behaves like <pre> and does escaping of unsafe charcaters too, but still doesn't wrap to the window), so the text probably needs processing in Perl first, and then maybe displaying with <code> tags.

Currently I'm thinking of changing newlines to <br> tags and spaces to &nbsp; entities (after escaping unsafe characters first) and then using <code> tags, but I wondered if others had a more elegant way of doing this.

- Steve

Replies are listed 'Best First'.
•Re: Formatting CGI script error messages
by merlyn (Sage) on Nov 17, 2004 at 12:39 UTC
    spaces to &nbsp; entities
    If you do that, and it behaves any differently than a PRE tag, your browser is broken. Therefore, you're going through a lot of work for nothing.

    I agree with another response in this thread... simply return a text/plain MIME type.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Damn! Yes, you're quite right. But alternating spaces and &nbsp; entities would work -- i.e. leave single spaces alone, but change pairs of spaces to " &nbsp;".

      Or is there any easier way to get "non-collapsing" spaces which are allowed to be broken across lines?

      - Steve

Re: Formatting CGI script error messages
by jobi (Scribe) on Nov 17, 2004 at 12:35 UTC
    I don't know what type of error handling routines you use, but it sounds to me like you want to display text/plain and not text/html?

      That's certainly a good idea, and one that hadn't occurred to me, but I was hoping to have the pages decorated with the usual HTML header and footer stuff that all the other pages in the software have.

      I could perhaps use three frames (HTML header, text error, HTML footer), so I'll have a think about that, but one simple non-framed page would be simpler.

      - Steve

Re: Formatting CGI script error messages
by hostyle (Scribe) on Nov 17, 2004 at 15:56 UTC
    <style type="text/css"> pre { background: #EEEEEE; border: 1px solid #CCCCCC; width: 100%; /* overflow: scroll; */ /* IE only */ word-wrap: break-word; /* non-standard */ white-space: normal; } </style> <pre> this is a very very very very very very very very very very very very +very very very very very very very very very very very very very very + very very very very very very very very very very very very very ver +y very very very very very very very very very very very very very ve +ry very very very very very very very very very very very very very v +ery very very very very very very very very very very very very very +very very very very very very very very very very very very very very + very very very very very very very very very very very very very ver +y very very very very very very very very long string </pre>

    update: added IE only CSS

    update 2: added non-standard CSS and commented out overflow: scroll as its no longer needed

    Hrm. It seems that white-space is standard. IE doesn't support it however ... but who uses that these days anyway :) Above code works in all browsers I have at hand in any case

    update 3: started from scratch

    After more deliberation, it seems I've still not solved your problem - except inadvertantly in IE - so heres another attempt. Its not perfect, but its closer.

    <style type="text/css"> pre { padding: 0.5em; background: #EEEEEE; border: 1px solid #CCCCCC; overflow: auto; /* non-standard */ /* white-space : normal; */ } * html pre { /* IE only */ word-wrap:break-word; } </style> <pre> this is a very very very very very very very very very very very very +very very very very very very very very very very very very very very + very very very very very very very very very very very very very ver +y very very very very very very very very very very very very very ve +ry very very very very very very very very very very very very very v +ery very very very very very very very very very very very very very +very very very very very very very very very very very very very very + very very very very very very very very very very very very very ver +y very very very very very very very very long string and spacing of things </pre>

      I didn't know about the "overflow: scroll" thing. Pretty neat. It got me looking back at HTML/CSS documentation, and I actually found that <pre> has a "wrap" attribute!

      Unfortunately, the "wrap" attribute doesn't work in IE. However, your "word-wrap: break-word" trick does (thanks! -- I didn't know about that one either). So now I have this, which works in both NS and IE:

      <pre style="word-wrap: break-word" wrap>...</pre>
      

      (Note that "white-space: normal" is no good, though, because it collapses multiple spaces and newlines (at least, it does in NS; IE seems to not honour that either).)

      - Steve

        For Opera and Mozilla add the styles
        white-space: -o-pre-wrap; white-space: -moz-pre-wrap;
Re: Formatting CGI script error messages
by TedPride (Priest) on Nov 17, 2004 at 12:59 UTC
    Can't you just specify a standard fixed-width font or fonts (Courier, perhaps), or use <pre> and hard wrap the text on the first word boundary before x number of characters on the current line? I use the latter method when generating emails for my list.

      Just specifying a fixed-width font doesn't address the problem of wanting to preserve whitespace -- HTML collapses multiple consecutive spaces to single spaces, and also treats newlines as spaces.

      Using <pre> tags after "hard-wrapping" the text to a reasonable width is certainly an option, but I thought it would be nicer if it wrapped to the browser's window size. A fixed paragraph width can't account for variations in the font size in each user's browser.

      - Steve

        You don't have to use just one "fixed paragraph width."

        Set it, per user, dynamically. Browser detection provides you a basis to infer a maximum char_count that should be useable on the narrowest_likely screen. And in some cases, ENV detection can give you the info to set your max_line_length more precisely. Alternately, have user supply a desired width as a CL argument. ('course then, you'd better check their input for safety too.)

        Either or both are "doable," but add complicatations.
        Duh! I'd forgotten the answer is in the original, so out of curiosity: why do you want to preserve multi-spaces?

        If it's solely for readability that's one thing; if you need the info, is there some good reason not to

        t/\s{2}/~/; t/\r/(something else)/;
        to catch whatever you really need?

        Questions are likely to be IGNORANCE_based