I need help creating an extension to “clean up" filenames

Basically I’m trying to make an extension to “clean up” filenames by removing underscores, periods and hyphens, converting it to title case, and ignoring the file extension.

Turn “random_picture_you.downloaded.from-the-internet.jpg” into “Random Picture You Downloaded From the Internet.jpg”

I’ve got the first part down: remove periods, hyphens and underscores.

But I don’t know how to convert it to Title Case or how to preserve the dot before the extension (.jpg | .pdf | .mp3 | .doc) or if it’s even possible.

Currently the way I do it is I select everything but the file extension part, use the PopClip extension I have to remove the unwanted characters and use PopClip’s Title Case extension.

I would like to combine all those steps or at least two of them to make the whole task smoother.

This is the extension I’ve got:

#popclip
name: Clean filename
icon: circle filled fn
javascript:
  let text = popclip.input.text;
  text = text.replaceAll(/[_]/g, ' ');
  text = text.replaceAll(/[-]/g, ' ');
  text = text.replaceAll(/[.]/g, ' ');
  popclip.pasteText(text);

How would I go about converting it to Title Case and maybe telling the extension to ignore the .jpg part?

1 Like

That’s a great start!

I added three backticks (```) on the lines before and after your code so it would be formatted as code on the forum.

I also recommend using the pipe (|) like this javascript: | because that causes the line breaks to exist in the code. Otherwiser the YAML processor merges all the lines into one. (It’s how I get away without semicolons.)

As for Title Case, that’s tricky because you have to include all the rules like which words don’t get capitalized. I think that’s beyond the scope of a snippet. But it’s easy enough to capitalize every word (including the ‘the’).

Anyway, there are loads of ways you could code this, but here’s my attempt:

#popclip
name: Clean filename
icon: circle filled fn
javascript: |
  // a function to uppercase the first letter
  function ucfirst(word) { 
    word = word.toLowerCase()
    return word.substr(0, 1).toUpperCase() + word.substr(1)
  }

  // start with the filename
  let filename = popclip.input.text

  // extract file extension, if any
  const dotPosition = filename.lastIndexOf('.')
  let extension = ''
  if (dotPosition >= 0) {
    extension = filename.substr(dotPosition)
    filename = filename.substr(0, dotPosition)
  }

  // split into words
  let words = filename.split(/[ ._-]/)

  // capitalize all words
  words = words.map(ucfirst)
  
  // join with spaces and put the extension back on
  popclip.pasteText(words.join(' ') + extension)

This is really interesting – it’s kind of an opposite to the more common “slugify” approach.

This is an interesting way to use PopClip and the solutions here will be helpful for other tasks as well.

Hazel is possibly more powerful when it comes to the content of whole folders. Its rules are applied automatically, saving you time and clicks.