Greasy Fork is available in English.
Ajoute des boutons pour télécharger les descriptions de la Workshop Steam au format .MD et .BBCode.
- // ==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/*// ==/UserScript==/*I RECOMMEND TAKE A LOOK TO SUPPORTED SYNTAX CONVERSIONS HERE:https://github.com/criskkky/SWDD?tab=readme-ov-file#supported-conversionsANYWAYS, YOU CAN HELP ME TO IMPROVE THIS SCRIPTBY DOING A PULL REQUEST OR OPENING AN ISSUE ON GITHUB :Dhttps://github.com/criskkky/SWDDAVOID USING OFUSCATED CODE OR LIBS, PLEASE,OR YOUR PULL REQUEST WILL BE REJECTED. THANKS!*/// Function to download content as a filefunction 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 descriptionvar descriptionHTML = descriptionElement.innerHTML;return descriptionHTML;}return null;}function getHTMLtoBBC(descriptionHTML) {// Custom replacements for Steam HTML to BBCode conversionvar bbReplacements = {// Essential'<br>': '\n','<span class="bb_link_host">([\\s\\S]*?)<\/span>': '','<span>([\\s\\S]*?)<\/span>': '$1',// Headers'<div class="bb_h1">([^<]+)<\/div>': '[h1]$1[/h1]\n','<div class="bb_h2">([^<]+)<\/div>': '[h2]$1[/h2]\n','<div class="bb_h3">([^<]+)<\/div>': '[h3]$1[/h3]\n',// Font styling'<b>([\\s\\S]*?)<\/b>': '[b]$1[/b]','<u>([\\s\\S]*?)<\/u>': '[u]$1[/u]','<i>([\\s\\S]*?)<\/i>': '[i]$1[/i]',// Font formatting'<span class="bb_strike">([\\s\\S]*?)<\/span>': '[strike]$1[/strike]','<span class="bb_spoiler">([\\s\\S]*?)<\/span>': '[spoiler]$1[/spoiler]','<a[^>]*class="bb_link"[^>]*href="([^"]+)"(?:[^>]*target="([^"]+)")?(?:[^>]*rel="([^"]+)")?[^>]*>([\\s\\S]*?)<\/a>': '[url=$1]$4[/url]',// Lists'<ul class="bb_ul">([\\s\\S]*?)<\/ul>': '\n[list]\n$1\n[/list]','<li>([\\s\\S]*?)<\/li>': '[*]$1','<ol>([\\s\\S]*?)<\/ol>': '\n[olist]\n$1\n[/olist]',// Font formatting'<div class="bb_code">([\\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.'<div class="bb_table_tr">([\\s\\S]*?)<\/div>': '\n[tr]\n$1\n[/tr]\n','<div class="bb_table_th">([\\s\\S]*?)<\/div>': '[th]$1[/th]','<div class="bb_table_td">([\\s\\S]*?)<\/div>': '[td]$1[/td]',// Images'<img src="([^"]+)"[^>]*>': '[img]$1[/img]',// Others'<hr>': '[hr]','<blockquote class="bb_blockquote">([\\s\\S]*?)</blockquote>' : '[quote]$1[/quote]',};// Apply custom replacementsfor (var pattern in bbReplacements) {var regex = new RegExp(pattern, 'gi');descriptionHTML = descriptionHTML.replace(regex, bbReplacements[pattern]);}// Clear unsupported tagsdescriptionHTML = 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 conversionvar mdReplacements = {// Essential'<br>': '\n','<span class="bb_link_host">([\\s\\S]*?)<\/span>': '','<span>([\\s\\S]*?)<\/span>': '$1',// Headers'<div class="bb_h1">([\\s\\S]*?)<\/div>': '# $1\n','<div class="bb_h2">([\\s\\S]*?)<\/div>': '## $1\n','<div class="bb_h3">([\\s\\S]*?)<\/div>': '### $1\n',// Font styling'<b>([\\s\\S]*?)<\/b>': '**$1**','<u>([\\s\\S]*?)<\/u>': '__$1__','<i>([\\s\\S]*?)<\/i>': '*$1*',// Font formatting'<span class="bb_strike">([\\s\\S]*?)<\/span>': '~~$1~~','<span class="bb_spoiler">([\\s\\S]*?)<\/span>': '<details><summary>Spoiler</summary>$1</details>','<a[^>]*class="bb_link"[^>]*href="([^"]+)"(?:[^>]*target="([^"]+)")?(?:[^>]*rel="([^"]+)")?[^>]*>([\\s\\S]*?)<\/a>': '[$4]($1)',// Lists'<li>([\\s\\S]*?)<\/li>': '* $1','<ol>([\\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 listconst isNewList = line.trim().startsWith('<li>');// If it's a new list, reset currentIndex to 1if (isNewList) {currentIndex = 1;}// Replace asterisks (*) or hyphens (-) with incremental numbersreturn line.replace(/^\s*[\*\-]/, () => {const updatedNumber = currentIndex++;return `${updatedNumber}.`;});});return `<ol>\n${formattedLines.join('\n')}\n</ol>`;},// Font formatting'<div class="bb_code">([\\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'<img src="([^"]+)"[^>]*>': '',// Others'<hr>': '---','<blockquote class="bb_blockquote">([\\s\\S]*?)</blockquote>' : '> $1',};// Apply custom replacementsfor (var pattern in mdReplacements) {var regex = new RegExp(pattern, 'gi');descriptionHTML = descriptionHTML.replace(regex, mdReplacements[pattern]);}// Clear unsupported tags except for <details><summary>Spoiler</summary>$1</details>descriptionHTML = descriptionHTML.replace(/<(?!details><summary>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 insertedvar targetElement = document.querySelector('.workshopItemDescription');if (targetElement) {// Insert the button after the target elementtargetElement.parentNode.insertBefore(downloadButton, targetElement.nextSibling);}}}// Create go to repo buttonfunction createGoToRepoButton() {var goToRepoButton = document.createElement('a');goToRepoButton.innerHTML = '<img src="https://raw.githubusercontent.com/criskkky/SWDD/stable/static/icons/github_line.png" style="vertical-align: middle; margin-right: 5px; margin-left: -4px; max-width: 20px; max-height: 20px;">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 Markdownfunction createDownloadButtonMD() {var downloadButton = document.createElement('button');downloadButton.innerHTML = '<img src="https://raw.githubusercontent.com/criskkky/SWDD/adb175e273c563b3ffad4e81e7afe7f76449fd04/static/icons/cloud-download-white.svg" style="vertical-align: middle; margin-right: 5px; margin-left: -6px; max-width: 20px; max-height: 20px;">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 BBCodefunction createDownloadButtonBBC() {var downloadButton = document.createElement('button');downloadButton.innerHTML = '<img src="https://raw.githubusercontent.com/criskkky/SWDD/adb175e273c563b3ffad4e81e7afe7f76449fd04/static/icons/cloud-download-white.svg" style="vertical-align: middle; margin-right: 5px; margin-left: -6px; max-width: 20px; max-height: 20px;">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 loadswindow.addEventListener('load', function () {createGoToRepoButton();createDownloadButtonMD();createDownloadButtonBBC();});