[code] Split a long pathstring ~in half at the nearest '/'

[code] Split a long pathstring ~in half at the nearest '/'

Postby Dan Rathbun » Thu Feb 10, 2011 11:31 pm


[ code ] Split a long pathstring ~in half at the nearest '/'

Scenario:
(a) You have a very long absolute pathstring, and you want to display it in a UI.messagebox, but don't want the dialog to be tremendously wide (or definately not wider than the screen.)
(b) You want the pathstring to look "correct", having the split on the nearest '/' near the middle of the string.

Question: The following code is what I came up with (as I could not find any built-in Enumerable iterator that would do what I wanted.) Can anyone suggest a better or more consise (more readable,) way of doing this?

So you would have code that needs the method, like:
Code: Select all
info = "Couldn't load:\n\n"
info<< path_knife(pathstring)
info<< "\n\nAnswer this question for some action?"
choice = UI.messagebox( info, MB_YESNO|96 )
choice == IDYES ? do_sometask() : do_othertask

And the path_knife() method:
Code: Select all
def path_knife(path,max=60)
  path = File.expand_path(path)
  if path.length > max
    
# cut the file path into 2 lines
    spa = [0.54,0.58,0.62,0.66,0.71]
    i= for e in spa
      c 
= ((path.length)*e).to_i
      x 
= while c >= 0
        
(path[c,1]=='/')?(break c):((c==0)?(break 0):(= c-1))
      end # while
      (x.to_f/(path.length.to_f-1.0) >= 0.45)?(break x):((e==spa.last)?(break 0):(next))
    end # for
    #    
    return "#{path[0,i+1]}    \n#{path[i+1,path.length-1]}    " if i>0
    return 
"#{path}    " # just in case i is still 0
  else # leave it as one line
    return "#{path}    "
  end
end 
# def
 


Here's an "unwound" edition of the same method, with annotation comments:
Code: Select all
def path_knife(path,max=60)
  path = File.expand_path(path)
  if path.length > max
    
# cut the file path into 2 lines
    
    
# start point array of %
    spa = [0.54,0.58,0.62,0.66,0.71]
    i= for e in spa
      
# Get a start index at e% into path.
      c = ((path.length)*e).to_i
      
      
# Iterate backwards from startpoint
      # until a '/' character is found, or
      # 0 is reached. Return result in x.
      x = while c >= 0
        if 
(path[c,1]=='/')
          break c
        else
          if c
==0
            break 0
          else
            c 
= c-1
          end
        end
      end 
# while
      
      
# Test x to see if it's at least 45% of path;
      # if so, return result in i. If not, next.
      if x.to_f/(path.length.to_f-1.0) >= 0.45
        break x
      else
        break 0 if e
==spa.last
      end
    end 
# for
    #
    return "#{path[0,i+1]}    \n#{path[i+1,path.length-1]}    " if i>0
    return 
"#{path}    " # just in case i is still 0
  else # leave it as one line
    return "#{path}    "
  end
end 
# def
 
0
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: [code] Split a long pathstring ~in half at the nearest '

    Postby Dan Rathbun » Thu Feb 10, 2011 11:39 pm

    This is what a dialog using path_knife() looks like:

    path_knife.png
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: [code] Split a long pathstring ~in half at the nearest '

      Postby todd burch » Fri Feb 11, 2011 2:52 am

      Code: Select all
      def path_knife(path,max=60)
         path = File.expand_path(path)
         if path.length > max
            s = []
            minlen = path.length
            path.gsub(/\//) {|piece|
               len = ($`.length - $'.length).abs
               if len < minlen then
                  s = [ $`, $']
                  minlen = len
               end
            }   
            return "#{s[0]}/\n#{s[1]}"
         else # leave it as one line
            return "#{path}"
         end
      end # def
       
      puts path_knife("C:/Program Files/Google/Google SketchUp 8/Plugins/test/error/NoMemoryError.rb")
      0

      todd burch 
       

      Re: [code] Split a long pathstring ~in half at the nearest '

      Postby david. » Fri Feb 11, 2011 6:32 pm

      How about:

      Code: Select all
      def path_knife( path, max=60 )
          fpath = File.expand_path(path)

          if( fpath.length > max )
              rMax = fpath[0..max].reverse =~ /\//
              "#{fpath[0..(max - rMax)]}\n\t#{fpath[(max + 1 - rMax)...fpath.length]}"
          else
              "#{fpath}"
          end
      end
      0

      david. 
       

      Re: [code] Split a long pathstring ~in half at the nearest '

      Postby todd burch » Fri Feb 11, 2011 6:36 pm

      Looks good david, but it doesn't satisfy
      (b) You want the pathstring to look "correct", having the split on the nearest '/' near the middle of the string.
      0

      todd burch 
       

      Re: [code] Split a long pathstring ~in half at the nearest '

      Postby Dan Rathbun » Fri Feb 11, 2011 8:33 pm

      Isn't this a 'vicious' little Ruby exercise ?? ;)

      At first blush, you think, "Oh simple string manipulation. No problem.." Then you actually try and code it.

      It's a good one for a Ruby class, for sure.


      @Todd: I had forgotten about the $` (prematch) and $' (postmatch) globals. That could simplify things, especially the string output at the end as you showed.

      @Dave: I had entertained the idea of dup'ing and reversing the path, and then using the standard String class iterator .each_byte and then stoping when a '/' was found between 45%..55% of the path length. I just didn't want to figure out that night, how to invert the reverse index.
      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: [code] Split a long pathstring ~in half at the nearest '

        Postby david. » Fri Feb 11, 2011 8:56 pm

        Well, I am using "max" to determine about where to split the path string. The assumption being that you know what string length looks OK in general. That should be a valid assumption for most legitimate path strings (at least, it would be for any system I've ever encountered). If strings get much longer than that, you'll need a slightly modified version to split into more than 2 lines. The code I provided could easily be modified to take fpath.length/2 to approximate the middle of the path string on the fly. Or, it could easily be modified to do splits into more than 2 lines.
        0

        david. 
         

        Re: [code] Split a long pathstring ~in half at the nearest '

        Postby TIG » Fri Feb 11, 2011 10:08 pm

        Why not ?
        Code: Select all
        def path_knife(path, max=60)
          return path if path.length<=max
          return path
        [0..(max/2).to_i]+"..."+path[-(max/2).to_i/2..-1]
        end#def   
        :?
        0
        TIG
        User avatar
        TIG 
        Global Moderator
         

        Re: [code] Split a long pathstring ~in half at the nearest '

        Postby Dan Rathbun » Fri Feb 11, 2011 10:24 pm

        TIG wrote:Why not ?
        Code: Select all
        def path_knife(path, max=60)
          return path if path.length<=max
          return path
        [0..(max/2).to_i]+"..."+path[-(max/2).to_i/2..-1]
        end#def        
        :?

        That does not meet the specifications. It will divide folder names.
        (The instructor grades you a C- for your effort.) :roflmao:

        EDIT: .. AND it does not return a two line string (or add padding to which is lacking in the API implementation of the UI.messagbox method.)

        EDIT2: Tested your suggestion and for the test path, it returns:
        "C:/Program Files/Google/Google ...oMemoryError.rb"
        So, it also chops off part the filename at the end.
        0
        Last edited by Dan Rathbun on Sat Feb 12, 2011 3:50 am, edited 2 times in total.
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          Re: [code] Split a long pathstring ~in half at the nearest '

          Postby Dan Rathbun » Sat Feb 19, 2011 11:21 pm

          Ok here's my current version:
          Code: Select all
          def self.path_knife(path,max=60)
            # make sure it's a Ruby path using '/'.
            path = File.expand_path(path)
            if path.length > max
              
          # cut the file path into 2 lines
              ok = ((path.length-1)*0.45).to_i
              cut 
          = path.split(//).each_with_index { |e,i|
                break i if( e=='/' && i>=ok )
              }
              cut = 0 unless cut.is_a?(Integer)
              return "  #{path[0..cut]}   \n  #{path[(cut+1)..-1]}   " if cut>0
            end
            
          # otherwise, leave it as one line
            return "  #{path}   "
            #
          end # def
           

          EDIT: Added test after iterator, to set cut to 0, if a string had no '/' characters (in which case each_with_index just returns the array characters.)
          Also removed frivolous line before iterator: cut = 0

          EDIT 2:(2011-02-19) Simplified path substring references (line 11.)
          Removed frivolous else clause (were lines 12 and 13.)
          0


          Last bumped by Dan Rathbun on Sat Feb 19, 2011 11:21 pm.
            I'm not here much anymore. But a PM will fire email notifications.
            User avatar
            Dan Rathbun 
            PluginStore Author
            PluginStore Author
             

            SketchUcation One-Liner Adverts

            by Ad Machine » 5 minutes ago



            Ad Machine 
            Robot
             



             

            Return to Developers' Forum

            Who is online

            Users browsing this forum: No registered users and 11 guests