// ==UserScript== // @name YuQue (UC) Table Transformer // @namespace http://tampermonkey.net/ // @version 1.1 // @description try to take over the world! // @author You // @match https://www.yuque.com/siyou-lmowq/* // @grant GM_setClipboard // ==/UserScript== (function() { 'use strict'; const regexpGeneric = /^(?:List|Set)<([^>]+)>$/i const convertType = (type) => { let isList = false if (type.endsWith('[]')) { isList = true type = type.substring(0, type.length - 2) } else if (regexpGeneric.test(type)) { isList = true type = regexpGeneric.exec(type)[1] } switch (type.toLowerCase()) { case 'long': case 'float': case 'double': case 'int': case 'integer': type = 'number'; break case 'boolean': type = 'boolean'; break case 'string': type = 'string'; break } if (isList) type += '[]' return type } const parseRow = (row) => { const tds = row.querySelectorAll('td') if (tds.length < 3) return '' const name = tds[0].innerText.trim() if (!name) return '' const type = tds[1].innerText.trim() const comment = tds[2].innerText.trim() return ` ${name.replace(/\n/g, '')}: ${convertType(type)} // ${comment.replace(/\n/g, ' ')}\n` } const parseRows = (header, rows) => { if (!rows.length) return let content = `interface ${header} {\n` rows.forEach(row => { content += parseRow(row) }) content += '}' GM_setClipboard(content) return content } const parseTable = (tableDiv, header) => { const result = document.createElement('pre') result.append(document.createTextNode(parseRows(header, tableDiv.querySelectorAll('tr:nth-child(n+2)')))) tableDiv.prepend(result) } const createButton = (container, header) => { container.dataset.dump = true container.style.position = 'relative' const btn = document.createElement('button') btn.append(document.createTextNode('Dump')) btn.addEventListener('click', () => { parseTable(container, header) btn.remove() }) btn.style.position = 'absolute' btn.style.top = '0' btn.style.right = '-2em' btn.style.zIndex = 10000 container.prepend(btn) } const searchHeader = (element, tagName) => { do { element = element?.previousElementSibling if (element?.tagName === tagName) return element } while (element?.tagName) } const ob = new MutationObserver(mutations => { mutations.forEach(({ target }) => { if (target?.tagName === 'NE-TABLE-HOLE' && !target?.dataset?.dump) { setTimeout(() => { const header = searchHeader(target, 'NE-H3')?.innerText?.trim() if (header) createButton(target, header) }, 1000) } }) }) ob.observe(document.body, { subtree: true, childList: true }) })();