optimization
parent
a3f9c96cd4
commit
bed7a348d4
|
|
@ -29,13 +29,10 @@ Sometimes, when you type too fast or copy prompts from all over the places, you
|
|||
- [x] Pressing `Alt` + `Shift` + `F` can also trigger formatting
|
||||
- [x] Assign "[alias](#tag-alias)" that counts as duplicates for the specified tags
|
||||
- [x] Exclude specific tags from `Remove Underscores`
|
||||
- [x] Click `Reload Cached Cards & Alias` to force a reload
|
||||
- By default, the `ExtraNetwork` cards are cached once at the start, to be excluded from `Remove Underscores`. If you add more cards while the Webui is still running, you may click this to re-cache again.
|
||||
- [x] Click `Reload` to cache new cards
|
||||
- By default, the `ExtraNetwork` cards are cached once at the start, to be excluded from `Remove Underscores`. If you added more cards while the Webui is already running, click this button to re-cache again.
|
||||
|
||||
### Tag Alias
|
||||
|
||||
<p align="right"><i><b>New</b> 🔥</i></p>
|
||||
|
||||
- In the `Prompt Format` settings, there is a new field for **Tag Alias**
|
||||
- You can assign other tags that count as the same as the main tag, and thus get removed during `Remove Duplicates`
|
||||
- The syntax is in the format of `main tag: alias1, alias2, alias3`
|
||||
|
|
|
|||
|
|
@ -29,13 +29,10 @@
|
|||
- [x] 按下 `Alt` + `Shift` + `F` 亦可觸發格式化
|
||||
- [x] 為指定單字新增 "[同義詞](#同義詞)"
|
||||
- [x] 將指定字詞除外 `Remove Underscores` 的影響
|
||||
- [x] 點擊 `Reload Cached Cards & Alias` 以重新載入
|
||||
- 在一開始, `ExtraNetwork` 中的卡片會被緩存一次以防被 `Remove Underscores` 影響。如果你在 Webui 仍在運行時加入更多的卡片,點擊此按鈕來重新緩存。
|
||||
- [x] 點擊 `Reload` 以緩存卡片
|
||||
- 在 Webui 剛開啟時, `ExtraNetwork` 中的卡片會被緩存一次以防被 `Remove Underscores` 影響。如果你在 Webui 已運行時加入更多的卡片,點擊此按鈕來重新緩存。
|
||||
|
||||
### 同義詞
|
||||
|
||||
<p align="right"><i><b>新功能</b> 🔥</i></p>
|
||||
|
||||
- 在 `Prompt Format` 的設定裡,有個新的 **Tag Alias** 欄位
|
||||
- 你可以在此把其它字詞設為主單字的同義詞,使其在 `Remove Duplicates` 中被當作重複字而刪去
|
||||
- 格式為 `main tag: alias1, alias2, alias3`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
class LeFormatterConfig {
|
||||
class pfConfigs {
|
||||
|
||||
constructor() {
|
||||
this.refresh = this.#shouldRefresh();
|
||||
|
|
@ -7,7 +7,6 @@ class LeFormatterConfig {
|
|||
this.removeUnderscore = this.#defaultRemoveUnderscore();
|
||||
this.comma = this.#appendComma();
|
||||
this.promptFields = this.#getPromptFields();
|
||||
this.button = this.#createReloadButton();
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
|
|
@ -40,56 +39,47 @@ class LeFormatterConfig {
|
|||
return config.checked;
|
||||
}
|
||||
|
||||
// ===== Cache All Prompt Fields =====
|
||||
/** @returns {HTMLTextAreaElement[]} */
|
||||
/**
|
||||
* Cache All Prompt Fields
|
||||
* @returns {HTMLTextAreaElement[]}
|
||||
*/
|
||||
#getPromptFields() {
|
||||
const textareas = [];
|
||||
|
||||
// Expandable ID List in 1 place
|
||||
[
|
||||
/** Expandable List of IDs in 1 place */
|
||||
const IDs = [
|
||||
'txt2img_prompt',
|
||||
'txt2img_neg_prompt',
|
||||
'img2img_prompt',
|
||||
'img2img_neg_prompt',
|
||||
'hires_prompt',
|
||||
'hires_neg_prompt'
|
||||
].forEach((id) => {
|
||||
];
|
||||
|
||||
for (const id of IDs) {
|
||||
const textArea = document.getElementById(id)?.querySelector('textarea');
|
||||
if (textArea != null)
|
||||
textareas.push(textArea);
|
||||
});
|
||||
}
|
||||
|
||||
// ADetailer
|
||||
[
|
||||
const ADetailer = [
|
||||
"script_txt2img_adetailer_ad_main_accordion",
|
||||
"script_img2img_adetailer_ad_main_accordion"
|
||||
].forEach((id) => {
|
||||
];
|
||||
|
||||
for (const id of ADetailer) {
|
||||
const fields = document.getElementById(id)?.querySelectorAll('textarea');
|
||||
if (fields != null)
|
||||
fields.forEach((textArea) => {
|
||||
if (textArea.placeholder.length > 0)
|
||||
textareas.push(textArea);
|
||||
});
|
||||
});
|
||||
if (fields == null)
|
||||
continue;
|
||||
for (const textArea of fields) {
|
||||
if (textArea.placeholder.length > 0)
|
||||
textareas.push(textArea);
|
||||
}
|
||||
}
|
||||
|
||||
return textareas;
|
||||
}
|
||||
|
||||
/** @returns {HTMLButtonElement} */
|
||||
#createReloadButton() {
|
||||
const button = document.getElementById('settings_show_all_pages').cloneNode(false);
|
||||
const page = document.getElementById('column_settings_pf');
|
||||
|
||||
button.id = "setting_pf_reload";
|
||||
button.textContent = "Reload Cached Cards & Alias";
|
||||
|
||||
button.style.borderRadius = "1em";
|
||||
button.style.margin = "1em 0em 0em 0em";
|
||||
|
||||
page.appendChild(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
/** @returns {string[]} */
|
||||
static cacheCards() {
|
||||
const extras = document.getElementById('txt2img_extra_tabs');
|
||||
|
|
@ -97,16 +87,15 @@ class LeFormatterConfig {
|
|||
return [];
|
||||
|
||||
const cards = [];
|
||||
extras.querySelectorAll('span.name').forEach((card) => {
|
||||
for (const card of extras.querySelectorAll('span.name')) {
|
||||
if (card.textContent.includes('_'))
|
||||
cards.push(card.textContent);
|
||||
});
|
||||
}
|
||||
|
||||
const config = document.getElementById('setting_pf_exclusion').querySelector('input').value;
|
||||
if (config.trim()) {
|
||||
config.split(",").forEach((tag) => {
|
||||
for (const tag of config.split(","))
|
||||
cards.push(tag.trim());
|
||||
});
|
||||
}
|
||||
|
||||
return cards;
|
||||
|
|
@ -117,22 +106,21 @@ class LeFormatterConfig {
|
|||
const alias = new Map();
|
||||
|
||||
const config = document.getElementById('setting_pf_alias').querySelector('textarea').value;
|
||||
|
||||
if (!config.trim())
|
||||
return alias;
|
||||
|
||||
config.split("\n").forEach((line) => {
|
||||
for (const line of config.split("\n")) {
|
||||
const [tag, words] = line.split(":");
|
||||
const mainTag = tag.trim();
|
||||
|
||||
words.split(",").map(part => part.trim()).forEach((word) => {
|
||||
for (const word of words.split(",").map(part => part.trim())) {
|
||||
if (word === mainTag)
|
||||
return;
|
||||
continue;
|
||||
|
||||
const pattern = this.#parseRegExp(word);
|
||||
alias.set(pattern, mainTag);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
|
@ -141,7 +129,6 @@ class LeFormatterConfig {
|
|||
static #parseRegExp(input) {
|
||||
const startAnchor = input.startsWith('^');
|
||||
const endAnchor = input.endsWith('$');
|
||||
|
||||
return new RegExp(`${startAnchor ? '' : '^'}${input}${endAnchor ? '' : '$'}`);
|
||||
}
|
||||
|
||||
|
|
@ -1,26 +1,22 @@
|
|||
class LeFormatterUI {
|
||||
class pfUI {
|
||||
|
||||
/** @param {Function} onClick @returns {HTMLButtonElement} */
|
||||
static #button(onClick) {
|
||||
/** @param {string} text @param {string} tip @returns {HTMLButtonElement} */
|
||||
static #button(text, tip) {
|
||||
const button = document.createElement('button');
|
||||
button.textContent = 'Format';
|
||||
|
||||
button.id = 'manual-format';
|
||||
button.classList.add(['lg', 'secondary', 'gradio-button']);
|
||||
|
||||
button.addEventListener('click', onClick);
|
||||
button.textContent = text;
|
||||
if (tip) button.title = tip;
|
||||
return button;
|
||||
}
|
||||
|
||||
/** @param {boolean} default_value @param {string} text @returns {HTMLDivElement} */
|
||||
static #checkbox(default_value, text) {
|
||||
/** @param {boolean} value @param {string} text @returns {HTMLLabelElement} */
|
||||
static #checkbox(value, text) {
|
||||
const label = document.getElementById('tab_settings').querySelector('input[type=checkbox]').parentNode.cloneNode(true);
|
||||
label.removeAttribute('id');
|
||||
label.classList.add("pf-checkbox");
|
||||
label.removeAttribute('id');
|
||||
|
||||
const checkbox = label.children[0];
|
||||
checkbox.checked = default_value;
|
||||
|
||||
checkbox.checked = value;
|
||||
const span = label.children[1];
|
||||
span.textContent = text;
|
||||
|
||||
|
|
@ -28,16 +24,19 @@ class LeFormatterUI {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Function} onManual
|
||||
* @param {boolean} autoRun @param {boolean} dedupe @param {boolean} removeUnderscore
|
||||
* @param {boolean} autoRun
|
||||
* @param {boolean} dedupe
|
||||
* @param {boolean} removeUnderscore
|
||||
* @returns {HTMLDivElement}
|
||||
* */
|
||||
static setupUIs(onManual, autoRun, dedupe, removeUnderscore) {
|
||||
*/
|
||||
static setupUIs(autoRun, dedupe, removeUnderscore) {
|
||||
const formatter = document.createElement('div');
|
||||
formatter.id = 'le-formatter';
|
||||
|
||||
const manualBtn = this.#button(onManual);
|
||||
const manualBtn = this.#button('Format', null);
|
||||
manualBtn.style.display = autoRun ? 'none' : 'flex';
|
||||
const refreshBtn = this.#button('Reload', 'Reload Cached Cards & Alias');
|
||||
refreshBtn.style.display = removeUnderscore ? 'flex' : 'none';
|
||||
|
||||
const autoCB = this.#checkbox(autoRun, 'Auto Format');
|
||||
const dedupeCB = this.#checkbox(dedupe, 'Remove Duplicates');
|
||||
|
|
@ -47,13 +46,13 @@ class LeFormatterUI {
|
|||
formatter.appendChild(manualBtn);
|
||||
formatter.appendChild(dedupeCB);
|
||||
formatter.appendChild(underscoreCB);
|
||||
formatter.appendChild(refreshBtn);
|
||||
|
||||
formatter.btn = manualBtn;
|
||||
formatter.checkboxs = [
|
||||
autoCB.children[0],
|
||||
dedupeCB.children[0],
|
||||
underscoreCB.children[0]
|
||||
];
|
||||
formatter.manual = manualBtn;
|
||||
formatter.refresh = refreshBtn;
|
||||
formatter.auto = autoCB.children[0];
|
||||
formatter.dedupe = dedupeCB.children[0];
|
||||
formatter.underscore = underscoreCB.children[0];
|
||||
|
||||
return formatter;
|
||||
}
|
||||
|
|
@ -1,11 +1,27 @@
|
|||
class LeFormatter {
|
||||
|
||||
static #cachedCards = null;
|
||||
static #alias = null;
|
||||
static #cachedCardsInternal = null;
|
||||
static #aliasInternal = null;
|
||||
|
||||
static forceReload() {
|
||||
this.#alias = LeFormatterConfig.getTagAlias();
|
||||
this.#cachedCards = LeFormatterConfig.cacheCards();
|
||||
this.#cachedCardsInternal = null;
|
||||
this.#aliasInternal = null;
|
||||
}
|
||||
|
||||
/** @returns {string[]} */
|
||||
static get #cachedCards() {
|
||||
if (this.#cachedCardsInternal == null)
|
||||
this.#cachedCardsInternal = pfConfigs.cacheCards();
|
||||
|
||||
return this.#cachedCardsInternal;
|
||||
}
|
||||
|
||||
/** @returns {Map<RegExp, string>} */
|
||||
static get #alias() {
|
||||
if (this.#aliasInternal == null)
|
||||
this.#aliasInternal = pfConfigs.getTagAlias();
|
||||
|
||||
return this.#aliasInternal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -25,7 +41,7 @@ class LeFormatter {
|
|||
textArea.value = lines.join('\n');
|
||||
else {
|
||||
const val = lines.join(',\n');
|
||||
textArea.value = val.replace(/\n,\n/g, "\n\n");
|
||||
textArea.value = val.replace(/\n,\n/g, '\n\n');
|
||||
}
|
||||
|
||||
if (autoRefresh)
|
||||
|
|
@ -35,12 +51,7 @@ class LeFormatter {
|
|||
/** @param {string} input @param {boolean} dedupe @param {boolean} removeUnderscore @returns {string} */
|
||||
static #formatString(input, dedupe, removeUnderscore) {
|
||||
// Remove Duplicate
|
||||
if (dedupe) {
|
||||
if (this.#alias == null)
|
||||
this.#alias = LeFormatterConfig.getTagAlias();
|
||||
|
||||
input = this.#dedupe(input);
|
||||
}
|
||||
input = dedupe ? this.#dedupe(input) : input;
|
||||
|
||||
// Fix Commas inside Brackets
|
||||
input = input
|
||||
|
|
@ -50,22 +61,17 @@ class LeFormatter {
|
|||
.replace(/\[\s*,+/g, ',[');
|
||||
|
||||
// Sentence -> Tags
|
||||
var tags = input.split(',');
|
||||
let tags = input.split(',');
|
||||
|
||||
// Remove Underscore
|
||||
if (removeUnderscore) {
|
||||
if (this.#cachedCards == null)
|
||||
this.#cachedCards = LeFormatterConfig.cacheCards();
|
||||
|
||||
tags = this.#removeUnderscore(tags);
|
||||
}
|
||||
tags = removeUnderscore ? this.#removeUnderscore(tags) : tags;
|
||||
|
||||
// Remove Stray Brackets
|
||||
const patterns = /^\(+$|^\)+$|^\[+$|^\]+$/;
|
||||
tags = tags.filter(word => !patterns.test(word));
|
||||
|
||||
// Remove extra Spaces
|
||||
input = tags.join(', ').replace(/\s{2,}/g, ' ');
|
||||
input = tags.join(', ').replace(/\s+/g, ' ');
|
||||
|
||||
// Fix Bracket & Space
|
||||
input = input
|
||||
|
|
@ -85,22 +91,22 @@ class LeFormatter {
|
|||
static #dedupe(input) {
|
||||
const chunks = input.split(',');
|
||||
|
||||
const KEYWORD = /^(AND|BREAK)$/;
|
||||
const uniqueSet = new Set();
|
||||
const resultArray = [];
|
||||
const KEYWORD = /^(AND|BREAK)$/;
|
||||
|
||||
chunks.forEach((tag) => {
|
||||
for (const tag of chunks) {
|
||||
const cleanedTag = tag.replace(/\[|\]|\(|\)/g, '').replace(/\s+/g, ' ').trim();
|
||||
|
||||
if (KEYWORD.test(cleanedTag)) {
|
||||
resultArray.push(tag);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
var substitute = null;
|
||||
let substitute = null;
|
||||
for (const [pattern, mainTag] of this.#alias) {
|
||||
if (substitute != null)
|
||||
return;
|
||||
continue;
|
||||
if (pattern.test(cleanedTag))
|
||||
substitute = mainTag;
|
||||
}
|
||||
|
|
@ -108,39 +114,39 @@ class LeFormatter {
|
|||
if ((substitute == null) && (!uniqueSet.has(cleanedTag))) {
|
||||
uniqueSet.add(cleanedTag);
|
||||
resultArray.push(tag);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((substitute != null) && (!uniqueSet.has(substitute))) {
|
||||
uniqueSet.add(substitute);
|
||||
resultArray.push(tag.replace(cleanedTag, substitute));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
resultArray.push(tag.replace(cleanedTag, ''));
|
||||
});
|
||||
}
|
||||
|
||||
return resultArray.join(', ');
|
||||
}
|
||||
|
||||
/** @param {Array<string} tags @returns {Array<string} */
|
||||
/** @param {string[]} tags @returns {string[]} */
|
||||
static #removeUnderscore(tags) {
|
||||
const result = [];
|
||||
|
||||
tags.forEach((tag) => {
|
||||
for (const tag of tags) {
|
||||
if (!tag.trim())
|
||||
return;
|
||||
continue;
|
||||
|
||||
// [start:end:step] OR <lora:name:str>
|
||||
const chucks = tag.split(':').map(c => c.trim());
|
||||
|
||||
for (let i = 0; i < chucks.length; i++) {
|
||||
if (!this.#cachedCards.includes(chucks[i]))
|
||||
chucks[i] = chucks[i].replace(/_/g, ' ');
|
||||
chucks[i] = chucks[i].replaceAll('_', ' ');
|
||||
}
|
||||
|
||||
result.push(chucks.join(':').trim());
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -148,51 +154,59 @@ class LeFormatter {
|
|||
|
||||
onUiLoaded(() => {
|
||||
|
||||
const config = new LeFormatterConfig();
|
||||
config.button.onclick = () => { LeFormatter.forceReload(); }
|
||||
const config = new pfConfigs();
|
||||
const formatter = pfUI.setupUIs(config.autoRun, config.dedupe, config.removeUnderscore);
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.altKey && e.shiftKey && e.code === 'KeyF') {
|
||||
e.preventDefault();
|
||||
config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, true, config.comma));
|
||||
for (const field of config.promptFields)
|
||||
LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, true, config.comma);
|
||||
}
|
||||
});
|
||||
|
||||
const formatter = LeFormatterUI.setupUIs(
|
||||
() => {
|
||||
config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, true, config.comma));
|
||||
},
|
||||
config.autoRun, config.dedupe, config.removeUnderscore
|
||||
);
|
||||
|
||||
formatter.checkboxs[0].addEventListener("change", (e) => {
|
||||
config.autoRun = e.target.checked;
|
||||
formatter.btn.style.display = config.autoRun ? 'none' : 'flex';
|
||||
formatter.auto.addEventListener("change", () => {
|
||||
config.autoRun = formatter.auto.checked;
|
||||
formatter.manual.style.display = config.autoRun ? 'none' : 'flex';
|
||||
});
|
||||
|
||||
formatter.checkboxs[1].addEventListener("change", (e) => {
|
||||
config.dedupe = e.target.checked;
|
||||
formatter.dedupe.addEventListener("change", () => {
|
||||
config.dedupe = formatter.dedupe.checked;
|
||||
});
|
||||
|
||||
formatter.checkboxs[2].addEventListener("change", (e) => {
|
||||
config.removeUnderscore = e.target.checked;
|
||||
formatter.underscore.addEventListener("change", () => {
|
||||
config.removeUnderscore = formatter.underscore.checked;
|
||||
formatter.refresh.style.display = config.removeUnderscore ? 'flex' : 'none';
|
||||
});
|
||||
|
||||
formatter.manual.addEventListener("click", () => {
|
||||
for (const field of config.promptFields)
|
||||
LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, config.refresh, config.comma);
|
||||
});
|
||||
|
||||
formatter.refresh.addEventListener("click", () => {
|
||||
LeFormatter.forceReload();
|
||||
});
|
||||
|
||||
const tools = document.getElementById('quicksettings');
|
||||
tools.after(formatter);
|
||||
|
||||
['txt', 'img'].forEach((mode) => {
|
||||
// Expandable ID List in 1 place
|
||||
[
|
||||
`${mode}2img_generate`,
|
||||
`${mode}2img_enqueue`,
|
||||
].forEach((id) => {
|
||||
const button = document.getElementById(id);
|
||||
button?.addEventListener('click', () => {
|
||||
if (config.autoRun)
|
||||
config.promptFields.forEach((field) => LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, config.refresh, config.comma));
|
||||
});
|
||||
/** Expandable List of IDs in 1 place */
|
||||
const IDs = [
|
||||
'txt2img_generate',
|
||||
'txt2img_enqueue',
|
||||
'img2img_generate',
|
||||
'img2img_enqueue'
|
||||
];
|
||||
|
||||
for (const id of IDs) {
|
||||
const button = document.getElementById(id);
|
||||
button?.addEventListener('click', () => {
|
||||
if (config.autoRun) {
|
||||
for (const field of config.promptFields)
|
||||
LeFormatter.formatPipeline(field, config.dedupe, config.removeUnderscore, config.refresh, config.comma);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,61 +1,39 @@
|
|||
from modules.script_callbacks import on_ui_settings
|
||||
from modules.shared import OptionInfo, opts
|
||||
import gradio as gr
|
||||
|
||||
section = ("pf", "Prompt Format")
|
||||
|
||||
|
||||
def on_settings():
|
||||
from modules.shared import OptionInfo, opts
|
||||
import gradio as gr
|
||||
|
||||
args = {"section": ("pf", "Prompt Format"), "category_id": "system"}
|
||||
|
||||
opts.add_option(
|
||||
"pf_disableupdateinput",
|
||||
OptionInfo(
|
||||
False,
|
||||
"Disable automatic input updates",
|
||||
section=section,
|
||||
category_id="system",
|
||||
).html(
|
||||
"""
|
||||
<span class='info'>(enable this if you have Extension,
|
||||
such as <a href="https://github.com/DominikDoom/a1111-sd-webui-tagcomplete">tagcomplete</a>,
|
||||
that subscribes to text editing event)</span>
|
||||
"""
|
||||
OptionInfo(False, "Disable the automatic updates of the prompts", **args).info(
|
||||
'enable this if you have Extensions, such as <a href="https://github.com/DominikDoom/a1111-sd-webui-tagcomplete">tagcomplete</a>, that subscribe to text editing events'
|
||||
),
|
||||
)
|
||||
|
||||
opts.add_option(
|
||||
"pf_startinauto",
|
||||
OptionInfo(True, "Start in Auto Mode", section=section, category_id="system"),
|
||||
OptionInfo(True, "Launch in Auto Mode", **args),
|
||||
)
|
||||
|
||||
opts.add_option(
|
||||
"pf_startwithdedupe",
|
||||
OptionInfo(
|
||||
True,
|
||||
"Launch with Remove Duplicates",
|
||||
section=section,
|
||||
category_id="system",
|
||||
),
|
||||
OptionInfo(True, "Launch with Remove Duplicates", **args),
|
||||
)
|
||||
|
||||
opts.add_option(
|
||||
"pf_startwithrmudscr",
|
||||
OptionInfo(
|
||||
False,
|
||||
"Launch with Remove Underscores",
|
||||
section=section,
|
||||
category_id="system",
|
||||
),
|
||||
OptionInfo(True, "Launch with Remove Underscores", **args),
|
||||
)
|
||||
|
||||
opts.add_option(
|
||||
"pf_appendcomma",
|
||||
OptionInfo(
|
||||
True,
|
||||
"Append a comma at the end of a line",
|
||||
section=section,
|
||||
category_id="system",
|
||||
).info("only active when there are more than one line"),
|
||||
OptionInfo(True, "Append a comma at the end of each line", **args).info(
|
||||
"only active when there are multiple lines"
|
||||
),
|
||||
)
|
||||
|
||||
opts.add_option(
|
||||
|
|
@ -66,11 +44,10 @@ def on_settings():
|
|||
component=gr.Textbox,
|
||||
component_args={
|
||||
"placeholder": "score_9, score_8_up, score_7_up",
|
||||
"lines": 1,
|
||||
"max_lines": 1,
|
||||
"lines": 1,
|
||||
},
|
||||
section=section,
|
||||
category_id="system",
|
||||
**args
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -82,18 +59,17 @@ def on_settings():
|
|||
component=gr.Textbox,
|
||||
component_args={
|
||||
"placeholder": "1girl: girl, woman, lady\nadult: \\d*\\s*(y\\.?o\\.?|[Yy]ear[s]? [Oo]ld)",
|
||||
"lines": 8,
|
||||
"max_lines": 64,
|
||||
"max_lines": 16,
|
||||
"lines": 4,
|
||||
},
|
||||
section=section,
|
||||
category_id="system",
|
||||
**args
|
||||
)
|
||||
.link("RegExr", "https://regexr.com/")
|
||||
.info(
|
||||
"""treat tags on the right as duplicates, and substitute them with the main tag on the left)
|
||||
(based on regular expression, meaning you may need to escape some symbols)
|
||||
(comma is not supported in pattern"""
|
||||
)
|
||||
.link("RegExr", "https://regexr.com/"),
|
||||
"""treat tags on the right as duplicates of the main tag on the left)
|
||||
(based on regular expression, meaning you need to escape special characters)
|
||||
(comma is not allowed"""
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue