您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
选择指定标签并复制到剪贴板,供Stable Diffusion WebUI或NovelAI等使用
// ==UserScript== // @name Danbooru Tags Select to Export // @name:zh-TW Danbooru 標籤導出器 // @name:zh-HK Danbooru 標籤導出器 // @name:zh-CN Danbooru 标签导出器 // @name:ja Danbooru Tags Select to Export // @namespace https://github.com/FSpark/Danbooru-Tags-Exporter // @supportURL https://github.com/FSpark/Danbooru-Tags-Exporter/issues // @homepageURL https://github.com/FSpark/Danbooru-Tags-Exporter // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js // @version 0.3.4 // @description Select specified tags and copy to clipboard, for Stable Diffusion WebUI or NovelAI to use. // @description:zh-TW 選擇指定標籤並複製到剪貼板,供Stable Diffusion WebUI或NovelAI等使用 // @description:zh-HK 選擇指定標籤並複製到剪貼板,供Stable Diffusion WebUI或NovelAI等使用 // @description:zh-CN 选择指定标签并复制到剪贴板,供Stable Diffusion WebUI或NovelAI等使用 // @description:ja 指定したタグを選択し、クリップボードにコピーして、Stable Diffusion WebUIやNovelAIなどで使用することができます。 // @author FSpark // @match https://danbooru.donmai.us/posts/* // @match https://safebooru.donmai.us/posts/* // @match https://aibooru.online/posts/* // @match https://betabooru.donmai.us/posts/* // @match https://gelbooru.com/index.php?page=post&s=view&id=* // @icon https://www.google.com/s2/favicons?sz=64&domain=donmai.us // @grant GM.setClipboard // @grant GM.notification // @grant GM.addStyle // @license AGPL-3.0 // ==/UserScript== (function () { 'use strict'; if(location.host == "gelbooru.com"){ GM_addStyle(`#tags-exporter-setting h2{ font-size:1.2em} #tags-exporter-setting { margin: 0px 10px 0px 10px; } #tags-exporter-container button, #tag-list button {padding: 0.1em 0.3em; margin-bottom:0.1em} #tags-exporter-container { margin: 0px 10px 0px 10px; } ul.tag-list li{margin: 2px 0 } #tags-exporter-setting label{margin: .25em; line-height: 1.5em;} .tag-weight {width: 3em; margin-left: .25em}`); }else{ GM_addStyle(`#tags-exporter-setting button, #tag-list button {padding: 0.25em 0.75em;} #tags-exporter-setting label{margin: .25em; line-height: 1.5em;} .tag-weight {width: 3em; margin-left: .25em}`); } let SettingPanel = document.createElement('section'); SettingPanel.id = "tags-exporter-setting"; SettingPanel.innerHTML = ` <h2>Tags Export Settings</h2> <input type="checkbox" id="bracket-escape" checked/><label for="bracket-escape"><code>(</code> <code>)</code> -> <code>\\(</code> <code>\\)</code></label><br> <input type="checkbox" id="set-weight" /><label for="set-weight">Setting weights</label><br> <div> <input type="radio" name="use-bracket" id="round-brackets" value="0" checked/><label for="round-brackets">Using ( )</label> <input type="radio" name="use-bracket" id="curly-brackets" value="-1"/><label for="curly-brackets">Using { }</label></div> ` let Container = document.createElement('div'); Container.id = "tags-exporter-container"; Container.innerHTML = `<button name="select_all">All</button> <button name="select_none">None</button> <button name="invert_select">Invert</button> <button name="export">Export</button> ` function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } function insertBefore(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode); } if(location.host == "gelbooru.com"){ insertBefore(SettingPanel, document.querySelector(".aside>.tag-list")) insertBefore(Container, document.querySelector(".aside>.tag-list")) }else{ insertAfter(SettingPanel, document.querySelector("#search-box")) insertAfter(Container, document.querySelector("#tags-exporter-setting > h2")) } function addBrackets(prompts,isRound,n){ let l,r; if(n==0) return prompts else if(n>0){ if(isRound){ l='(' r=')'} else{ l='{' r='}' } }else{ l='[' r=']' } n=Math.abs(n) return l.repeat(n).concat(prompts,r.repeat(n)) } function exportTags(target){ let tags = [] let bracket_escape = document.getElementById("bracket-escape").checked let set_weight = document.getElementById("set-weight").checked let round_brackets = document.getElementById("round-brackets").checked document.querySelectorAll(target).forEach((e) => { let prompts = e.value if(bracket_escape) prompts = prompts.replaceAll(`(`,`\\(`).replaceAll(`)`,`\\)`) if(set_weight){ prompts = addBrackets(prompts,round_brackets,e.nextSibling.value) } tags.push(prompts) }) let res = tags.join(", ") GM.setClipboard(res) GM.notification(`${tags.length} tag(s) were copied.`, "Danbooru Tags Exporter") } function insertButtons(target){ let head = document.querySelector(`h3.${target}-list`) if(!head) return; let buttonContainer = Container.cloneNode(true) buttonContainer.id = `${target}-buttons` insertAfter(buttonContainer, head) document.querySelectorAll(`.${target}-list>li`).forEach((e) => { let chk = document.createElement('input'); chk.type = "checkbox" chk.name = `${target}s` chk.value = e.dataset.tagName.replaceAll("_", " ") e.insertBefore(chk, e.firstChild) let nbr = document.createElement('input'); nbr.type = "number" nbr.name = `${target}s-weight` nbr.className = "tag-weight" nbr.value = 0 nbr.hidden = true insertAfter(nbr,chk) }) buttonContainer.querySelector("[name='select_all']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked = true; } }; buttonContainer.querySelector("[name='select_none']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked = false; } }; buttonContainer.querySelector("[name='invert_select']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked == true ? items[i].checked = false : items[i].checked = true; } }; buttonContainer.querySelector("[name='export']").onclick = function () { exportTags(`[name=${target}s]:checked`) }; } function insertButtonsGelbooru(target){ let head = document.querySelector(`.${target}`) if(!head) return; head = head.previousSibling; let buttonContainer = Container.cloneNode(true) buttonContainer.id = `${target}-buttons` insertAfter(buttonContainer, head) document.querySelectorAll(`.${target}`).forEach((e) => { let chk = document.createElement('input'); chk.type = "checkbox" chk.name = `${target}s` chk.value = e.querySelector(':scope>a').innerText; e.insertBefore(chk, e.firstChild) let nbr = document.createElement('input'); nbr.type = "number" nbr.name = `${target}s-weight` nbr.className = "tag-weight" nbr.value = 0 nbr.hidden = true insertAfter(nbr,chk) }) buttonContainer.querySelector("[name='select_all']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked = true; } }; buttonContainer.querySelector("[name='select_none']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked = false; } }; buttonContainer.querySelector("[name='invert_select']").onclick = function () { var items = document.getElementsByName(`${target}s`); for (var i = 0; i < items.length; i++) { items[i].checked == true ? items[i].checked = false : items[i].checked = true; } }; buttonContainer.querySelector("[name='export']").onclick = function () { exportTags(`[name=${target}s]:checked`) }; } ["artist-tag","character-tag","copyright-tag","general-tag"].forEach((t)=>insertButtons(t)); ["tag-type-artist","tag-type-character","tag-type-copyright","tag-type-metadata","tag-type-general"].forEach((t)=>insertButtonsGelbooru(t)); Container.querySelector("[name='select_all']").onclick = function () { var items = document.querySelectorAll("#tag-list input[type='checkbox']") for (var i = 0; i < items.length; i++) { items[i].checked = true; } }; Container.querySelector("[name='select_none']").onclick = function () { var items = document.querySelectorAll("#tag-list input[type='checkbox']") for (var i = 0; i < items.length; i++) { items[i].checked = false; } }; Container.querySelector("[name='invert_select']").onclick = function () { var items = document.querySelectorAll("#tag-list input[type='checkbox']") for (var i = 0; i < items.length; i++) { items[i].checked == true ? items[i].checked = false : items[i].checked = true; } }; Container.querySelector("[name='export']").onclick = function () { exportTags(`#tag-list input[type='checkbox']:checked`) }; document.getElementById("set-weight").onchange = function (e){ if(e.target.checked){ document.querySelectorAll("#tag-list input[type='number']").forEach((e)=>e.hidden=false) }else{ document.querySelectorAll("#tag-list input[type='number']").forEach((e)=>e.hidden=true) } } })();