Warning: fopen(/www/sites/update.greasyfork.icu/index/store/temp/789829164a188a1be5ae3d4035514ecb.js): failed to open stream: No space left on device in /www/sites/update.greasyfork.icu/index/scriptControl.php on line 65
// ==UserScript== // @name SWDD - Steam Workshop Description Downloader // @namespace https://criskkky.carrd.co/ // @version 1.0.3 // @description Adds buttons to download Steam Workshop descriptions in .MD and .BBCode format. // @description:en Adds buttons to download Steam Workshop descriptions in .MD and .BBCode format. // @description:es Añade botones para descargar descripciones de la Workshop de Steam en formato .MD y .BBCode. // @description:pt Adiciona botões para baixar descrições da Workshop do Steam em formato .MD e .BBCode. // @description:fr Ajoute des boutons pour télécharger les descriptions de la Workshop Steam au format .MD et .BBCode. // @description:it Aggiunge pulsanti per scaricare le descrizioni della Workshop di Steam in formato .MD e .BBCode. // @description:uk Додає кнопки для завантаження описів Workshop Steam у форматі .MD та .BBCode. // @description:ru Добавляет кнопки для загрузки описаний Workshop Steam в формате .MD и .BBCode. // @description:ro Adaugă butoane pentru a descărca descrierile Workshop-ului Steam în format .MD și .BBCode. // @author https://criskkky.carrd.co/ // @supportURL https://github.com/criskkky/SWDD/issues // @homepageURL https://github.com/criskkky/SWDD/ // @icon https://raw.githubusercontent.com/criskkky/SWDD/stable/static/icons/swdd.png // @copyright https://github.com/criskkky/SWDD/tree/stable?tab=readme-ov-file#license // @license https://github.com/criskkky/SWDD/tree/stable?tab=readme-ov-file#license // @grant none // @match https://steamcommunity.com/sharedfiles/filedetails/* // @downloadURL https://update.greasyfork.icu/scripts/483563/SWDD%20-%20Steam%20Workshop%20Description%20Downloader.user.js // @updateURL https://update.greasyfork.icu/scripts/483563/SWDD%20-%20Steam%20Workshop%20Description%20Downloader.meta.js // ==/UserScript== /* I RECOMMEND TAKE A LOOK TO SUPPORTED SYNTAX CONVERSIONS HERE: https://github.com/criskkky/SWDD?tab=readme-ov-file#supported-conversions ANYWAYS, YOU CAN HELP ME TO IMPROVE THIS SCRIPT BY DOING A PULL REQUEST OR OPENING AN ISSUE ON GITHUB :D https://github.com/criskkky/SWDD AVOID USING OFUSCATED CODE OR LIBS, PLEASE, OR YOUR PULL REQUEST WILL BE REJECTED. THANKS! */ // Function to download content as a file function downloadContent(content, fileName) { var blob = new Blob([content], { type: 'text/plain' }); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.click(); } function getDescription() { var descriptionElement = document.querySelector('.workshopItemDescription'); if (descriptionElement) { // Get the HTML content of the description var descriptionHTML = descriptionElement.innerHTML; return descriptionHTML; } return null; } function getHTMLtoBBC(descriptionHTML) { // Custom replacements for Steam HTML to BBCode conversion var bbReplacements = { // Essential '
': '\n', '([\\s\\S]*?)<\/span>': '', '([\\s\\S]*?)<\/span>': '$1', // Headers '
([^<]+)<\/div>': '[h1]$1[/h1]\n', '
([^<]+)<\/div>': '[h2]$1[/h2]\n', '
([^<]+)<\/div>': '[h3]$1[/h3]\n', // Font styling '([\\s\\S]*?)<\/b>': '[b]$1[/b]', '([\\s\\S]*?)<\/u>': '[u]$1[/u]', '([\\s\\S]*?)<\/i>': '[i]$1[/i]', // Font formatting '([\\s\\S]*?)<\/span>': '[strike]$1[/strike]', '([\\s\\S]*?)<\/span>': '[spoiler]$1[/spoiler]', ']*class="bb_link"[^>]*href="([^"]+)"(?:[^>]*target="([^"]+)")?(?:[^>]*rel="([^"]+)")?[^>]*>([\\s\\S]*?)<\/a>': '[url=$1]$4[/url]', // Lists '
    ([\\s\\S]*?)<\/ul>': '\n[list]\n$1\n[/list]', '
  • ([\\s\\S]*?)<\/li>': '[*]$1', '
      ([\\s\\S]*?)<\/ol>': '\n[olist]\n$1\n[/olist]', // Font formatting '
      ([\\s\\S]*?)<\/div>': '\n[code]\n$1[/code]\n', // TODO: Fix noparse. It's not working properly. Do PR if you can fix it. // Tables // TODO: Fix bb_table. It's not working properly. Do PR if you can fix it. '
      ([\\s\\S]*?)<\/div>': '\n[tr]\n$1\n[/tr]\n', '
      ([\\s\\S]*?)<\/div>': '[th]$1[/th]', '
      ([\\s\\S]*?)<\/div>': '[td]$1[/td]', // Images ']*>': '[img]$1[/img]', // Others '
      ': '[hr]', '
      ([\\s\\S]*?)
      ' : '[quote]$1[/quote]', }; // Apply custom replacements for (var pattern in bbReplacements) { var regex = new RegExp(pattern, 'gi'); descriptionHTML = descriptionHTML.replace(regex, bbReplacements[pattern]); } // Clear unsupported tags descriptionHTML = descriptionHTML.replace(/<(?!\/?(h1|h2|h3|b|u|i|strike|spoiler|ul|li|ol|code|tr|th|td|img|hr|blockquote|\/blockquote))[^>]+>/g, ''); var bbcodeContent = descriptionHTML; return bbcodeContent; } function getHTMLtoMD(descriptionHTML) { // Custom replacements for Steam HTML to Markdown conversion var mdReplacements = { // Essential '
      ': '\n', '([\\s\\S]*?)<\/span>': '', '([\\s\\S]*?)<\/span>': '$1', // Headers '
      ([\\s\\S]*?)<\/div>': '# $1\n', '
      ([\\s\\S]*?)<\/div>': '## $1\n', '
      ([\\s\\S]*?)<\/div>': '### $1\n', // Font styling '([\\s\\S]*?)<\/b>': '**$1**', '([\\s\\S]*?)<\/u>': '__$1__', '([\\s\\S]*?)<\/i>': '*$1*', // Font formatting '([\\s\\S]*?)<\/span>': '~~$1~~', '([\\s\\S]*?)<\/span>': '
      Spoiler$1
      ', ']*class="bb_link"[^>]*href="([^"]+)"(?:[^>]*target="([^"]+)")?(?:[^>]*rel="([^"]+)")?[^>]*>([\\s\\S]*?)<\/a>': '[$4]($1)', // Lists '
    1. ([\\s\\S]*?)<\/li>': '* $1', '
        ([\\s\\S]*?)<\/ol>': (match, p1, offset, string) => { const lines = p1.trim().split('\n'); let currentIndex = 1; const formattedLines = lines.map((line, index) => { // Check if the current line starts a new ordered list const isNewList = line.trim().startsWith('
      1. '); // If it's a new list, reset currentIndex to 1 if (isNewList) { currentIndex = 1; } // Replace asterisks (*) or hyphens (-) with incremental numbers return line.replace(/^\s*[\*\-]/, () => { const updatedNumber = currentIndex++; return `${updatedNumber}.`; }); }); return `
          \n${formattedLines.join('\n')}\n
        `; }, // Font formatting '
        ([\\s\\S]*?)<\/div>': '\n```\n$1\n```\n', // TODO: Fix noparse. It's not working properly. Do PR if you can fix it. // Tables // TODO: Fix bb_table. It's not working properly. Do PR if you can fix it. // TODO: Fix bb_table_tr. It's not working properly. Do PR if you can fix it. // TODO: Fix bb_table_th. It's not working properly. Do PR if you can fix it. // TODO: Fix bb_table_td. It's not working properly. Do PR if you can fix it. // Images ']*>': '![image]($1)', // Others '
        ': '---', '
        ([\\s\\S]*?)
        ' : '> $1', }; // Apply custom replacements for (var pattern in mdReplacements) { var regex = new RegExp(pattern, 'gi'); descriptionHTML = descriptionHTML.replace(regex, mdReplacements[pattern]); } // Clear unsupported tags except for
        Spoiler$1
        descriptionHTML = descriptionHTML.replace(/<(?!details>Spoiler<\/summary>\$1<\/details>)[^>]+>/g, ''); var markdownContent = descriptionHTML; return markdownContent; } function insertButton(downloadButton) { var fixedMargin = document.querySelector('.game_area_purchase_margin'); if (fixedMargin) { // Better alignment ... fixedMargin.style.marginBottom = 'auto'; // Find the element after which the button should be inserted var targetElement = document.querySelector('.workshopItemDescription'); if (targetElement) { // Insert the button after the target element targetElement.parentNode.insertBefore(downloadButton, targetElement.nextSibling); } } } // Create go to repo button function createGoToRepoButton() { var goToRepoButton = document.createElement('a'); goToRepoButton.innerHTML = 'Repository'; goToRepoButton.classList.add('btn_darkblue_white_innerfade', 'btn_border_2px', 'btn_medium'); goToRepoButton.style.marginBottom = '5px'; goToRepoButton.style.marginRight = '5px'; goToRepoButton.style.padding = '5px 10px'; goToRepoButton.style.height = '21px'; goToRepoButton.style.fontSize = '14px'; goToRepoButton.href = 'https://github.com/criskkky/SWDD'; goToRepoButton.target = '_blank'; insertButton(goToRepoButton); } // Create the download button for Markdown function createDownloadButtonMD() { var downloadButton = document.createElement('button'); downloadButton.innerHTML = 'Download .MD'; downloadButton.classList.add('btn_green_white_innerfade', 'btn_border_2px', 'btn_medium'); downloadButton.style.marginBottom = '5px'; downloadButton.style.marginRight = '5px'; downloadButton.style.padding = '5px 10px'; downloadButton.style.height = '34.43px'; downloadButton.style.fontSize = '14px'; downloadButton.addEventListener('click', function () { var markdownContent = getHTMLtoMD(getDescription()); if (markdownContent) { downloadContent(markdownContent, 'WorkshopDownload.md'); } else { alert('No content found in Markdown format.'); } }); insertButton(downloadButton); } // Create the download button for BBCode function createDownloadButtonBBC() { var downloadButton = document.createElement('button'); downloadButton.innerHTML = 'Download .BBCode'; downloadButton.classList.add('btn_green_white_innerfade', 'btn_border_2px', 'btn_medium'); downloadButton.style.marginBottom = '5px'; downloadButton.style.marginRight = '5px'; downloadButton.style.padding = '5px 10px'; downloadButton.style.height = '34.43px'; downloadButton.style.fontSize = '14px'; downloadButton.addEventListener('click', function () { var bbcodeContent = getHTMLtoBBC(getDescription()); if (bbcodeContent) { downloadContent(bbcodeContent, 'WorkshopDownload.bbcode'); } else { alert('No content found in BBCode format.'); } }); insertButton(downloadButton); } // Execute the functions when the page loads window.addEventListener('load', function () { createGoToRepoButton(); createDownloadButtonMD(); createDownloadButtonBBC(); });