automatically strip redundant spaces from filenames

Occasionally when I am inserting text into a label (for Export Multiple), or the file requester, it will have redundant (leading, trailing or extra-between-words) spaces - maybe even tabs. wxString has a partial solution:

wxString& Trim(bool fromRight = true)

Removes white-space (space, tabs, form feed, newline and carriage return) from the left or from the right end of the string (right is default).

but will only strip from one end or the other so would need to be called twice and does not deal with multiple spaces between words.

If one is not concerned with Preferences creep one would probably add a preference to turn this automatic behavior on and off. Personally, I do not bother with this preference because I always want it on!

Here is the code:
at or near line number 32 in Export.h add two new function declarations:

class TimeTrack;
class Mixer;

wxString Trim(const wxString & pString, const wxString & pWhitespace = wxT(" t"));
wxString Reduce(const wxString & pString, const wxString & pFiller = wxT(" "), const wxString & pWhitespace = wxT(" t"));

class FormatInfo

at or near line number 777 in Export.cpp define the functions:

wxString Trim(const wxString & pString, const wxString & pWhitespace) {
    const auto stringBeginning = pString.find_first_not_of(pWhitespace);
    //if (stringBeginning == std::string::npos)
    if (stringBeginning == wxString::npos)
        return wxString(wxEmptyString); // no content

    const auto stringEnding = pString.find_last_not_of(pWhitespace);
    const auto stringRange = stringEnding - stringBeginning + 1;

    return pString.substr(stringBeginning, stringRange);

wxString Reduce(const wxString & pString, const wxString & pFiller, const wxString & pWhitespace)
    // trim first
    wxString result = Trim(pString, pWhitespace);

    // replace sub ranges
    auto beginSpace = result.find_first_of(pWhitespace);
    //while (beginSpace != std::string::npos)
    while (beginSpace != wxString::npos)
        const auto endSpace = result.find_first_not_of(pWhitespace, beginSpace);
        const auto range = endSpace - beginSpace;

        result.replace(beginSpace, range, pFiller);

        const auto newStart = beginSpace + pFiller.length();
        beginSpace = result.find_first_of(pWhitespace, newStart);

    return result;

at or near what will now be line number 827 in Export.cpp exercise the two new functions (note that Reduce calls Trim):

bool Exporter::CheckFilename()
   // Strip leading and trailing spaces & remove redundant spaces
   wxString fileName(mFilename.GetName());
   fileName = Reduce (fileName);
   if (!mProject->GetDirManager()->EnsureSafeFilename(mFilename))
      return false;

Note that I am using Reduce with only one parameter thus accepting the defaults. Both Reduce and Trim could be made a little simpler for this implementation by just completely eliminating the parameters which have default values but I left them in in case they could be useful in the future.

This looks like a good case for a plug-in.
Nyquist could handle stripping/replacing spaces in labels very easily (for example, changing " My New album Tack 5 " to “my_new_album_track_05”) if only Nyquist had read/write access to label tracks.

So is “somebody” going to write the plugin? :slight_smile:


Currently Nyquist plug-ins do not have read/write access to label tracks :frowning: otherwise the plug-in would be done already.
I guess that this is my vote for giving Nyquist access to label tracks.

As it turns out the supplied C++ code is not always reliable – just throw it out!

As well as mine.