<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://rt-wiki.bestpractical.com/index.php?action=history&amp;feed=atom&amp;title=PlainTextPre</id>
	<title>PlainTextPre - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://rt-wiki.bestpractical.com/index.php?action=history&amp;feed=atom&amp;title=PlainTextPre"/>
	<link rel="alternate" type="text/html" href="https://rt-wiki.bestpractical.com/index.php?title=PlainTextPre&amp;action=history"/>
	<updated>2026-08-22T22:55:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://rt-wiki.bestpractical.com/index.php?title=PlainTextPre&amp;diff=2607&amp;oldid=prev</id>
		<title>Admin: 2 revisions imported</title>
		<link rel="alternate" type="text/html" href="https://rt-wiki.bestpractical.com/index.php?title=PlainTextPre&amp;diff=2607&amp;oldid=prev"/>
		<updated>2016-04-06T20:20:28Z</updated>

		<summary type="html">&lt;p&gt;2 revisions imported&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This patch is at http://issues.bestpractical.com/Ticket/Display.html?id=8374. It was tested with 3.6.1 and I believe it will work as-is with 3.6.3.&lt;br /&gt;
&lt;br /&gt;
Many of the messages our RT instance handles contain space- and tab-based formatting in plain text. The way RT displays them (as HTML with &amp;amp;lt;br&amp;amp;gt; used to preserve line breaks) causes this formatting to be lost. Eg, this text:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;left side           right side&lt;br /&gt;
 ---------           ----------&lt;br /&gt;
 item one            value one&lt;br /&gt;
 item two            value two&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
won&amp;#039;t look right on the web page with a standard RT setup.&lt;br /&gt;
&lt;br /&gt;
I couldn&amp;#039;t figure out a clean way to change this via an overlay or callback. One problem is the &amp;amp;lt;br&amp;amp;gt;s get added after the callback returns. Another is that you want to use one &amp;amp;lt;pre&amp;amp;gt; for the whole message body (because it introduces vertical space the way a &amp;amp;lt;p&amp;amp;gt; does), but [[ShowMessageStanza]] is called for each blob of text Text::Quoted extracts. Additionally the standard [[ShowMessageStanza]] adds newlines around the &amp;amp;lt;div&amp;amp;gt;s, and these cause blank lines inside &amp;amp;lt;pre&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There might be a way to do have space- and tab-based formatting work based on &amp;quot;white-space: pre;&amp;quot; style instead of &amp;amp;lt;pre&amp;amp;gt;, but this didn&amp;#039;t line things up correctly when I tried it. I am no HTML expert.&lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s the solution I came up with. It adds a new config variable, $RT::[[PlainTextPre]], which allows you to tell the system to use &amp;amp;lt;pre&amp;amp;gt; on plain text message bodies.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;--- etc/RT_Config.pm.in.~1~	2006-10-25 23:18:11.000000000 -0400&lt;br /&gt;
 +++ etc/RT_Config.pm.in	2007-05-10 15:34:04.000000000 -0400&lt;br /&gt;
 @@ -463,6 +463,13 @@&lt;br /&gt;
 &lt;br /&gt;
  Set($ShowTransactionImages, 1);&lt;br /&gt;
 &lt;br /&gt;
 +# Normally plain text attachments are displayed as HTML with line&lt;br /&gt;
 +# breaks preserved.  This causes space- and tab-based formatting not&lt;br /&gt;
 +# to be displayed correctly.  By setting $PlainTextPre they&amp;#039;ll be&lt;br /&gt;
 +# displayed using &amp;amp;lt;pre&amp;amp;gt; instead so such formatting works, but they&amp;#039;ll&lt;br /&gt;
 +# use a monospaced font.&lt;br /&gt;
 +&lt;br /&gt;
 +Set($PlainTextPre, 0);&lt;br /&gt;
 &lt;br /&gt;
  # $HomepageComponents is an arrayref of allowed components on a user&amp;#039;s&lt;br /&gt;
  # customized homepage (&amp;quot;RT at a glance&amp;quot;).&lt;br /&gt;
 --- html/Ticket/Elements/ShowMessageStanza.~1~	2006-06-19 18:44:04.000000000 -0400&lt;br /&gt;
 +++ html/Ticket/Elements/ShowMessageStanza	2007-05-10 14:52:13.000000000 -0400&lt;br /&gt;
 @@ -1,3 +1,4 @@&lt;br /&gt;
 +%# $Id: PlainTextPre,v 1.1 2007/05/10 20:30:13 www-data Exp www-data $&lt;br /&gt;
  %# BEGIN BPS TAGGED BLOCK {{{&lt;br /&gt;
  %#&lt;br /&gt;
  %# COPYRIGHT:&lt;br /&gt;
 @@ -43,35 +44,73 @@&lt;br /&gt;
  %# those contributions and any derivatives thereof.&lt;br /&gt;
  %#&lt;br /&gt;
  %# END BPS TAGGED BLOCK }}}&lt;br /&gt;
 -% if (ref($Message)) {&lt;br /&gt;
 -&amp;amp;lt;div class=&amp;quot;message-stanza-depth-&amp;amp;lt;% $Depth %&amp;amp;gt;&amp;quot;&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;%perl&amp;amp;gt;&lt;br /&gt;
 -foreach my $stanza (@$Message) {&lt;br /&gt;
 -    if ( ref $stanza eq &amp;quot;ARRAY&amp;quot; ) {&lt;br /&gt;
 -        $m-&amp;amp;gt;comp( &amp;#039;ShowMessageStanza&amp;#039;,&lt;br /&gt;
 -                  Depth   =&amp;amp;gt; $Depth + 1,&lt;br /&gt;
 -                  Transaction =&amp;amp;gt; $Transaction,&lt;br /&gt;
 -                  Message =&amp;amp;gt; $stanza );&lt;br /&gt;
 -    }&lt;br /&gt;
 -    elsif ( ref $stanza eq &amp;quot;HASH&amp;quot; ) {&lt;br /&gt;
 -        my $content = $stanza-&amp;amp;gt;{raw};&lt;br /&gt;
 -        RT::Interface::Web::EscapeUTF8(\$content);&lt;br /&gt;
 -        $m-&amp;amp;gt;comp(&amp;#039;/Elements/Callback&amp;#039;, content =&amp;amp;gt; \$content, %ARGS);&lt;br /&gt;
 -        $content =~ s{$}{&amp;amp;lt;br /&amp;amp;gt;}mg&lt;br /&gt;
 -            if defined $content;&lt;br /&gt;
 &lt;br /&gt;
 +# This component is called to display plain text attachments.  At the&lt;br /&gt;
 +# top level it&amp;#039;s passed the data structure returned by Text::Quoted,&lt;br /&gt;
 +# then it uses itself recursively to display it.&lt;br /&gt;
 +#&lt;br /&gt;
 +# By default the messages are displayed as simple escapped HTML.  Line&lt;br /&gt;
 +# breaks are preserved by adding &amp;amp;lt;br&amp;amp;gt;.&lt;br /&gt;
 +#&lt;br /&gt;
 +# If you set $RT::PlainTextPre then the messages are displayed inside a&lt;br /&gt;
 +# &amp;amp;lt;pre&amp;amp;gt; section.  This allows space- and tab-based formatting to work,&lt;br /&gt;
 +# at the cost of using a monospaced font.&lt;br /&gt;
 +#&lt;br /&gt;
 +# There might be a way to do have space- and tab-based formatting work&lt;br /&gt;
 +# based on &amp;quot;white-space: pre;&amp;quot; style instead of &amp;amp;lt;pre&amp;amp;gt;, but this didn&amp;#039;t&lt;br /&gt;
 +# line things up correctly when I tried it.  I am no HTML expert.&lt;br /&gt;
 +&lt;br /&gt;
 +# Because the output might be inside &amp;amp;lt;pre&amp;amp;gt; this code has to be careful&lt;br /&gt;
 +# not to introduce extra newlines.&lt;br /&gt;
 +&lt;br /&gt;
 +# An oddity of Text::Quoted is that it strips the trailing newline from&lt;br /&gt;
 +# each returned strings.  The strings can be multi-line, they&amp;#039;ll always&lt;br /&gt;
 +# be missing the newline at the end.&lt;br /&gt;
 +&lt;br /&gt;
 +if (ref($Message)) {&lt;br /&gt;
 +    my ($pon, $poff) = ($RT::PlainTextPre &amp;amp;amp;&amp;amp;amp; $Depth == 0)&lt;br /&gt;
 +                            ? (&amp;#039;&amp;amp;lt;pre&amp;amp;gt;&amp;#039;, &amp;#039;&amp;amp;lt;/pre&amp;amp;gt;&amp;#039;)&lt;br /&gt;
 +                            : (&amp;#039;&amp;#039;, &amp;#039;&amp;#039;);&lt;br /&gt;
 +    $m-&amp;amp;gt;out($pon);&lt;br /&gt;
 +    $m-&amp;amp;gt;out(qq(&amp;amp;lt;div class=&amp;quot;message-stanza-depth-$Depth&amp;quot;&amp;amp;gt;));&lt;br /&gt;
 +    foreach my $stanza (@$Message) {&lt;br /&gt;
 +        if ( ref $stanza eq &amp;quot;ARRAY&amp;quot; ) {&lt;br /&gt;
 +            $m-&amp;amp;gt;comp( &amp;#039;ShowMessageStanza&amp;#039;,&lt;br /&gt;
 +                      Depth   =&amp;amp;gt; $Depth + 1,&lt;br /&gt;
 +                      Transaction =&amp;amp;gt; $Transaction,&lt;br /&gt;
 +                      Message =&amp;amp;gt; $stanza );&lt;br /&gt;
 +        }&lt;br /&gt;
 +        elsif ( ref $stanza eq &amp;quot;HASH&amp;quot; ) {&lt;br /&gt;
 +            my $content = $stanza-&amp;amp;gt;{raw};&lt;br /&gt;
 +            RT::Interface::Web::EscapeUTF8(\$content);&lt;br /&gt;
 +            $m-&amp;amp;gt;comp(&amp;#039;/Elements/Callback&amp;#039;, content =&amp;amp;gt; \$content, %ARGS);&lt;br /&gt;
 +            # I put the trailing \n back here, after the callback,&lt;br /&gt;
 +            # because the callback was historically called without it&lt;br /&gt;
 +            # attached.&lt;br /&gt;
 +            $content .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
 +            $content =~ s{\n}{&amp;amp;lt;br /&amp;amp;gt;\n}mg&lt;br /&gt;
 +                if !$RT::PlainTextPre;&lt;br /&gt;
 +            $m-&amp;amp;gt;out($content);&lt;br /&gt;
 +        }&lt;br /&gt;
 +    }&lt;br /&gt;
 +    $m-&amp;amp;gt;out(&amp;#039;&amp;amp;lt;/div&amp;amp;gt;&amp;#039;);&lt;br /&gt;
 +    $m-&amp;amp;gt;out($poff);&lt;br /&gt;
 +} else {&lt;br /&gt;
 +    my $content = $Message;&lt;br /&gt;
 +    RT::Interface::Web::EscapeUTF8(\$content);&lt;br /&gt;
 +    $m-&amp;amp;gt;comp(&amp;#039;/Elements/Callback&amp;#039;, content =&amp;amp;gt; \$content, %ARGS);&lt;br /&gt;
 +    $content .= &amp;quot;\n&amp;quot;&lt;br /&gt;
 +        if $content !~ /\n$/;&lt;br /&gt;
 +    if ($RT::PlainTextPre) {&lt;br /&gt;
 +        $content = &amp;quot;&amp;amp;lt;pre&amp;amp;gt;$content&amp;amp;lt;/pre&amp;amp;gt;&amp;quot;;&lt;br /&gt;
 +    }&lt;br /&gt;
 +    else {&lt;br /&gt;
 +        $content =~ s{\n}{&amp;amp;lt;br /&amp;amp;gt;\n}mg;&lt;br /&gt;
 +    }&lt;br /&gt;
 +    $m-&amp;amp;gt;out($content);&lt;br /&gt;
 +}&lt;br /&gt;
  &amp;amp;lt;/%perl&amp;amp;gt;&lt;br /&gt;
 -&amp;amp;lt;%$content |n%&amp;amp;gt;&lt;br /&gt;
 -%   }&lt;br /&gt;
 -% } # end foreach&lt;br /&gt;
 -&amp;amp;lt;/div&amp;amp;gt;&lt;br /&gt;
 -% } else {&lt;br /&gt;
 -%       my $content = $Message;&lt;br /&gt;
 -%       RT::Interface::Web::EscapeUTF8(\$content);&lt;br /&gt;
 -%       $m-&amp;amp;gt;comp(&amp;#039;/Elements/Callback&amp;#039;, content =&amp;amp;gt; \$content, %ARGS);&lt;br /&gt;
 -%       $content =~ s{$}{&amp;amp;lt;br /&amp;amp;gt;}mg;&lt;br /&gt;
 -&amp;amp;lt;%$content |n%&amp;amp;gt;&lt;br /&gt;
 -% }&lt;br /&gt;
  &amp;amp;lt;%INIT&amp;amp;gt;&lt;br /&gt;
  use URI::URL;&lt;br /&gt;
  &amp;amp;lt;/%INIT&amp;amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>