Repository for neat file name string patterns and tagger script snippets

EDIT 2016-11-02: Updated to version 0.0.4α. Also, if anyone uses Notepad++, I have a fairly good definition of the Picard Tagger Script language, posted below.


Here’s my first attempt at a naming script. You just maybe might be able to guess that I’m a software professional. :wink: But I’m new to this level of detail in this language. (I don’t even know what the language is called or where it’s documented, although I’ve specified file and folder names with it in other tagging apps.)

I want to learn how to create functions to get rid of all the repeated code and to create my own unique functions. And if there’s documentation beyond the Scripting page on the Picard site I’d love to know where it is.

Anyway, if you see anything you like or you think could be improved, don’t hesitate to comment.

Pardon the formatting - it’s copied from the text editor I’m using, with tabs replaced by spaces for display here. This was written for Picard v1.3.2, my first Picard. No guarantees that it works with earlier versions.

$noop(MusicBrainz Picard file naming script.

   Author: Michael Piz [Your intrepid author {YIA}; @Piz on MusicBrainz]
   Version 0.0.4α [2016-11-01, edit history at end]

   Copyright 2016 by Michael Pizolato. This work is licensed under a Creative
   Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
   Details are available at http://creativecommons.org/licenses/by-nc-sa/4.0/
   
   THIS IS AN ALPHA RELEASE!
   USE AT YOUR OWN RISK!

   YIA has a very specific naming convention for files and folders because, 
   while he's a genial fellow, he does have minor OCD tendencies. Here's what 
   this script generates for the examples in Picard's options [as of v1.3.2; 
   the line breaks are for display formatting only]: 
   
   ROOT/Beatles, The/Help! [soundtrack]/Beatles, The • Help! [soundtrack] • 
   07 · Ticket to Ride.mp3

   ROOT/Various Artists/Coup d'État, Volume 1 - Ku De 
   Ta - Prologue/Snowboy · Various Artists • Coup d'État, Volume 1 - Ku De 
   Ta - Prologue • 02.05 · I've Got to Learn the Mambo.mp3 

   Here are some from YIA's own library:

   ROOT/Wings/Wings over America/Wings • Wings over America • 02.11 · Band on 
   the Run [live].mp3 
   
   ROOT/Saint-Saëns, Camille/Saint-Saëns - Piano Concertos 1-5; Wedding Cake 
   Caprice-Valse/Saint-Saëns, Camille • Saint-Saëns - Piano Concertos 1-5; 
   Wedding Cake Caprice-Valse • 02.08 · 'Africa' Fantaisie, Op. 89
   
   Broken down, they look like this:

   ARTIST FOLDER: Beatles, The
    ALBUM FOLDER: Help! [soundtrack]
      TRACK FILE: Beatles, The • Help! [soundtrack] • Track 07 · Ticket to 
                  Ride.mp3

   ARTIST FOLDER: Various Artists
    ALBUM FOLDER: Coup d'État, Volume 1 - Ku De Ta - Prologue
      TRACK FILE: Snowboy · Various Artists • Coup d'État, Volume 1 - Ku De
                  Ta - Prologue • Disc 02 · Track 05 · I've Got to Learn the
                  Mambo.mp3

   ARTIST FOLDER: Wings
    ALBUM FOLDER: Wings over America
      TRACK FILE: Wings • Wings over America • 02.11 · Band on the Run [live]

   ARTIST FOLDER: Saint-Saëns, Camille
    ALBUM FOLDER: Saint-Saëns - Piano Concertos 1-5; Wedding Cake Caprice-Valse
      TRACK FILE: Saint-Saëns, Camille • Saint-Saëns - Piano Concertos 1-5; 
                  Wedding Cake Caprice-Valse • 02.08 · 'Africa' Fantaisie, Op. 
                  89.mp3

   Track filenames duplicate all the folder information because in most UI 
   file search r only the filename of a match is displayed. This way, 
   all the infomation will be in the search results, resulting in unique 
   matches. YIA tends to be impatient, especially with looking things up more 
   than once.

   Here are examples of artist folders:
   
   [Various Artists]
   [unknown artist]
   10,000 Maniacs
   Beatles, The
   Davis, Sammy, Jr
   
   In addition to individual album folders within those, there can be 
   "[unknown album]" and "[singles]" folders. Within any of these, individual 
   track files are stored. In the "[Various Artists]" folder there are 
   individual album folders [and possibly "[unknown album]"]. Track names in 
   the "[Various Artists]" album folders include the form "Artist · Various 
   Artists" so the individual artist is included. Tracks missing a title have 
   "unknown title" assigned as the title. Thus, should all fail, the 
   following is possible [though somewhat unlikely]:
   
   [unknown artist]/[unknown album]/[unknown artist] • [unknown album] • 
   [unknown title].mp3
   
   The brackets are added so those folders sort to the top of an ascending 
   alphabetical list [in Windows, anyway] instead of being mixed in with the  
   individual artist or album folders.
   
   Final note: You may wonder why YIA has created all these verbose constants 
   instead of just using their [shorter, duh] corresponding characters or 
   strings. That's because he doesn't trust himself not to drop extraneous 
   characters in this language. This language works by building a string from 
   the results of all the functions used plus, importantly, any explicit 
   characters in the script. For example, if you put "xyzzy" at the end of 
   your script, just literally like that, whatever final string you generate 
   will end in "xyzzy" even though it's not generated by a function call, and 
   no error will be displayed because that's how the language works. [If you 
   are insane and want to name all your files "foobar", your script can 
   consist solely of that string.] Stray spaces or punctuation or whatnot 
   strewn hither and yon could affect the final string in very difficult to 
   debug ways. Therefore, YIA, being completely untrusting of himself in such 
   matters, doesn't allow himself the possibility of strays. By using 
   variables as constants and never including whitespace in function calls 
   [except at the beginning of lines, where it is ignored], the possibility of 
   stray character gremlins is all but eliminated. [In addition, using 
   "_kNull" makes it explicit where null strings are used, also making 
   debugging, and reading the code, easier.]
   )

$noop(Basic constants.)
   $set(_kNull,)
   $set(_kSpace, )
   $set(_kComma,\,)
   $set(_kSingleQuote,')
   $set(_kEllipsis,…)
   $set(_kPeriod,.)
   $set(_kAmpersand, & )
   $set(_kNoteBracketLeft,[)
   $set(_kNoteBracketRight,])
$noop(End basic constants.)

$noop(Aticles.)
   $set(_kA,A)
   $set(_kAn,An)
   $set(_kThe,The)
$noop(End articles.)

$noop(Folder and track name constants.)
   $set(_kFolderSep,/)
   $noop(
      There are three levels of separators within track names. The top levels 
      are "Artist • Album • Track", corresponding to "Artist/Album/Track" in 
      the file system. In track names, for example when the album artist is 
      "Various Artists", one of the possible second levels is "Artist · 
      Various Artists" [see the Snowboy and Saint-Saëns examples above; also 
      note that the first and second level separators are different 
      characters, i.e. U+2022: Bullet and U+00B7: Middle Dot; the third level 
      separartor is U+002D: Hyphen-Minus, the simple minus sign]. The third 
      level separator replaces any characters in artist/album/track names that 
      are illegal filename characters, e.g. "Some Band: Greatest Hits" becomes 
      "Some Band - Greatest Hits" [again, see the Snowboy and Saint-Saëns 
      examples].
      )
      $set(_kTrackSep1, • )
      $set(_kTrackSep2, · )
      $set(_kTrackSep3, - )
$noop(End folder and track name constants.)

$noop(Filename substitution regex constants.)
   $noop(All bracket types.)
      $set(_kReOpenBrackets,[\\%_kNoteBracketLeft%\({])
      $set(_kReCloseBrackets,[\\%_kNoteBracketRight%\){])
   $noop(For replacing three consecutive periods with one ellipsis.)
      $set(_kRe3Dots,\\%_kPeriod%\\%_kPeriod%\\%_kPeriod%)
   $noop(Trim all multiple spaces down to single spaces.)
      $set(_kMultiSpace,\\s+)
   $noop(
      Remove characters not permitted in file or folder names. These are
      treated as separators and replaced with _kTrackSep2. Underscore isn't
      really an illegal char but having it here gets it replaced by a
      separator.
      )
      $set(_kReIllegalFileChars,\\s*[/\\><*:_|]+\\s*)
   $noop(
      Replace all quote marks with single quotes. The double quote isn't part
      of the illegal chars because those get dropped, not replaced.
      )
      $set(_kReQuoteMarks,["“”‘’]+)
   $noop(
      Remove question marks entirely. E.g., "What Kind of Fool Am I?" becomes
      "What Kind of Fool Am I". This isn't part of the illegal chars because
      those get dropped, not replaced. The inverted question mark is dropped
      for aesthetic reasons - it won't have its mate.
      )
      $set(_kReQuestionMarks,[¿?]+)
   $noop(
      Windows doesn't allow periods as the final char of folder names. It 
      automatically drops them in Windows Explorer, but YIA doesn't know what 
      happens programatically so it's best to drop them here.
      )
      $set(_kReEndPeriod,\\.\$)
   $noop(Case insensitivity.)
      $set(_kReCaseInsensitive,\(?i\))
   $noop(And. Always replace wth '&'.)
      $set(_kReAnd,%_kReCaseInsensitive%\\sand\\s)
   $noop(
      Remove "feat." or "ft." [with or without the periods] plus everything 
      that follows [and precedes, if inside brackets].
      )
      $set(_kReFeat,
         \\s+\(%_kReOpenBrackets%.*\)?f\(ea\)?t\\.?.*\(%_kReCloseBrackets%.*\)?
         )
$noop(End filename substitution regex constants.)

$noop(Artist/album/title/media/track constants.)
   $noop(
      Release types. Comment shows whether value goes in album or track 
      notes. Album and single determine the others. "Other" isn't used 
      because it provides no information.
      )
      $set(_kAlbum,album)           $noop(N/A)
      $set(_kSingle,single)         $noop(N/A)
      $set(_kEP,ep)                 $noop(album)
      $set(_kBroadcast,broadcast)   $noop(track)
      $set(_kOther,other)           $noop(N/A)
   $noop(
      Secondary release types. Comment shows whether value goes in album 
      or track notes.
      )
      $set(_kCompilation,compilation)  $noop(album)
      $set(_kSoundtrack,soundtrack)    $noop(album)
      $set(_kAudiobook,audiobook)      $noop(album)
      $set(_kMixtape,mixtape/street)   $noop(album)
      $set(_kSpokenword,spokenword)    $noop(track)
      $set(_kInterview,interview)      $noop(track)
      $set(_kLive,live)                $noop(track)
      $set(_kRemix,remix)              $noop(track)
      $set(_kDJMix,dj-mix)             $noop(track)
   $noop(Default artist/album/title.)
      $set(_kUnknownArtist,unknown artist)
      $set(_kUnknownAlbum,unknown album)
      $set(_kNoTitle,unknown title)
   $noop(
      NOTE: The next two must duplicate the "Various artists" and "Non-album
      tracks" option settings. I've submitted a Picard feature request to
      have those options be made available as tags, to avoid having to
      maintain them in two places. That ticket can be found at 
      https://tickets.musicbrainz.org/browse/PICARD-849
      )
      $set(_kVariousArtists,Various Artists)
      $set(_kNonAlbumTracks,%_kNoteBracketLeft%singles%_kNoteBracketRight%)
   $noop(Media and track number.)
      $set(_kDefaultMedia,Disc)
      $set(_kTrackTxt,Track )
$noop(End artist/album/title/media/track constants.)

$noop(Copies of existing tags.

   After this, only the copies are used. In some instances, the tag is later
   replaced by the processed copy.
   )
   $set(_media,%media%)
   $set(_totaldiscs,%totaldiscs%)
   $set(_discNum,%discnumber%)
   $set(_trackNum,%tracknumber%)
   $noop(Album, artist, album artist, and title are more complex.)
      $set(_artist,
         $if2(
            %artistsort%,
            %artist%,
            %albumartistsort%,
            %albumartist%,
            %_kUnknownArtist%
            )
         )
      $set(_albumArtist,
         $noop(albumartistsort already handles "A" and The")
         $swapprefix(
            $if2(%albumartistsort%,
               %albumartist%,
               %artistsort%,
               %artist%,
               %_kUnknownArtist%
               ),
            %_kAn%
            )
         )
      $set(_album,
         $swapprefix(
            $if2(%album%,%_kUnknownAlbum%),
            %_kA%,%_kAn%,%_kThe%
            )
         )
      $set(_title,
         $swapprefix(
            $if2(%title%,%_kNoTitle%),
            %_kA%,%_kAn%,%_kThe%
            )
         )
$noop(End copies of existing tags.)

$noop(Album/artist/track characteristics.)
   $set(_isVariousArtists,$eq(%albumartist%,%_kVariousArtists%))
   $set(_differentAlbumArtist,$ne(%artistsort%,%albumartistsort%))
   $set(_isUnknownArtist,
      $or($not(%albumartist%),$eq(%albumartist%,%_kUnknownArtist%))
      )
   $set(_isUnknownAlbum,
      $or($not(%album%),$eq(%album%,%_kUnknownAlbum%))
      )
   $set(_isSingle,$in(%releasetype%,%_kSingle%))
$noop(End track characteristics.)

$noop(Album/track notes.)
   $set(_relType,%_kSoundtrack%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_albumNotes,
         %_albumNotes%$if(%_albumNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kAudiobook%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_albumNotes,
         %_albumNotes%$if(%_albumNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kMixtape%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_albumNotes,
         %_albumNotes%$if(%_albumNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kCompilation%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($not(%_isVariousArtists%)
      $if($rsearch(%_secondaryreleasetype%,%_pattern%),
         $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
         $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
         $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
         $set(_albumNotes,
            %_albumNotes%$if(%_albumNotes%,%_kComma%%_kSpace%)%_relType%
            )
         ),
      %_kNull%
      )
   $set(_relType,%_kEP%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%releasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_albumNotes,
         %_albumNotes%$if(%_albumNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kLive%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kBroadcast%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%releasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         ),
      )
   $set(_relType,%_kSpokenword%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kInterview%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kRemix%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $set(_relType,%_kDJMix%)
   $set(_pattern,
      %_kReCaseInsensitive%\(%_kReOpenBrackets%?%_relType%%_kReCloseBrackets%?\)
      )
   $if($rsearch(%_secondaryreleasetype%,%_pattern%),
      $set(_artist,$rreplace(%_artist%,%_pattern%,%_kNull%))
      $set(_album,$rreplace(%_album%,%_pattern%,%_kNull%))
      $set(_title,$rreplace(%_title%,%_pattern%,%_kNull%))
      $set(_trackNotes,
         %_trackNotes%$if(%_trackNotes%,%_kComma%%_kSpace%)%_relType%
         )
      )
   $if(%_albumNotes%,
      $set(_albumNotes,
         %_kSpace%%_kNoteBracketLeft%%_albumNotes%%_kNoteBracketRight%
         )
      )
   $if(%_trackNotes%,
      $set(_trackNotes,
         %_kSpace%%_kNoteBracketLeft%%_trackNotes%%_kNoteBracketRight%
         )
      )
$noop(End album/track notes.)

$noop(Set up file/folder names.)
   $noop(Artist. Only used for the track filename.)
      $set(_artist,$rreplace($rreplace($rreplace($rreplace(%_artist%,
         %_kReFeat%,%_kNull%),
         %_kMultiSpace%,%_kSpace%),
         %_kRe3Dots%,%_kEllipsis%),
         %_kReAnd%,%_kAmpersand%)
         )
      $noop(
         At this point the artist to be used for tagging is "clean", so set
         the actual tag value. Similarly for album artist and album, below.
         )
         $set(artist,%_artist%)
      $noop(Scrub _artist for file names.)
         $set(_artist,$rreplace($rreplace($rreplace(%_artist%,
            %_kReQuestionMarks%,%_kNull%),
            %_kReQuoteMarks%,%_kSingleQuote%),
            %_kReIllegalFileChars%,%_kTrackSep3%)
            )
      $noop(Make the filename part.)
         $set(_artistTrack,
            %_artist%
            $if(%_differentAlbumArtist%,
               %_kTrackSep2%,
               %_kTrackSep1%
               )
            )
   $noop(End artist.)

   $noop(Album artist.)
      $set(_albumArtist,$rreplace($rreplace($rreplace($rreplace(%_albumArtist%,
         %_kReFeat%,%_kNull%),
         %_kMultiSpace%,%_kSpace%),
         %_kRe3Dots%,%_kEllipsis%),
         %_kReAnd%,%_kAmpersand%)
         )
      $set(albumartist,%_albumArtist%)
      $set(_albumArtist,$rreplace($rreplace($rreplace(%_albumArtist%,
         %_kReQuestionMarks%,%_kNull%),
         %_kReQuoteMarks%,%_kSingleQuote%),
         %_kReIllegalFileChars%,%_kTrackSep3%)
         )
      $set(_albumArtist,$rreplace(%_albumArtist%,%_kReEndPeriod%,%_kNull%))
      $if(%_differentAlbumArtist%,
         $noop(_albumArtistTrack is unnecesasry when they match.)
         $set(_albumArtistTrack,
            $if(%_isUnknownArtist%,
               %_kNoteBracketLeft%%_albumArtist%%_kNoteBracketRight%,
               %_albumArtist%
               )
               %_kTrackSep1%
            )
         )
      $set(_albumArtistFolder,
         $if($or(%_isVariousArtists%,%_isUnknownArtist%),
            %_kNoteBracketLeft%%_albumArtist%%_kNoteBracketRight%,
            %_albumArtist%
            )
            %_kFolderSep%
         )
   $noop(End album artist.)

   $noop(Album.)
      $set(_album,$rreplace($rreplace($rreplace($rreplace(%_album%,
         %_kReFeat%,%_kNull%),
         %_kMultiSpace%,%_kSpace%),
         %_kRe3Dots%,%_kEllipsis%),
         %_kReAnd%,%_kAmpersand%)
         )
      $set(_album,%_album%%_albumNotes%)
      $set(album,%_album%)
      $set(_album,$rreplace($rreplace($rreplace(%_album%,
         %_kReQuestionMarks%,%_kNull%),
         %_kReQuoteMarks%,%_kSingleQuote%),
         %_kReIllegalFileChars%,%_kTrackSep3%)
         )
      $set(_album,$rreplace(%_album%,%_kReEndPeriod%,%_kNull%))
      $set(_albumTrack,$if($not(%_isSingle%),%_album%%_kTrackSep1%))
      $set(_albumFolder,
         $if(%_isUnknownAlbum%,
            %_kNoteBracketLeft%%_album%%_kNoteBracketRight%,
            %_album%
            )
            %_kFolderSep%
         )
   $noop(End album.)

   $noop(Media type.)
      $set(_media,$if2(%_media%,%_kDefaultMedia%)%_kSpace%)
   $noop(End media type.)

   $noop(Disc number, if necessary.)
      $set(_discNum,
         $if($gt(%_totaldiscs%,1),
            $num(%_discNum%,2)%_kPeriod%,
            %_kNull%
            )
         )
   $noop(End end disc number. )

   $noop(Track number.)
   $set(_trackNum,
      $if($and(
            %_trackNum%,
            $or($not(%_isSingle%),$ne(%_album%,%_kNonAlbumTracks%))
            ),
         $num(%_trackNum%,2)%_kTrackSep2%
         )
      )
   $noop(End track number.)
   
   $noop(Title.)
      $set(_title,$rreplace($rreplace($rreplace($rreplace(%_title%,
         %_kReFeat%,%_kNull%),
         %_kMultiSpace%,%_kSpace%),
         %_kRe3Dots%,%_kEllipsis%),
         %_kReAnd%,%_kAmpersand%)
         )
      $set(_title,%_title%%_trackNotes%)
      $set(title,%_title%)
      $set(_title,$rreplace($rreplace($rreplace(%_title%,
         %_kReQuestionMarks%,%_kNull%),
         %_kReQuoteMarks%,%_kSingleQuote%),
         %_kReIllegalFileChars%,%_kTrackSep3%)
         )
$noop(???)
      $set(_trackFile,
         %_artistTrack%%_albumArtistTrack%%_albumTrack%%_discNum%%_trackNum%
         %_title%
         )
   $noop(End title.)
$noop(End set up file/folder names.)

$noop(
   Finally, apply it all to the actual folders and file.
   )
%_albumArtistFolder%%_albumFolder%%_trackFile%

$noop(EDIT HISTORY
   2016-11-01 0.0.4α
      1. Revamped naming convention. Now "Various Artists" is an artist and 
         the album artist goes in the track filename."[Various Artists]" will 
         be a folder at the same level as other artists. Same for "[unknown 
         artist]". "[unknown album]" will get its own folder under each 
         artist, if necessary. "[unknown artist]", "[unknown album]", and 
         "[unknown title]" will be included in track filenames, if necessary.
      2. Updated comments to reflect all that.
      3. Removed a bunch of unnecessary "_kNull"s.
      4. Bug fixes.
   2016-10-28 0.0.3α
      1. Added replacing all occurrances of " and " with " & ".
      2. Added moving articles to the end of title and album.
      3. Tweaked handling for primary/secondary release types.
      4. Bug fixes.
   2016-10-27 0.0.2α
      1. Added handling for all primary/secondary release types.
      2. Tweaked regex for "feat." handling.
      3. Bug fixes.
   2016-10-26 0.0.1α
      1. Initial version.
   )
3 Likes