"Copy Tracklist Markup" with MPA

Adds multiple primary artists unlike the original function + button accessible to Contributors

当前为 2025-02-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name "Copy Tracklist Markup" with MPA
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.2
  5. // @description Adds multiple primary artists unlike the original function + button accessible to Contributors
  6. // @author thousandeyes
  7. // @match https://genius.com/albums/*
  8. // @grant none
  9. // @run-at document-end
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14. function getTracklist() {
  15. const artistLink = document.querySelector('a.header_with_cover_art-primary_info-primary_artist');
  16. const albumTitle = document.querySelector('h1.header_with_cover_art-primary_info-title');
  17. const tracks = document.querySelectorAll('album-tracklist-row .chart_row-content');
  18.  
  19. if (!artistLink || !albumTitle || tracks.length === 0) {
  20. console.log('');
  21. return;
  22. }
  23.  
  24. const artistName = artistLink.textContent.trim();
  25. const artistUrl = artistLink.href;
  26. const albumName = albumTitle.textContent.trim();
  27. const albumUrl = window.location.href;
  28.  
  29. let tracklistText = `<b>[${artistName}](${artistUrl}) - [*${albumName}*](${albumUrl}) Lyrics and Tracklist</b>\n\n`;
  30.  
  31. tracks.forEach((trackElement, index) => {
  32. const trackLink = trackElement.querySelector('a');
  33. if (!trackLink) return;
  34.  
  35. let rawTitle = trackLink.textContent.trim().replace(/\s*Lyrics$/, '');
  36. const trackUrl = trackLink.href;
  37.  
  38. let title = rawTitle;
  39. let featuredText = "";
  40.  
  41. const ftPattern = /[\(\s](ft\.?|feat\.?|Ft\.?)[\s\.](.+?)[\)]?$/i;
  42. const ftMatch = title.match(ftPattern);
  43. if (ftMatch) {
  44. featuredText = ftMatch[2].trim();
  45. title = title.replace(ftPattern, '').trim();
  46. }
  47.  
  48. let primaryArtists = [];
  49. const byPattern = /(.+?)\s+by\s+(.+)/i;
  50. const match = title.match(byPattern);
  51. if (match) {
  52. title = match[1].trim();
  53. primaryArtists = match[2]
  54. .split(/,\s*|\s*&\s*/)
  55. .map(artist => `[${artist}](${getArtistUrl(artist)})`);
  56. }
  57.  
  58. let trackText = `${index + 1}. `;
  59. if (primaryArtists.length > 0) {
  60. const joinedPrimary = primaryArtists.length > 2
  61. ? primaryArtists.slice(0, -1).join(', ') + ' & ' + primaryArtists[primaryArtists.length - 1]
  62. : primaryArtists.join(' & ');
  63. trackText += joinedPrimary + ' - ';
  64. }
  65. trackText += `[${title}](${trackUrl})`;
  66.  
  67. let featuredArtistsText = "";
  68. const featuredArtists = trackElement.querySelectorAll('.featured_artists a');
  69. if (featuredArtists.length > 0) {
  70. featuredArtistsText = Array.from(featuredArtists).map(artist => {
  71. const name = artist.textContent.trim();
  72. return `[${name}](${artist.href})`;
  73. }).join(', ');
  74. } else if (featuredText) {
  75. featuredArtistsText = featuredText;
  76. }
  77.  
  78. if (featuredArtistsText) {
  79. trackText += ` ft. ${featuredArtistsText}`;
  80. }
  81.  
  82. tracklistText += `${trackText}\n`;
  83. });
  84.  
  85. navigator.clipboard.writeText(tracklistText)
  86. .then(() => {
  87. const button = document.querySelector('.custom-copy-button');
  88. button.textContent = 'Copied to clipboard';
  89. setTimeout(() => {
  90. button.textContent = 'Copy Tracklist Markup';
  91. }, 2000);
  92. })
  93. .catch(err => console.log('Error: ' + err));
  94. }
  95.  
  96. function getArtistUrl(artistName) {
  97. return `https://genius.com/artists/${encodeURIComponent(artistName.trim().replace(/\s+/g, '-'))}`;
  98. }
  99.  
  100. function createCopyButton() {
  101. const button = document.createElement('div');
  102. button.className = 'square_button u-bottom_margin custom-copy-button';
  103. button.textContent = 'Copy Tracklist Markup';
  104. button.style.cursor = 'pointer';
  105. button.addEventListener('click', getTracklist);
  106.  
  107. const moreButton = document.querySelector('div.square_button.drop-target');
  108. if (moreButton) {
  109. moreButton.parentNode.insertBefore(button, moreButton.nextSibling);
  110. }
  111. }
  112.  
  113. window.addEventListener('load', createCopyButton);
  114. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址