您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds buttons to download Steam Workshop descriptions in .MD and .BBCode format.
// ==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-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 '<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 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 '<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 list const isNewList = line.trim().startsWith('<li>'); // 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 `<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 replacements for (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 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 = '<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 Markdown function 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 BBCode function 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 loads window.addEventListener('load', function () { createGoToRepoButton(); createDownloadButtonMD(); createDownloadButtonBBC(); });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址