SHOW:
|
|
- or go back to the newest paste.
| 1 | javascript:(function() {
| |
| 2 | - | console.log('[Reddit BBCode Tool] Activated - Click copy buttons on posts/comments');
|
| 2 | + | var textareas = document.querySelectorAll('textarea.input');
|
| 3 | - | const USE_DATA_URL_FOR_IMAGES = false; |
| 3 | + | textareas.forEach(function(textarea) {
|
| 4 | var text = textarea.value; | |
| 5 | - | function htmlToBBCode(html) {
|
| 5 | + | |
| 6 | - | const textarea = document.createElement('textarea');
|
| 6 | + | |
| 7 | - | textarea.innerHTML = html; |
| 7 | + | var pattern1 = /$$\s*URL=(.*?)\s*\$\$(.*?)\s*\/\s*URL\s*$$/gi; |
| 8 | - | const decoded = textarea.value; |
| 8 | + | var pattern2 = /$$\s*URL\s*\$\$(.*?)\s*\/\s*URL\s*$$/gi; |
| 9 | - | return decoded |
| 9 | + | replacedText = text.replace(pattern1, '[U][URL=$1]$2[/URL][/U]'); |
| 10 | - | .replace(/<h1>([\s\S]+?)<\/h1>/g, '[HEADING=1][b]$1[/b][/HEADING]\n\n') |
| 10 | + | replacedText = replacedText.replace(pattern2, '[U][URL]$1[/URL][/U]'); |
| 11 | - | .replace(/<h2>([\s\S]+?)<\/h2>/g, '[HEADING=2][b]$1[/b][/HEADING]\n\n') |
| 11 | + | replacedText = replacedText.replace(/$$U$$\$\$U\$\$URL=(.*?)\/URL\$\$\/U\$\$\/U$$/g, '[U][URL=$1[/URL][/U]'); |
| 12 | - | .replace(/<h3>([\s\S]+?)<\/h3>/g, '[HEADING=3][b]$1[/b][/HEADING]\n\n') |
| 12 | + | |
| 13 | - | .replace(/<a href="([^"]+)"[^>]*>([\s\S]+?)<\/a>/g, (m, url, text) => {
|
| 13 | + | |
| 14 | - | const cleanUrl = url.replace(/&/g, '&'); |
| 14 | + | var existingUrlPattern = /(?<!\[U\])\[URL=(.*?)\](.*?)\[\/URL\](?!\[\/U\])/gi; |
| 15 | - | const cleanText = text.replace(/<(?!\/?(?:b|i|s|u)\b)[^>]*>/gi, ''); |
| 15 | + | replacedText = replacedText.replace(existingUrlPattern, '[U][URL=$1]$2[/URL][/U]'); |
| 16 | - | return `[u][url='${cleanUrl}']${cleanText}[/url][/u]`;
|
| 16 | + | |
| 17 | - | }) |
| 17 | + | var existingUrlSimplePattern = /(?<!\[U\])\[URL\](.*?)\[\/URL\](?!\[\/U\])/gi; |
| 18 | - | .replace(/<img src="([^"]+)"[^>]*>/g, '[img]$1[/img]') |
| 18 | + | replacedText = replacedText.replace(existingUrlSimplePattern, '[U][URL]$1[/URL][/U]'); |
| 19 | - | .replace(/<(b|strong)>([^<]+)<\/(b|strong)>/g, '[b]$2[/b]') |
| 19 | + | |
| 20 | - | .replace(/<(i|em)>([^<]+)<\/(i|em)>/g, '[i]$2[/i]') |
| 20 | + | var pattern3 = /(\n)([A-Z"]|\d|$$B$$|$$I$$|$$IMG$$)/g; |
| 21 | - | .replace(/<s>([^<]+)<\/s>/g, '[s]$1[/s]') |
| 21 | + | var pattern6 = /($$HEADING=2$$|$$LIST$$|$$\*$$|$$\/LIST$$|$$IMG$$)/g; |
| 22 | - | .replace(/<blockquote>([\s\S]+?)<\/blockquote>/g, '[quote]$1[/quote]') |
| 22 | + | replacedText = replacedText.replace(pattern6, '\n$1'); |
| 23 | - | .replace(/<pre>([\s\S]+?)<\/pre>/g, '[code]$1[/code]') |
| 23 | + | replacedText = replacedText.replace(/$$\/HEADING$$\n/g, '[/HEADING]\n'); |
| 24 | - | .replace(/<code>([^<]+)<\/code>/g, '[icode]$1[/icode]') |
| 24 | + | replacedText = replacedText.replace(/$$\/IMG$$\n/g, '[/IMG]\n'); |
| 25 | - | .replace(/<ol>([\s\S]+?)<\/ol>/g, (match, listContent) => '[LIST=1]\n' + listContent.replace(/<li>([\s\S]+?)<\/li>/g, '[*] $1\n') + '[/LIST]') |
| 25 | + | replacedText = replacedText.replace(/\[\/LIST\]/g, '[/LIST]\n'); |
| 26 | - | .replace(/<ul>([\s\S]+?)<\/ul>/g, (match, listContent) => '[LIST]\n' + listContent.replace(/<li>([\s\S]+?)<\/li>/g, '[*] $1\n') + '[/LIST]') |
| 26 | + | |
| 27 | - | .replace(/<\/p>|<\s*br\s*\/?>/gi, '\n') |
| 27 | + | var pattern4 = /$$IMG alt="([^"]*)"/g; |
| 28 | - | .replace(/<\/?[^>]+>/g, '') |
| 28 | + | var pattern9 = /\$\$\/IMG$$([A-Za-z0-9])/g; |
| 29 | - | .replace(/&/g, '&') |
| 29 | + | replacedText = replacedText.replace(pattern4, '\n[IMG alt="$1"] '); |
| 30 | - | .replace(/\n{3,}/g, '\n\n')
|
| 30 | + | replacedText = replacedText.replace(pattern9, '[/IMG] $1'); |
| 31 | - | .replace(/^\s+|\s+$/g, ''); |
| 31 | + | |
| 32 | - | } |
| 32 | + | var pattern5 = /\n/g; |
| 33 | var pattern10 = /^\n+|\n{2,}|\n+$/g;
| |
| 34 | - | function extractTextWithLinks(html) {
|
| 34 | + | replacedText = replacedText.replace(pattern5, '\n'); |
| 35 | - | const parser = new DOMParser(); |
| 35 | + | replacedText = replacedText.replace(pattern10, '\n'); |
| 36 | - | const doc = parser.parseFromString(html, 'text/html'); |
| 36 | + | |
| 37 | - | let text = doc.body.innerText.trim(); |
| 37 | + | var pattern7 = /$$\/?FONT(=.*?)?$$/g; |
| 38 | - | const links = Array.from(doc.body.querySelectorAll('a'));
|
| 38 | + | var pattern8 = /$$\/?COLOR(=.*?)?$$/g; |
| 39 | - | const images = Array.from(doc.body.querySelectorAll('img'));
|
| 39 | + | replacedText = replacedText.replace(pattern7, ''); |
| 40 | - | let reconstructedText = text; |
| 40 | + | replacedText = replacedText.replace(pattern8, ''); |
| 41 | - | links.forEach(link => {
|
| 41 | + | |
| 42 | - | const linkText = link.textContent.trim(); |
| 42 | + | replacedText = replacedText.replace(/\$\$B\$\$(.*?)\$\$\/B\$\$/g, '[B]$1[/B]'); |
| 43 | - | const linkUrl = link.href; |
| 43 | + | replacedText = replacedText.replace(/\$\$I\$\$(.*?)\$\$\/I\$\$/g, '[I]$1[/I]'); |
| 44 | - | reconstructedText = reconstructedText.replace(linkText, `[u][url]${linkUrl}[/url][/u]`);
|
| 44 | + | |
| 45 | - | }); |
| 45 | + | var mathPattern = /\$\$(.*?)\$\$/g; |
| 46 | - | images.forEach(image => {
|
| 46 | + | replacedText = replacedText.replace(mathPattern, '\$$$1\$$'); |
| 47 | - | let src = image.src; |
| 47 | + | |
| 48 | - | if (USE_DATA_URL_FOR_IMAGES) {
|
| 48 | + | var paragraphPattern = /([^\n])\n([A-Z0-9])/g; |
| 49 | - | src = image.getAttribute('data-url') || src.replace(/preview\\.redd\\.it/, 'i.redd.it');
|
| 49 | + | replacedText = replacedText.replace(paragraphPattern, '$1\n\n$2'); |
| 50 | - | } |
| 50 | + | |
| 51 | - | reconstructedText += `\n[img]${src}[/img]`;
|
| 51 | + | var quotePattern = /$$QUOTE$$(?:.*?\n)*?(.*?)$$\/QUOTE$$/gs; |
| 52 | - | }); |
| 52 | + | replacedText = replacedText.replace(quotePattern, '[QUOTE][SIZE=4]$1[/SIZE][/QUOTE]'); |
| 53 | - | return reconstructedText.trim(); |
| 53 | + | |
| 54 | - | } |
| 54 | + | const emptyListItemsPattern = /\[LIST\](\n\[\*\]\s*)+\[\/LIST\]/gi; |
| 55 | replacedText = replacedText.replace(emptyListItemsPattern, ''); | |
| 56 | - | function extractPostUrl(element) {
|
| 56 | + | const emptyListBlockPattern = /\[LIST\]\s*\[\/LIST\]/gi; |
| 57 | - | return element.querySelector('a.bylink[href*="/comments/"]')?.href || element.querySelector('a.title[href*="/comments/"]')?.href || (element.hasAttribute('data-permalink') ? `https://www.reddit.com${element.getAttribute('data-permalink')}` : window.location.href);
|
| 57 | + | replacedText = replacedText.replace(emptyListBlockPattern, ''); |
| 58 | - | } |
| 58 | + | |
| 59 | replacedText = replacedText.replace(/\[B\]\[\/B\]/g, ''); | |
| 60 | - | function getParentComments(commentElement, maxDepth = 10) {
|
| 60 | + | replacedText = replacedText.replace(/\[I\]\[\/I\]/g, ''); |
| 61 | - | const parents = []; |
| 61 | + | |
| 62 | - | const seenIds = new Set(); |
| 62 | + | textarea.value = replacedText; |
| 63 | - | let currentComment = commentElement.closest('.thing.comment, shreddit-comment');
|
| 63 | + | }); |
| 64 | })(); |