Addressing #2

- Now remove duplicates in brackets too
- Added Chinese translation
- Defaults to UpdateInput now
pull/4/head
Haoming 2023-06-17 11:21:53 +08:00
parent 0beb13a023
commit e894b3a003
3 changed files with 65 additions and 25 deletions

View File

@ -23,10 +23,13 @@ Sometimes, when you type too fast or copy prompts from all over the places, you
- **Note:** `Remove Duplicates` only checks within the same line
- [x] Pressing `Ctrl + \` to quickly escape the **parentheses** of the hovered tag *(the words where the caret is)*
- Normally, **parentheses** are used to increase the weight of a prompt. Therefore, for tags like `mejiro mcqueen (umamusume)`, you will need to escape it like `mejiro mcqueen \(umamusume\)`.
- [X] **[New]** Toggle between auto formatting and manual formatting
- [x] Toggle between auto formatting and manual formatting
- In `Auto`: The process is ran whenever you press **Generate**
- In `Manual`: The process is only ran when you press the **Format** button
- [x] **[New]** Toggle between auto updating prompts or not[^1]
- Some Extensions *(**eg.** [tagcomplete](https://github.com/DominikDoom/a1111-sd-webui-tagcomplete))* listen to the text editing event, which means the formatting causes them to trigger
- You only really need to disable this if you have the above Extension
- You can open `prompt_format.js` and edit this line at the top `static updateInput = true;` to `static updateInput = false;` to save the setting
- When `disabled`, the formatting is purely visual. It will only update once you manually edit the prompt again
<hr>
<sup><b>Note:</b> The formatting is purely visual. The actual prompt is unchanged until you manually edit the texts again.</sup>
[^1]: Due to the implementation being in `JavaScript` instead pf `Python`, the image's metadata will still only be updated in the next generation. This toggle mainly affects when you click `Send to img2img`, will the prompt be already formatted or not, etc.

View File

@ -10,6 +10,7 @@
有時候打字太快,或是從各地東拼西湊咒語,常造成多個重複的空格或逗點。這項插件可以幫忙移除它們。
## 功能實作
- [x] **[New]** 你可以打開`prompt_format.js`並把上面的`static UseCN = false;`改成`static UseCN = true;`來套用中文翻譯
- [x] 在`txt2img`和`img2img`都有用
- [x] 移除多餘**空格**和**逗點**
- [x] 修改錯誤的**括弧**
@ -23,10 +24,13 @@
- **注意:** 上述的`Remove Duplicates`只在同一行中有效
- [x] 按下`Ctrl + \`來跳脫目前游標所在的單字
- 平時,**括弧**是用來強調單字。所以若使用像是`mejiro mcqueen (umamusume)`的咒語,便必須跳脫成`mejiro mcqueen \(umamusume\)`
- [X] **[New]** 按下`Auto Format`以在手動與自動間切換
- [x] 按下`Auto Format`以在手動與自動間切換
- `自動`: 每次按下 **生成 (Generate)** 時處裡
- `手動`: 手動按下`Format`時才處裡
- [x] **[New]** 按下`Update Input`以開/關格式套用[^1]
- 有些擴充 *(**如.** [tagcomplete](https://github.com/DominikDoom/a1111-sd-webui-tagcomplete))* 訂閱文字的編輯事件,意即我的格式化會導致它們啟動
- 基本上,只有在有安裝上述擴充時才需要關閉這個功能
- 你可以打開`prompt_format.js`並把上面的`static updateInput = true;`改成`static updateInput = false;`來永久關閉
- 在`關閉`時,前述的美化只是視覺效果。唯有再次手動編輯後,咒語才會更新
<hr>
<sup><b>注意:</b> 上述美化只是視覺效果。唯有再次手動編輯後,咒語才會更新。</sup>
[^1]: 由於透過`JavaScript`而非`Python`撰寫,生成圖片的內部資料只會在下一次生成才更新。這個選項主要影響,當你按下`Send to img2img`時所傳送的咒語是否已美化過等等。

View File

@ -1,4 +1,11 @@
class LeFormatter {
class LeFormatter {
// === Configs ===
static UseCN = false;
static updateInput = true;
// === Configs ===
static manualButton(text, id, { onClick }) {
const button = gradioApp().getElementById(id).cloneNode()
@ -40,6 +47,28 @@ class LeFormatter {
}
static formatString(input, dedupe, removeUnderscore) {
// Remove Duplicate
if (dedupe) {
const temp = input.split(',')
const cleanArray = []
const finalArray = []
temp.forEach((tag) => {
const cleanedTag = tag.replace(/\[|\]|\(|\)|\s+/g, '').trim()
if (!cleanArray.includes(cleanedTag)) {
cleanArray.push(cleanedTag)
finalArray.push(tag)
} else {
finalArray.push(tag.replace(cleanedTag, ''))
}
})
input = finalArray.join(', ')
}
// Fix Bracket & Comma
input = input.replace(/,\s*\)/g, '),').replace(/,\s*\]/g, '],').replace(/\(\s*,/g, ',(').replace(/\[\s*,/g, ',[')
@ -47,14 +76,11 @@ class LeFormatter {
let tags = input.split(',').map(word => (removeUnderscore ? word.replace(/_/g, ' ') : word).trim()).filter(word => word !== '')
// Remove Stray Brackets
const patterns = [/^\(+$/, /^\)+$/, /^\[+$/, /^\]+$/];
const patterns = [/^\(+$/, /^\)+$/, /^\[+$/, /^\]+$/]
tags = tags.filter(word => !patterns[0].test(word)).filter(word => !patterns[1].test(word)).filter(word => !patterns[2].test(word)).filter(word => !patterns[3].test(word))
// Remove Duplicate
input = dedupe ? [...new Set(tags)].join(', ') : tags.join(', ')
// Remove Spaces
input = input.replace(/\s+/g, ' ')
input = tags.join(', ').replace(/\s+/g, ' ')
// Fix Bracket & Space
input = input.replace(/\s+\)/g, ')').replace(/\s+\]/g, ']').replace(/\(\s+/g, '(').replace(/\[\s+/g, '[')
@ -62,12 +88,10 @@ class LeFormatter {
// Fix Empty Bracket
input = input.replace(/\(\s+\)/g, '').replace(/\[\s+\]/g, '')
while (input.includes('()'))
input = input.replace(/\(\s*\)/g, '')
while (input.includes('[]'))
input = input.replace(/\[\s*\]/g, '')
while (input.match(/\(\s*\)|\[\s*\]/g))
input = input.replace(/\(\s*\)|\[\s*\]/g, '')
return input.trim()
return input.split(',').map(word => word.trim()).filter(word => word !== '').join(', ')
}
static grabBrackets(str, index) {
@ -142,8 +166,9 @@ onUiLoaded(async () => {
let autoRun = true
let dedupe = false
let removeUnderscore = false
let refreshInput = LeFormatter.updateInput
const manualBtn = LeFormatter.manualButton('Format', 'txt2img_generate', {
const manualBtn = LeFormatter.manualButton((LeFormatter.UseCN ? '格式化' : 'Format'), 'txt2img_generate', {
onClick: () => {
const ids = ['txt2img_prompt', 'txt2img_neg_prompt', 'img2img_prompt', 'img2img_neg_prompt']
@ -161,23 +186,27 @@ onUiLoaded(async () => {
}
})
const autoCB = LeFormatter.checkbox('Auto Format', autoRun, {
manualBtn.style.display = 'none'
const autoCB = LeFormatter.checkbox((LeFormatter.UseCN ? '自動格式化' : 'Auto Format'), autoRun, {
onChange: (checked) => {
autoRun = checked
manualBtn.style.display = autoRun ? 'none' : 'block'
}
})
manualBtn.style.display = 'none'
const dedupeCB = LeFormatter.checkbox('Remove Duplicates', dedupe, {
const dedupeCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除重複':'Remove Duplicates'), dedupe, {
onChange: (checked) => { dedupe = checked }
})
const underlineCB = LeFormatter.checkbox('Remove Underscores', removeUnderscore, {
const underlineCB = LeFormatter.checkbox((LeFormatter.UseCN ? '去除底線':'Remove Underscores'), removeUnderscore, {
onChange: (checked) => { removeUnderscore = checked }
})
const refreshCB = LeFormatter.checkbox((LeFormatter.UseCN ? '更新文字' : 'Update Input'), autoRun, {
onChange: (checked) => { refreshInput = checked }
})
const formatter = document.createElement('div')
formatter.id = 'le-formatter'
formatter.style.display = 'flex'
@ -187,6 +216,7 @@ onUiLoaded(async () => {
formatter.appendChild(manualBtn)
formatter.appendChild(dedupeCB)
formatter.appendChild(underlineCB)
formatter.appendChild(refreshCB)
const tools = document.getElementById('quicksettings')
tools.after(formatter)
@ -209,6 +239,9 @@ onUiLoaded(async () => {
lines[m][i] = LeFormatter.formatString(lines[m][i], dedupe, removeUnderscore)
textAreas[m].value = lines[m].join('\n')
if (refreshInput)
updateInput(textAreas[m])
}
}
})