Erlang Central

Difference between revisions of "String Tabs"

From ErlangCentral Wiki

 
Line 46:Line 46:
  
 
Python includes an expandtabs() method, but Erlang doesn't. This is probably because the tab/space distinction is very important in Python source code, but not so in Erlang. Still, it's a useful thing to do sometimes. The tricky thing about tab expansion is that a tab doesn't translate directly into a fixed number of spaces; you have to calculate the number of spaces for each tab to reach the next tabstop. Tabstops divide the string into equal partitions of the length specified, and the action of a tab character is to move forward to the next tabstop. For example, if your tabstop is 4 and you have the string "12345\t678\t", the first tab converts to 3 spaces and the 2nd converts to one space, e.g. "12345 678 ".
 
Python includes an expandtabs() method, but Erlang doesn't. This is probably because the tab/space distinction is very important in Python source code, but not so in Erlang. Still, it's a useful thing to do sometimes. The tricky thing about tab expansion is that a tab doesn't translate directly into a fixed number of spaces; you have to calculate the number of spaces for each tab to reach the next tabstop. Tabstops divide the string into equal partitions of the length specified, and the action of a tab character is to move forward to the next tabstop. For example, if your tabstop is 4 and you have the string "12345\t678\t", the first tab converts to 3 spaces and the 2nd converts to one space, e.g. "12345 678 ".
 +
 +
 +
[[Category:CookBook]]

Revision as of 21:42, 18 August 2006

Problem

You want to convert spaces in a string to tabs, or vice versa.

Solution

You can define this by searching for tabs and expanding them as they're found:

-define(TABSTOPS,4).

expand_tabs(Str) ->
    expand_tabs("", Str).

expand_tabs(Accum, Str) ->
    Tabloc = string:chr(Str, $\t),
    case Tabloc of
        0 -> Accum ++ Str;
        _ -> UpToTab = string:substr(Str, 1, Tabloc - 1),
             AfterTab = string:substr(Str, Tabloc + 1),
             Extra = (Tabloc - 1) rem ?TABSTOPS,
             SpaceCount = case Extra of
                              0 -> ?TABSTOPS;
                              _ -> ?TABSTOPS - Extra
                          end,
             expand_tabs(Accum ++ UpToTab ++
               string:chars($ , SpaceCount), AfterTab)
    end.


This looks like this in action:

1> cookbook:expand_tabs("12345\t678\t9").             
"12345   678 9"
2> cookbook:expand_tabs("this is\ta test.").          
"this is a test."
3> cookbook:expand_tabs("this is \ta test.").
"this is     a test."
4> cookbook:expand_tabs("this is  \ta test.").
"this is     a test."
5> cookbook:expand_tabs("this is   \ta test.").
"this is     a test."
6> cookbook:expand_tabs("this is    \ta test.").
"this is     a test."
7> cookbook:expand_tabs("this is     \ta test.").
"this is         a test."

Python includes an expandtabs() method, but Erlang doesn't. This is probably because the tab/space distinction is very important in Python source code, but not so in Erlang. Still, it's a useful thing to do sometimes. The tricky thing about tab expansion is that a tab doesn't translate directly into a fixed number of spaces; you have to calculate the number of spaces for each tab to reach the next tabstop. Tabstops divide the string into equal partitions of the length specified, and the action of a tab character is to move forward to the next tabstop. For example, if your tabstop is 4 and you have the string "12345\t678\t", the first tab converts to 3 spaces and the 2nd converts to one space, e.g. "12345 678 ".