How to truncate a string (containg a path) without touching the filename?
Asked Answered
D

2

6

How to truncate a string (containing a path) without touching the filename (keep the last folder, the filename and the drive letter)?

Hi, I'm looking for a way to truncate a path to fit a specified width.

I already search on SO and I found this: Truncate a string nicely to fit within a given pixel width

But it's adding ... at the end of the string. I would like to have a similar function but it need to keep the begining and the ending..

For exemple, I have this path (string):

H:\Informatique\Personnalisation\Icones\__\Crystal GT PNG Pack\Applications\licq.png

And it need to fit the div's width like this:

H:\Informatique\...PNG Pack\Applications\licq.png

Another exemple:

D:\A___VERY___________LONG________PATH____________\myfile.png

Will be shorten to:

D:\A___VERY___________LONG________PA...\myfile.png

Last exemple:

D:\A___VERY___________LONG________PATH____________\and-a-sub-solder\myfile.png

Will be shorten to:

D:\A___VERY________...\and-a-sub-solder\myfile.png

Restriction:

  • The drive part is required (H:)
  • The filename and the extension is required (licq.png)
  • If there's multiple folders, the last folder must not be truncate, exept if everything is already truncated and it is the only way to make the string shorter.
  • If the filename is too long, truncate it in the middle.

Long filename exemple:

D:\my____file___________________________name____is___too____________long.png

Will be shorten to:

D:\my____file_________..._is___too____________long.png

I see windows and apple doing it the nice way... but I can't find any script that is near that.

Any link with similar script so I can try adjust it? Or anybody who wants to help me with that? :)

Thank you very much

Dardan answered 13/1, 2013 at 22:11 Comment(3)
Any more specific rules for truncating long filenames?Horseshoe
Is there a rule as to when the ellipsis goes at the beginning (example 1), end (example 2 & 3) or in the middle (example 4) of truncated directory/file name?Bakeman
It's just logic, if we truncate at the end, the user doesn't see the filename, at the begining, the user doesn't see the Drive Letter. The last folder generally tell something to the user... Program File doesn't mean anything for most of them ;) - If you want more exemple just ask!Dardan
T
4

That's an interesting problem, here is my solution: http://jsfiddle.net/AlienHoboken/y7SgA/

It assumes that you have a variable str with the path in it, and maxLength with your max character length.

You will need to change code slightly as str is hard coded, you'll need to change maxLength, and you'll need to change where you write the information too (it just writes to body right now).

NB: If your drive name + file name exceed the maxLength variable, it will just print out those two together, even though they are too large.

Code, incase you don't like jsfiddle:

$(document).ready(function () {
  var str = "H:\\Informatique\\Personnalisation\\Icones\\__\\Crystal GT PNG Pack\\Applications\\licq.png";
  var maxLength = 25;

  var tokens = str.split("\\");
  var drive = tokens[0];
  var fileName = tokens[tokens.length - 1];
  var len = drive.length + fileName.length;
  //remove the current lenth and also space for 3 dots and 2 slashes
  var remLen = maxLength - len - 5;

  //if remLen < 0, then it will over flow our maxLength to still maintain drive and     filename
  if (remLen > 0) {
    //remove first and last elements from the array
    tokens.splice(0, 1);
    tokens.splice(tokens.length - 1, 1);
    //recreate our path
    var path = tokens.join("\\");
    //handle the case of an odd length
    var lenA = Math.ceil(remLen / 2);
    var lenB = Math.floor(remLen / 2);
    //rebuild the path from beginning and end
    var pathA = path.substring(0, lenA);
    var pathB = path.substring(path.length - lenB);
    path = drive + "\\" + pathA + "..." + pathB + "\\" + fileName;

    //write it out
    $("body").html("Orig. Path: " + str + "<br /><br />" +
      "New Path: " + path + "<br /><br />" +
      "MaxLength: " + maxLength + "<br /><br />" +
      "New Length: " + path.length);
  } else {

    //try and fit our maxlength by taking only drive and filename
    $("body").html("Orig. Path: " + str + "<br /><br />" +
      "New Path: " + drive + "\\" + fileName + "<br /><br />" +
      "MaxLength: " + maxLength + "<br /><br />" +
      "New Length: " + (len + 1) + "<br /><br />");
  }
});
Tempura answered 13/1, 2013 at 22:53 Comment(3)
Nice! Amazing! I'll b able to work from that to finalize what I want to accomplish. Thanks AlienHoboken for this answer.Hard code is not a problem ;)Dardan
No problem. Enjoy buddy. =]Tempura
Very nice code, but if you have a filepath like H:\ploppy\licq.png then your script will produce H:\plopp...loppy\licq.png which is probably not the desirable output. I guess, one simply need to check whether the string length exceeds the max length and return the string untouched if that's not the case.Bedspring
P
4

Let me just add a bit optimized version of @AlienHoboken 's code. This version

  • works for paths with or without drive in the beggining of the string
  • works for paths with / or \ seperator
  • can omit the filename when we only need to show the folder path

Hope it helps!

function pathShorten(str, maxLength, removeFilename) {
    var splitter = str.indexOf('/')>-1 ? '/' : "\\",
        tokens = str.split(splitter), 
        removeFilename = !!removeFilename,
        maxLength = maxLength || 25,
        drive = str.indexOf(':')>-1 ? tokens[0] : "",  
        fileName = tokens[tokens.length - 1],
        len = removeFilename ? drive.length  : drive.length + fileName.length,    
        remLen = maxLength - len - 5, // remove the current lenth and also space for 3 dots and 2 slashes
        path, lenA, lenB, pathA, pathB;    
    //remove first and last elements from the array
    tokens.splice(0, 1);
    tokens.splice(tokens.length - 1, 1);
    //recreate our path
    path = tokens.join(splitter);
    //handle the case of an odd length
    lenA = Math.ceil(remLen / 2);
    lenB = Math.floor(remLen / 2);
    //rebuild the path from beginning and end
    pathA = path.substring(0, lenA);
    pathB = path.substring(path.length - lenB);
    path = drive + splitter + pathA + "..." + pathB + splitter ;
    path = path + (removeFilename ? "" : fileName); 
    //console.log(tokens, maxLength, drive, fileName, len, remLen, pathA, pathB);
    return path;
}
Pernik answered 22/9, 2017 at 9:55 Comment(1)
Wow awesome. Some people laught when I asked this but what I explained above is simple, it prevent confusion - it keeps important information visible. I'll try your version tomorrow I'm very interested to test it. Thanks!Dardan

© 2022 - 2024 — McMap. All rights reserved.