<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Posts Tagged With 'Trim' RSS Feed</title>
    <link>http://www.programmersheaven.com/blog/tags/Trim</link>
    <description>Contains the latest posts from the Programmer's Heaven blogs that are tagged with the label 'Trim'</description>
    <lastBuildDate>Fri, 10 Oct 2008 17:13:32 -0700</lastBuildDate>
    <generator>Argotic Syndication Framework 2007.3.0.1, http://www.codeplex.com/Argotic</generator>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <item>
      <title>Trimming strings</title>
      <link>http://www.programmersheaven.com/user/Actor/blog/115-Trimming-strings/</link>
      <description>Here, for completeness without further comment, is the code for &lt;strong&gt;RTrim&lt;/strong&gt;, &lt;strong&gt;LTrim&lt;/strong&gt; and &lt;strong&gt;Trim&lt;/strong&gt; which are included in the unit &lt;strong&gt;Tools&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
      Function RTrim (Var S : String) : String ;
      {
         RTrim -- remove trailing blanks
      }
      Var
         i : Byte ;

      begin { RTrim }
         for i := Length(S) downto 1 do
            if S[i] &amp;gt; BLANK then begin
               S     := Copy(S,1,i) ;
               RTrim := S ;
               Exit
            end ;
         {
               if we reach this point then S contains only BLANKS
            so we return a null string
         }
         S     := '' ;
         RTrim := S
      end ; { RTrim }


      Function LTrim (Var S : String) : String ;
      {
         LTrim -- remove leading blanks
      }
      Var
         i : Byte ;

      begin { LTrim }
         for i := 1 to Length(S) do
            if S[i] &amp;gt; BLANK then begin
               S     := Copy(S,i,MAXSTR) ;
               LTrim := S ;
               Exit
            end ;
         {
               if we reach this point then S contains only BLANKS
            so we return a null string
         }
         S     := '' ;
         LTrim := S
      end ; { LTrim }


      Function Trim  (Var S : String) : String ;
      {
         Trim -- remove leading and trailing blanks
      }
      begin { Trim }
         S     := RTrim(S) ;
         S     := LTrim(S) ;
         Trim  := S
      end ; { Trim }
&lt;/pre&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/user/Actor/blog/115-Trimming-strings/</guid>
      <pubDate>Wed, 02 Jan 2008 02:43:07 -0700</pubDate>
      <dc:creator>Actor</dc:creator>
    </item>
    <item>
      <title>Detabbing</title>
      <link>http://www.programmersheaven.com/user/Actor/blog/114-Detabbing/</link>
      <description>DeTab is the inverse of EnTab.  Here is the specification:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
{
PROGRAM
      DeTab    -- convert tabs to blanks
USAGE
      DeTab
FUNCTION
      DeTab copies its input to its output, expanding horizontal tabs to 
      blanks along the way, so that the output is visually the same as the        
      input, but contains no tab chars.  Tab stops are assumed to be set
      every three columns (i.e., 1, 4, 7, 10, ...), so that each tab char
      is replaced by from one to three blanks.
BUGS
      1. DeTab is naive about backspace, vertical motions, and
         non-printing chars.
      2. Each line of output will be truncated at MAXSTR chars.
      3. Trailing BLANKS will be trimmed from each line of output.

}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
DeTab's main routine echos EnTab's, reducing the problem to one of detabbing a single string.  To detab the string we could try to simply apply EnTab's strategy in reverse, however, this is another chance to apply the "how would a human do it?" approach.&lt;br /&gt;
&lt;br /&gt;
How would a human do it?  If a human is sitting at a typewriter typing the incoming text, what is happening?  First, he is looking at a blank sheet of paper.  At least the current line is blank.  If he hits any other than the TAB key the corresponding letter/character gets typed.  Even if he hits the space bar a character, a BLANK, gets typed, even though what actually happens is that the carriage moves one space to the left (effectively moving the print head to the right).  However, if he hits the TAB key the carriage moves to the left until it hits a tab stop, printing nothing and leaving the print head at the tab stop awaiting the next character.&lt;br /&gt;
&lt;br /&gt;
This is the behavior we will try to emulate.  We will copy the input string to an output string.  But first we will fill the output string with BLANKS, effectively giving us a blank line.  We will use an index &lt;strong&gt;i&lt;/strong&gt; for the input string and &lt;strong&gt;j&lt;/strong&gt; for the output string.  If the char is not a TAB then we will copy the char and increment both &lt;strong&gt;i&lt;/strong&gt; and &lt;strong&gt;j&lt;/strong&gt;.  However, if it is a TAB we increment &lt;strong&gt;i&lt;/strong&gt; once but we increment &lt;strong&gt;j&lt;/strong&gt; repeatedly until we get to a tab stop.&lt;br /&gt;
&lt;br /&gt;
To deal with the situation of what happens when we encounter a TAB after the last tab stop we cease incrementing &lt;strong&gt;j&lt;/strong&gt; once it exceeds MAXSTR.  We also do an early exit from the routine should &lt;strong&gt;j&lt;/strong&gt; exceed MAXSTR.  In keeping with our previous philosophy we do not expect this to happen but it could.  If it does the program exits cleanly, albeit with a corrupted output.  We will simply live with this known bug.&lt;br /&gt;
&lt;br /&gt;
Finally, we trim the end of the output string of any BLANKS.  This means that any trailing BLANKS in the input string will not get copied to the output.  Strictly speaking this is a bug but it is unlikely to cause problems.  Again we will live with it.&lt;br /&gt;
&lt;br /&gt;
The function &lt;strong&gt;RTrim&lt;/strong&gt; gets rid of trailing BLANKS. We will add it to &lt;strong&gt;Tools&lt;/strong&gt;.  While we are at it we will also add &lt;strong&gt;LTrim&lt;/strong&gt;, which gets rid of leading BLANKS, and &lt;strong&gt;Trim&lt;/strong&gt;, which does both.  I will post the&lt;br /&gt;
code next time.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="sourcecode"&gt;
Program DeTab ;
{
   DeTab -- replace blanks with tabs and blanks
}
Uses
   Tools,
   TabsUnit ;

      Procedure DeTabStr (Var S : String) ;
      {
         Detab a string
      }
      Var
         i     :  Byte ;
         j     :  Word ;
         T     :  String ;

      begin { DeTabStr }
         {
            clear target string
         }
         T := '' ;
         while Length(T) &amp;lt; MAXSTR do
            T := T + BLANK ;

         j := 1 ;
         for i := 1 to Length(S) do begin
            if j &amp;gt; MAXSTR then      { not likely but not impossible }
               Break ;                  

            Case S[i] of
               TAB :
                  repeat
                     j := j + 1
                  until (j in TabSet) OR (j &amp;gt; MAXSTR)
               else
                  begin
                     if j &amp;lt;= MAXSTR then
                        T[j]  := S[i] ;
                     j     := j + 1
                  end
            end { Case }
         end ;

         S := RTrim(T)
      end ; { DeTabStr }

Var
   S      :  String ;

begin { DeTab }
   SetTabs ;

   while NOT eof do begin
      ReadLn (S) ;
      DeTabStr (S) ;
      WriteLn (S)
   end
end.  { DeTab }
&lt;/pre&gt;&lt;br /&gt;</description>
      <guid isPermaLink="true">http://www.programmersheaven.com/user/Actor/blog/114-Detabbing/</guid>
      <pubDate>Tue, 01 Jan 2008 09:08:25 -0700</pubDate>
      <dc:creator>Actor</dc:creator>
    </item>
  </channel>
</rss>