by 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 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 = c-1)) end (x.to_f/(path.length.to_f-1.0) >= 0.45)?(break x):((e==spa.last)?(break 0):(next)) end return "#{path[0,i+1]} \n#{path[i+1,path.length-1]} " if i>0 return "#{path} " else return "#{path} " end end
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 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 if (path[c,1]=='/') break c else if c==0 break 0 else c = c-1 end end end if x.to_f/(path.length.to_f-1.0) >= 0.45 break x else break 0 if e==spa.last end end return "#{path[0,i+1]} \n#{path[i+1,path.length-1]} " if i>0 return "#{path} " else return "#{path} " end end
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Dan Rathbun » Thu Feb 10, 2011 11:39 pm
This is what a dialog using path_knife() looks like: path_knife.png
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by 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")
-
todd burch
-
- Posts: 913
- Joined: Mon Nov 12, 2007 2:43 pm
- Location: Katy, Texas
- Name: Todd Burch
-
by 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
-
david.
-
- Posts: 162
- Joined: Wed Sep 03, 2008 10:08 pm
- Location: USA
- Name: david.
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: woodworking
- Level of SketchUp: Intermediate
by 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.
-
todd burch
-
- Posts: 913
- Joined: Mon Nov 12, 2007 2:43 pm
- Location: Katy, Texas
- Name: Todd Burch
-
by 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.
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by 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.
-
david.
-
- Posts: 162
- Joined: Wed Sep 03, 2008 10:08 pm
- Location: USA
- Name: david.
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: woodworking
- Level of SketchUp: Intermediate
by 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 
TIG
-

TIG
- Global Moderator
-
- Posts: 20380
- Joined: Mon Nov 12, 2007 7:24 pm
- Location: Northumbria UK
- Name: TIG
- Operating system: Windows
- License type: Pro
- SketchUp use: architecture
- Level of SketchUp: Advanced
by 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 
That does not meet the specifications. It will divide folder names. (The instructor grades you a C- for your effort.) 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.
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.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by 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) path = File.expand_path(path) if path.length > max ok = ((path.length-1)*0.45).to_i cut = path.split( 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 return " #{path} " end 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.)
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.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Ad Machine » 5 minutes ago
-
Ad Machine
- Robot
-
- Posts: 2012
-
Return to Developers' Forum
|