$noop( ######################################################################## # # # MusicBrainz Picard File Naming Script v3.0 # # 2026-01-29 # # # # License: GPL-3.0 # # # ######################################################################## # # VERSION HISTORY: # # v1.0 - "MBP YA Magic-Script v2.7" by amd/17500mph # Based on "MBP Magic Script" by Ski-lleR # Filter contributions by avibrazil # https://github.com/avibrazil/picard-scripting # # v2.0 - User additions and modifications # # v3.0 - Complete refactoring with comprehensive documentation # Organized configuration, inline examples, detailed comments # Removed redundant sections, added reference tables # ######################################################################## # # WHAT THIS SCRIPT DOES: # # This script automatically organizes your music library with extensive # customization options. It can: # # • Organize by artist with alphabetical folders [A/, B/, C/, etc.] # • Separate albums, singles, EPs, live recordings into subfolders # • Handle multi-disc albums with disc subfolders # • Special handling for: Various Artists, Soundtracks, Audiobooks # • Vinyl support with MusicBrainz-style track numbering [A1, B1, etc.] # • Display audio quality in filenames [bitrate, sample rate, etc.] # • Genre-based pre-sorting for advanced organization # • Handle incomplete albums separately # • Cross-platform filename compatibility [Windows/Linux/macOS] # # EXAMPLE OUTPUT: # # /B/Beatles, The/\(1969\) Abbey Road [CD - MP3]/01. Come Together.mp3 # /P/Pink Floyd/Albums/\(1979\) The Wall [CD - FLAC]/Disc01/01. In the Flesh.flac # /Various/\(2011\) Now That's What I Call Music! 80 [CD - MP3]/Disc01/03. Rolling in the Deep [Adele].mp3 # ######################################################################## # # REQUIRED PLUGINS: # # 1. Additional Artists Variables Plugin \(REQUIRED\) # Author: Bob Swift [rdswift] # Source: https://github.com/rdswift/picard-plugins/tree/2.0_RDS_Plugins # License: GPL-2.0 or later # # This plugin provides enhanced artist variables used throughout # this script. Without it, artist sorting will fall back to basic # %albumartist% and %artist% tags. # # OPTIONAL PLUGINS: # # 2. Last.fm.ng Plugin \(for genre-based category sorting\) # Source: https://github.com/fdemmer/Picard-Last.fm.ng-Plugin # Only needed if you enable genre-based root sorting # # 3. Classical Extras Plugin \(for classical music workflow\) # Only needed if you enable Classical music handling # Requires setting: \$set\(_isClassical,1\) in a separate script # ######################################################################## # # QUICK START: # # 1. Install the "Additional Artists Variables" plugin # 2. Copy this entire script into: Options > File Naming > Script # 3. Set your destination directory: Options > File Naming > Move Files # 4. Review configuration settings below [Section 2] # 5. Tag your files and save! # # For detailed documentation, see README.md and SCRIPT_GUIDE.md # ######################################################################## ) $noop( ######################################################################## # # # SECTION 1: CONSTANTS # # # # These define default names for special cases. Customize if needed. # # # ######################################################################## ) $noop( MusicBrainz Special Artist IDs ) $set(_cUnknownArtistID,125ec42a-7229-4250-afc5-e057484327fe) $set(_cVariousArtistID,89ad4ac3-39f7-470e-963a-56509c546377) $noop( Default Display Names - Customize these to your preferred names ) $set(_cUnknownArtist,[Unknown Artist]) $set(_cVariousArtist,[Various Artists]) $set(_cUnknownAlbum,[Unknown Album]) $set(_cNoTitle,[Unknown Title]) $set(_cClassical,[Classical]) $set(_cSoundtrack,[Soundtracks]) $set(_cSingles,[~Singles~]) $set(_cOther,[Other]) $noop( Regex Constants ) $set(_reCaseInsensitive,\(?i\)) $noop( ######################################################################## # # # SECTION 2: CONFIGURATION # # # # Customize these settings to control how your music is organized. # # Settings use 0 = disabled, 1 = enabled unless otherwise noted. # # # ######################################################################## ) $noop( ======================================================================== 2.1 Development & Testing Settings ======================================================================== ) $noop( DevMode: Use test values instead of actual metadata ) $noop( 0 = Normal operation \(use real metadata\) ) $noop( 1 = Test mode \(use hardcoded values below for testing\) ) $noop( WARNING: MUST be set to 0 for actual use! ) $set(_devMode,0) $noop( Quick No-Name Format: Skip filename formatting ) $noop( 0 = Full formatting with all metadata ) $noop( 1 = Minimal formatting \(for quick sorting from unmatched files\) ) $noop( Disables audio metrics display when enabled ) $set(_quickNoNameFormat,0) $noop( ======================================================================== 2.2 Display Options - What Shows in Folder/File Names ======================================================================== ) $noop( Show Date/Year in Album Folder Name ) $noop( 0 = Album Name only ) $noop( 1 = Album Name \(Year\) ) $noop( Example: "Abbey Road" vs "\(1969\) Abbey Road" ) $set(_showDate,1) $noop( Show Record Label in Album Folder Name ) $noop( 0 = Don't show label ) $noop( 1 = Show label ) $noop( Example: "Album \(1985\) [Epic Records]" ) $set(_showRecordLabel,0) $noop( Show Release Status in Album Folder Name ) $noop( 0 = Don't show status ) $noop( 1 = Show status \(Official, Promotion, Bootleg, etc.\) ) $noop( Example: "Album \(1985\) [Promotion]" ) $set(_showReleaseStatus,0) $noop( Show Catalogue Number in Album Folder Name ) $noop( 0 = Don't show catalog number ) $noop( 1 = Show catalog number ) $noop( Example: "Album \(1985\) [XPCD-1234]" ) $set(_showCatalogueNumber,0) $noop( Show MusicBrainz ID and Catalog Number ) $noop( 0 = Don't show ) $noop( 1 = Show in format [mbid] {catalog} ) $set(_showIDNum,1) $noop( Show Track Duration in Filename ) $noop( 0 = Don't show duration ) $noop( 1 = Show duration [5m34s] ) $noop( Example: "01. Song Title [3m45s].mp3" ) $if($eq(%_quickNoNameFormat%,1),$set(_showTime,0),$set(_showTime,1)) $noop( ^ ) $noop( Change this number --->---------->---------->----------->--------^ ) $noop( Show Audio Quality Metrics in Filename ) $noop( 0 = Don't show quality info ) $noop( 1 = Show bitrate, sample rate, CBR/VBR, channels ) $noop( Example: "01. Song [320 44.1KHz CBR 2ch].mp3" ) $if($eq(%_quickNoNameFormat%,1),$set(_showBandwidth,0),$set(_showBandwidth,1)) $noop( ^ ) $noop( Change this number ----->---------->---------->---------->----------->--------^ ) $noop( ======================================================================== 2.3 Primary Organization Structure ======================================================================== ) $noop( Root Directory Organization Method ) $noop( 1 = By Last.fm category/genre \(requires Last.fm.ng plugin\) ) $noop( Example: /Rock/Artist/Album/ ) $noop( 2 = By artist first letter \(recommended\) ) $noop( Example: /B/Beatles, The/Album/ ) $set(_orderTypeForRoot,2) $noop( Artist Name Sorting Method ) $noop( 1 = First letter of first name ) $noop( Example: "Madonna" in /M/Madonna/ ) $noop( 2 = First letter of last name \(uses sort tags\) ) $noop( Example: "Weird Al Yankovic" in /Y/Yankovic, Weird Al/ ) $noop( 3 = No alphabetical separation ) $noop( Example: /Artist/Album/ \(no letter folders\) ) $set(_orderTypeForArtist,1) $noop( Separate Albums by Type in Artist Folder ) $noop( 0 = All releases directly in artist folder ) $noop( Example: /Artist/Album1/, /Artist/Album2/ ) $noop( 1 = Separate into subfolders by type ) $noop( Example: /Artist/Albums/Album1/, /Artist/Singles/Single1/ ) $set(_separateByTypeInArtistDirectory,1) $noop( Separate Regular Albums into Albums/ Subfolder ) $noop( 0 = Albums directly in artist folder ) $noop( 1 = Albums in Albums/ subfolder ) $noop( Only applies when _separateByTypeInArtistDirectory = 1 ) $set(_separateAlbum,0) $noop( Root Level File Type Separation ) $noop( 0 = Don't separate by file type at root ) $noop( 1 = Separate by extension: /MP3/, /FLAC/, /M4A/ ) $set(_rootLevelTypeSeparation,0) $noop( Album Level File Type Separation ) $noop( 0 = Don't separate by file type in album ) $noop( 1 = Separate: /Album/MP3/, /Album/FLAC/ ) $set(_albumLevelTypeSeparation,0) $noop( Show Album Name Before Type Folder ) $noop( 0 = Just type folder: /Album/MP3/ ) $noop( 1 = Album name + type: /Album/Album MP3/ ) $noop( Only applies when _albumLevelTypeSeparation = 1 ) $set(_albumNameAtTypeSeparation,0) $noop( ======================================================================== 2.4 Incomplete Albums Handling ======================================================================== ) $noop( How to Handle Albums with Extra Tracks ) $noop( When matched tracks < total tracks on release: ) $noop( 0 = Mark as incomplete ) $noop( 1 = Mark as complete \(show silver star, not gold\) ) $set(_extraTrackHandling,1) $noop( Early Presort for Incomplete Albums ) $noop( 0 = Handle incomplete status later in path ) $noop( 1 = Separate incomplete albums early ) $noop( Example: /- Partial/Artist/Album/ ) $set(_earlierPresortForIncompletes,1) $noop( ======================================================================== 2.5 Multi-Disc Handling ======================================================================== ) $noop( Use Subdirectories for Multi-Disc Albums ) $noop( 0 = All discs in same folder, track numbers like 101, 102, 201, 202 ) $noop( Example: /Album/101. Track.mp3, /Album/201. Track.mp3 ) $noop( 1 = Each disc in subfolder: /Album/[Disc1]/, /Album/[Disc2]/ ) $noop( Example: /Album/[Disc1]/01. Track.mp3 ) $set(_useSubDiscDirectory,1) $noop( Merge Single Disc When Not Using Subfolder ) $noop( 0 = Always use disc prefix in multi-disc naming ) $noop( 1 = Skip disc folder if only one disc ) $noop( Only applies when _useSubDiscDirectory = 0 ) $set(_mergeDiscWhenNotUsingSubDirectory,0) $noop( Show Disc Subtitle in Folder Name ) $noop( 0 = Just disc number: [Disc1] ) $noop( 1 = Include subtitle: [Disc1 - Subtitle] ) $set(_showDiscSubtitle,1) $noop( Vinyl Disc Naming ) $set(_nameForTypeCD,Disc) $set(_nameForTypeVinyl,Side) $noop( Use MusicBrainz Style Track Numbering for Vinyl ) $noop( 0 = Standard numbering: 01, 02, 03 ) $noop( 1 = Vinyl style: A1, A2, B1, B2 ) $noop( Only applies to Vinyl media type ) $set(_useMusicBrainzStyleForVinylTrack,1) $noop( ======================================================================== 2.6 Special Collections Directories ======================================================================== ) $noop( Soundtrack Albums Directory ) $set(_soundTracksDirectory,Soundtrack/) $noop( Various Artists Directory ) $set(_variousArtistsDirectory,Various/) $noop( Global Compilations Directory ) $set(_compilationsGSubDirectory,Compilations/) $noop( Audiobooks Directory ) $set(_audiobooksDirectory,Audiobook/) $noop( Podcasts Directory ) $set(_podcastSubDirectory,Podcast/) $noop( Incomplete Albums Directory Name ) $set(_incompleteDirectory,Partial) $noop( ======================================================================== 2.7 Artist-Level Subfolder Names \(Type Separation\) ======================================================================== ) $noop( Customize the names of subfolders when separating by type ) $noop( Format: /Artist/[subfolder_name]/Album/ ) $set(_albumSubDirectory,Albums/) $set(_compilationsASubDirectory,Compilation/) $set(_coverSubDirectory,Cover/) $set(_tributeSubDirectory,Tribute/) $set(_singlesSubDirectory,Singles/) $set(_liveSubDirectory,Live/) $set(_epSubDirectory,EP/) $set(_broadcastSubDirectory,Broadcast/) $set(_interviewSubDirectory,Interview/) $set(_videoSubDirectory,Video/) $set(_otherSubDirectory,Others/) $noop( ======================================================================== 2.8 Advanced: Genre-Based Pre-Sorting ======================================================================== ) $noop( Enable Genre SubSort at Root Level ) $noop( 0 = Disabled ) $noop( 1 = Enable genre-based pre-sorting ) $noop( Requires manually setting %genresort% tag on files ) $noop( Example: /Holiday/Artist/Album/, /Classical/Artist/Album/ ) $set(_isSubSort,1) $noop( Genre SubSort Directory Definitions ) $noop( These create custom root folders based on %genresort% tag value ) $noop( To use: Set %genresort% tag to trigger word \(case-sensitive\) ) $set(_subSortGame,Arcade/) $set(_subSortDJBits,DJBits/) $set(_subSortClassical,Classical/) $set(_subSortDemento,Dementia/) $set(_subSort12Inch,12 Inch Mix/) $set(_subSortDisney,Disney/) $set(_subSortPodcast,Podcast/) $set(_subSortInterview,Interview/) $set(_subSortBroadcast,Broadcast/) $set(_subSortReserved,Singles Candidates/) $set(_subSortPreTag,No MBID/) $set(_subSortHoliday,Holiday/) $set(_subSortCountry,Country/) $set(_subSortBlues,Blues/) $set(_subSortJazz,Jazz/) $noop( Seasonal SubSort Directories ) $set(_subSort2Oct,Spooktacular/) $set(_subSort2Nov,Fallback/) $set(_subSort2Dec,Here Comes Santa/) $set(_subSort2Jan,Wintertime/) $set(_subSort2Feb,Will You Be My Valentine?/) $set(_subSort2Mar,Spring is in the Air/) $set(_subSort2Apr,Foolish/) $set(_subSort2May,Maybe/) $set(_subSort2June,SumSumSummertime/) $set(_subSort2July,Fireworks & Stuff/) $set(_subSort2Aug,SumSumSummertime/) $set(_subSort2Sept,SumSumSummertime/) $noop( ======================================================================== 2.9 Tribute and Cover Album Handling ======================================================================== ) $noop( Place Tribute/Cover Albums with Original Artist ) $noop( 0 = Tribute albums filed under tribute artist ) $noop( 1 = File under original artist being tributed/covered ) $noop( Requires setting custom tag %coverTributeSort% = "Tribute" or "Cover" ) $noop( And setting %albumartistsort% to the original artist name ) $set(_altArtistSort,1) $noop( ======================================================================== 2.10 Track Breakdown by Artist \(Advanced\) ======================================================================== ) $noop( Separate Tracks by Artist Within Album ) $noop( 0 = All tracks directly in album folder ) $noop( 1 = Create subfolder for each track artist ) $noop( Example: /Album/Artist1/Track1.mp3, /Album/Artist2/Track2.mp3 ) $noop( Special case use - typically for left-side compilations ) $set(_showTrackArtistSeparation,0) $noop( ======================================================================== 2.11 Length and Padding Settings ======================================================================== ) $noop( Minimum Padding for Disc Numbers ) $noop( Auto-pads to length of total discs, but at least this many digits ) $set(_PaddedDiscNumMinLength,1) $noop( Minimum Padding for Track Numbers ) $noop( Auto-pads to length of total tracks, but at least this many digits ) $set(_PaddedTrackNumMinLength,2) $noop( Maximum Length for Album Title ) $noop( Album titles longer than this will be truncated with "..." ) $set(_aTitleMaxLength,65) $noop( Maximum Length for Track Title ) $noop( Track titles longer than this will be truncated with "..." ) $set(_tTitleMaxLength,65) $noop( Maximum Length for Complete Filename ) $noop( Full filename \(with metadata\) truncated to this length ) $set(_tFilenameMaxLength,120) $noop( ######################################################################## # # # END OF CONFIGURATION SECTION # # # # The sections below contain the script logic and should not be # # modified unless you know what you're doing. See SCRIPT_GUIDE.md # # for detailed explanations of how each section works. # # # ######################################################################## ) $noop( ######################################################################## # # # SECTION 3: DEFAULT VARIABLE SETUP # # # # Sets up fallback values when metadata or plugin data is missing. # # # ######################################################################## ) $noop( Album Artist Variables - with fallbacks ) $set(_nFAA,$if2(%_artists_album_all_std%,%albumartist%,%_cUnknownArtist%)) $set(_nPAA,$if2(%_artists_album_primary_std%,%albumartist%,%_cUnknownArtist%)) $set(_nFAAS,$if2(%_artists_album_all_sort%,%albumartistsort%,%_cUnknownArtist%)) $set(_nPAAS,$if2(%_artists_album_primary_sort%,%albumartistsort%,%_cUnknownArtist%)) $set(_nFAAPS,$if2(%_artists_album_all_sort_primary%,%albumartistsort%,%_cUnknownArtist%)) $noop( Track Artist Variables - with fallbacks ) $set(_nPTA,$if2(%_artists_track_primary_cred%,%artist%,%_cUnknownArtist%)) $set(_nATA,%_artists_track_additional_cred%) $set(_nFTA,$if2(%_artists_track_all_cred%,%artist%,%_cUnknownArtist%)) $noop( Album and Track Title Variables - with fallbacks ) $set(_nAN,$if2(%album%,%_cUnknownAlbum%)) $set(_nANT,$if2(%album%,%_cUnknownAlbum%)) $set(_nTN,$if2(%title%,%_cNoTitle%)) $set(_nTNT,$if2(%title%,%_cNoTitle%)) $noop( ######################################################################## # # # SECTION 4: WORKING VARIABLES INITIALIZATION # # # ######################################################################## ) $noop( Basic Media and Numbering Variables ) $set(_nMedia,%media%) $set(_nTotalDiscs,$if2(%totaldiscs%,1)) $set(_nDiscNum,$if2(%discnumber%,1)) $set(_nTotalTracks,$if2(%totaltracks%,1)) $set(_nTrackNum,$if2(%tracknumber%,1)) $set(_nAlbumArtistID,$if2(%musicbrainz_albumartistid%,%_kUnKnownArtistID%)) $noop( Create Artist Initial Folder Name - UNUSED VARIABLE ) $noop( Kept for reference only - actual letter folders are created in pathname generation ) $set(_nInitial,~ $upper($firstalphachar(%_nFAAPS%,#)) ~/) $noop( ------------------------------------------------------------------------ Featured Artist Detection Logic If the album artist differs from track artist, show full track artist. Otherwise, show just additional/featured artists. This prevents redundant artist names in filenames. ------------------------------------------------------------------------ ) $set(_tAlbumArtist,$lower($delprefix(%_nPAA%))) $set(_tTrackArtist,$lower($delprefix(%_nPTA%))) $if($eq(%_tAlbumArtist%,%_tTrackArtist%), $set(_nFeat,$if(%_nATA%, [feat. %_nATA%],)), $set(_nFeat, [%_nFTA%]) ) $noop( ------------------------------------------------------------------------ Calculate Automatic Padding for Disc and Track Numbers Ensures consistent sorting by padding to at least the length of the highest disc/track number, or the minimum configured length. ------------------------------------------------------------------------ ) $set(_TotalDiscNumberLength,$len($if2(%totaldiscs%,1))) $set(_TotalTrackNumberLength,$len($if2(%totaltracks%,1))) $set(_DiscPadLength,$if($gt(%_TotalDiscNumberLength%,%_PaddedDiscNumMinLength%),%_TotalDiscNumberLength%,%_PaddedDiscNumMinLength%)) $set(_TrackPadLength,$if($gt(%_TotalTrackNumberLength%,%_PaddedTrackNumMinLength%),%_TotalTrackNumberLength%,%_PaddedTrackNumMinLength%)) $noop( Apply Padding to Disc and Track Numbers ) $set(_PaddedDiscNum,$num($if2(%discnumber%,1),%_DiscPadLength%)) $set(_PaddedTrackNum,$num($if2(%tracknumber%,1),%_TrackPadLength%)) $noop( Extract Year and Format Track Number ) $set(_nYear,[$left($if2(%originaldate%,%originalyear%,%date%,0000),4)]) $set(_nTNum,$if($gt(%_nTotalDiscs%,1),%_PaddedDiscNum%-,)%_PaddedTrackNum%) $noop( ######################################################################## # # # SECTION 5: ALBUM TITLE ENHANCEMENTS # # # # Adds optional metadata to album title based on configuration. # # # ######################################################################## ) $noop( Add Disambiguation Comment if Present and Enabled ) $noop( Example: "Weezer \(Blue Album\)" ) $set(_nDisambig,$if($and(%_releasecomment%,%_aTitleDisambig%), \(%_releasecomment%\),)) $noop( Build Additional Title Info String ) $set(_nTitleExtra,) $noop( Add Record Label if Enabled ) $if(%_aTitleLabel%,$if(%label%, $setmulti(_temp,%label%) $set(_nTitleExtra,$getmulti(%_temp%,0)) ) ) $noop( Add Catalog Number if Enabled ) $if(%_aTitleCatalog%,$if(%catalognumber%, $setmulti(_temp,%catalognumber%) $set(_nTitleExtra,$trim(%_nTitleExtra% $getmulti(%_temp%,0))) ) ) $noop( Add Release Year if Enabled and Different from Original Year ) $if(%_aTitleReleaseYear%,$if(%date%, $set(_temp,$left(%date%,4)) $if($ne([%_temp%],%_nYear%), $if(%_nTitleExtra%,$set(_nTitleExtra,%_nTitleExtra%\,)) $set(_nTitleExtra,$trim(%_nTitleExtra% %_temp%)) ) ) ) $noop( Format Title Extras ) $if(%_nTitleExtra%,$set(_nTitleExtra, [%_nTitleExtra%])) $noop( Combine Album Name with Enhancements ) $set(_nANT,%_nANT%%_nDisambig%%_nTitleExtra%) $noop( ------------------------------------------------------------------------ Trim Long Album and Track Names Prevents excessively long folder/file names that can cause issues on some filesystems or reach path length limits. ------------------------------------------------------------------------ ) $if($gt($len(%_nANT%),%_aTitleMaxLength%),$set(_nANT,$left(%_nANT%,$sub(%_aTitleMaxLength%,3))...)) $if($gt($len(%_nTNT%),%_tTitleMaxLength%),$set(_nTNT,$left(%_nTNT%,$sub(%_tTitleMaxLength%,3))...)) $noop( ######################################################################## # # # SECTION 6: MUSIC TYPE DETECTION # # # # Analyzes MusicBrainz release type tags and sets boolean flags. # # # ######################################################################## ) $noop( Detect Album ) $if($in(%releasetype%,album), $set(_isAlbum,1) ) $noop( Detect Single ) $if($in(%releasetype%,single), $set(_isSingle,1) ) $noop( Detect Live ) $if($in(%releasetype%,live), $set(_isLive,1) ) $noop( Detect EP ) $if($in(%releasetype%,ep), $set(_isEP,1) ) $noop( Detect Broadcast ) $if($in(%releasetype%,broadcast), $set(_isBroadcast,1) ) $noop( Detect Interview ) $if($in(%releasetype%,interview), $set(_isInterview,1) ) $noop( Detect Artist Compilation ) $if($in(%releasetype%,compilation), $set(_isArtistCompil,1) ) $noop( Detect Audiobook ) $if($in(%releasetype%,audiobook), $set(_isAudiobook,1) ) $noop( Detect Other ) $if($in(%releasetype%,other), $set(_isOther,1) ) $noop( Detect Tribute Album - requires custom %coverTributeSort% tag ) $if($in(%coverTributeSort%,Tribute), $set(_isTribute,1) ) $noop( Detect Cover Album - requires custom %coverTributeSort% tag ) $if($in(%coverTributeSort%,Cover), $set(_isCover,1) ) $noop( Detect Podcast ) $if($in(%genre%,Podcast), $set(_isPodcast,1) ) $noop( Detect Soundtrack ) $if($in(%releasetype%,soundtrack), $set(_isSoundTrack,1) ) $noop( Detect Incomplete Album ) $if($not($is_complete()), $set(_isIncomplete,1) ) $noop( Detect Video ) $if($eq($is_video(),0), $set(_isVideo,1) ) $noop( Detect Various Artists ) $if($eq(%albumartist%,Various Artists), $set(_isVarious,1) ) $noop( Detect Global Compilation ) $if($eq(%compilation%,1), $set(_isGlobalCompil,1) ) $noop( If Global Compilation, Override Artist Compilation Flag ) $if($eq(%_isGlobalCompil%,1), $set(_isArtistCompil,0) ) $noop( Get Track Length for Display ) $if($eq(%_showTime%,1), $set(_trackLength,%_length%) ) $noop( ######################################################################## # # # SECTION 7: TAG CLEANUP # # # # Removes placeholder tags that were never filled with real data. # # This prevents default/template values from being written to files. # # # ######################################################################## ) $if($eq(%title%,Title),$delete(title)$delete(titlesort)) $if($eq(%subtitle%,Subtitle),$delete(subtitle)) $if($eq(%discsubtitle%,DiscSubtitle),$delete(discsubtitle)) $if($eq(%artists%,Artist;AdditionalArtists),$delete(artists)) $if($eq(%artistssortorder%,Artist),$delete(artistssortorder)) $if($eq(%album%,Album),$delete(album)$delete(albumsort)$delete(albumartistsort)$delete(albumartist)) $if($eq(%media%,Media),$delete(media)) $if($eq(%label%,Label),$delete(label)) $if($eq(%catalognumber%,Cat#),$delete(catalognumber)) $noop( ######################################################################## # # # SECTION 8: FILENAME VARIABLE SETUP # # # # Creates sanitized versions of metadata for use in file/folder names. # # # ######################################################################## ) $noop( Use sort tags as fallback for filename variables ) $set(_titleForFilename,$if2(%titlesort%,%title%)) $set(_albumForFilename,$if2(%albumsort%,%album%)) $set(_discsubtitleForFilename,%discsubtitle%) $set(_albumartistForFilename,$if2(%albumartist%,%artist%)) $set(_artistForFilename,%artist%) $set(_albumartistsortForFilename,$if2(%albumartistsort%,%artistsort%,%artist%)) $set(_artistsortForFilename,$if2(%artistsort%,%artist%)) $noop( Remove leading "The " from album artist for sorting ) $set(albumartist,$if($eq($left(%albumartist%,4),The ),%albumartistsort%,%albumartist%)) $noop( ######################################################################## # # # SECTION 9: CHARACTER FILTERING & TYPOGRAPHY # # # # Replaces problematic characters for cross-platform compatibility. # # # ######################################################################## ) $noop( ======================================================================== CHARACTER REPLACEMENT TABLE These replacements ensure filenames work on Windows, Linux, macOS, and network shares [Samba/CIFS]. Some are required, others improve readability and consistency. SCOPE LEGEND: [T] = Tags [actual metadata written to file] [F] = Filenames only [file/folder names] ------------------------------------------------------------------------ ORIGINAL REPLACEMENT SCOPE REASON ------------------------------------------------------------------------ ... & [T][F] Ellipsis standardization No. 1 1 [T][F] Remove "No." prefix 12" 12 Inch [T][F] Standardize vinyl notation "text" 'text' [T][F] Windows/Samba compatibility # - [F] Hash not allowed in some contexts : _ [F] Colon not allowed on Windows ? G [F] Question mark removed | è [F] Pipe character replacement > < [removed] [F] Angle brackets removed * 1 [F] Asterisk to "1" & & [F] Ampersand HTML entity ------------------------------------------------------------------------ ) $noop( ======================================================================== TAG-LEVEL Character Replacements \(Written to File Metadata\) ======================================================================== ) $noop( Ellipsis to Ampersand: "Best... Song" → "Best & Song" ) $set(album,$replace(%album%,...,&)) $set(title,$replace(%title%,...,&)) $set(discsubtitle,$replace(%discsubtitle%,...,&)) $noop( Remove "No." Prefix: "No. 1" → "1" ) $set(album,$replace(%album%, [Nn]o.\\s*\(\\d\), \\1)) $set(title,$rreplace(%title%, [Nn]o.\\s*\(\\d\), \\1)) $set(discsubtitle,$replace(%discsubtitle%, [Nn]o.\\s*\(\\d\), \\1)) $noop( Vinyl Inch Standardization: 12" → 12 Inch ) $set(discsubtitle,$rreplace(%discsubtitle%,\(\\d\)",\\1'')) $set(media,$rreplace(%media%,\(\\d\)",\\1 Inch)) $set(album,$rreplace(%album%,\(\\d\)",\\1 Inch)) $set(title,$rreplace(%title%,\(\\d\)",\\1 Inch)) $noop( Double Quotes to Single Quotes: "The "Best"" → "The 'Best'" ) $noop( Required for Samba/CIFS network share compatibility ) $set(albumartist,$rreplace(%albumartist%,"\(.*?\)",'\\1')) $set(artist,$rreplace(%artist%,"\(.*?\)",'\\1')) $set(albumartistsort,$rreplace(%albumartistsort%,"\(.*?\)",'\\1')) $set(artistsort,$rreplace(%artistsort%,"\(.*?\)",'\\1')) $set(album,$rreplace(%album%,"\(.*?\)",'\\1')) $set(title,$rreplace(%title%,"\(.*?\)",'\\1')) $set(discsubtitle,$rreplace(%discsubtitle%,"\(.*?\)",'\\1')) $noop( ======================================================================== FILENAME-LEVEL Character Replacements \(File/Folder Names Only\) ======================================================================== ) $noop( Hash to Hyphen: "Track #1" → "Track -1" ) $set(_titleForFilename,$replace(%_titleForFilename%,#,-)) $set(_albumForFilename,$replace(%_albumForFilename%,#,-)) $set(_discsubtitleForFilename,$replace(%_discsubtitleForFilename%,#,-)) $noop( Time Separator: "5:34" → "5m34" for duration display ) $set(_trackLength,$replace(%_trackLength%,:,m)) $noop( Colon to Underscore: "Title: Subtitle" → "Title_ Subtitle" ) $noop( Required: Windows does not allow colons in filenames ) $set(_titleForFilename,$replace(%_titleForFilename%,:,_)) $set(_albumForFilename,$replace(%_albumForFilename%,:,_)) $set(_discsubtitleForFilename,$replace(%_discsubtitleForFilename%,:,_)) $set(_artistForFilename,$replace(%_artistForFilename%,:,_)) $set(_albumartistForFilename,$replace(%_albumartistForFilename%,:,_)) $set(_artistsortForFilename,$replace(%_artistsortForFilename%,:,_)) $set(_albumartistsortForFilename,$replace(%_albumartistsortForFilename%,:,_)) $noop( Question Mark Removal: "Why?" → "WhyG" ) $set(_titleForFilename,$replace(%_titleForFilename%,?,G)) $set(_albumForFilename,$replace(%_albumForFilename%,?,G)) $set(_discsubtitleForFilename,$replace(%_discsubtitleForFilename%,?,G)) $set(_artistForFilename,$replace(%_artistForFilename%,?,G)) $set(_artistsortForFilename,$replace(%_artistsortForFilename%,?,G)) $noop( Pipe to è: "A|B" → "Aèb" ) $set(_titleForFilename,$replace(%_titleForFilename%,|,è)) $set(_albumForFilename,$replace(%_albumForFilename%,|,è)) $set(_discsubtitleForFilename,$replace(%_discsubtitleForFilename%,|,è)) $noop( Remove Greater-Than: "A>B" → "AB" ) $set(_titleForFilename,$replace(%_titleForFilename%,>,)) $set(_albumForFilename,$replace(%_albumForFilename%,>,)) $set(_discsubtitleForFilename,$replace(%_discsubtitleForFilename%,>,)) $noop( Remove Less-Than: "A