Improvements for pnginfo

- Handled no negative prompt scenario
- Include new lines in positive/negative prompts
- Added links to the top to copy png info sections (all/positive/negative/settings)
This commit is contained in:
MarcusNyne 2024-08-24 17:27:32 -04:00
parent 67309750da
commit eef1f1e0c6
4 changed files with 88 additions and 9 deletions

View File

@ -12,11 +12,17 @@ from modules.ui_common import plaintext_to_html
import gradio as gr
import safetensors.torch
def pnginfo_format_string(plain_text):
content = "<br>\n".join(html.escape(x) for x in str(plain_text).split('\n'))
return content
def pnginfo_format_setting(name, value):
cls_name = 'geninfo-setting-string' if value.startswith('"') else 'geninfo-setting-value'
return f"<span class='geninfo-setting-name'>{html.escape(name)}:</span> <span class='{cls_name}' onclick='uiCopyElementText(this)'>{html.escape(value)}</span>"
def pnginfo_format_quicklink(name):
return f"<span class='geninfo-quick-link' onclick='uiCopyPngInfo(this, \"{name}\")'>[{html.escape(name)}]</span>"
def run_pnginfo(image):
if image is None:
return '', '', ''
@ -28,16 +34,23 @@ def run_pnginfo(image):
if parser.valid:
info += f"""
<div class='pnginfo-page'>
<p><b>parameters</b></p>
{plaintext_to_html(str(parser.positive))}
<p><b>parameters</b><br>
{pnginfo_format_quicklink("All")}&nbsp;{pnginfo_format_quicklink("Positive")}"""
if parser.negative is not None:
info += f'&nbsp;{pnginfo_format_quicklink("Negative")}'
info += f"""&nbsp;{pnginfo_format_quicklink("Settings")}
</p>
<p id='pnginfo-positive'>{pnginfo_format_string(parser.positive)}</p>"""
if parser.negative is not None:
info += f"""
<p>
<span class='geninfo-setting-name'>Negative prompt:</span><br>{html.escape(str(parser.negative))}
<span class='geninfo-setting-name'>Negative prompt:</span><br><span id='pnginfo-negative'>{pnginfo_format_string(parser.negative)}</span>
</p>
"""
if parser.settings is None:
info += f"{plaintext_to_html(str(parser.parameters))}"
else:
info += "<p>"
info += "<p id='pnginfo-settings'>"
first = True
for setting in parser.settings:
if first:
@ -48,7 +61,7 @@ def run_pnginfo(image):
info += "</p>"
if parser.extra is not None:
info += f"{plaintext_to_html(str(parser.extra))}"
info += f"<p>{pnginfo_format_string(parser.extra)}</p>"
info += "</div>\n"
else:

View File

@ -2,6 +2,7 @@ import re
class PngParser:
re_top_level = None
re_top_level2 = None
re_extra_newline = None
re_parameters = None
@ -15,11 +16,18 @@ class PngParser:
# separate positive, negative, and parameters
m = PngParser.re_top_level.search(pnginfo_string)
if m is None:
return False
m = PngParser.re_top_level2.search(pnginfo_string)
if m is None:
return False
else:
self.positive = m.group(1)
self.negative = None
self.parameters = m.group(2)
else:
self.positive = m.group(1)
self.negative = m.group(2)
self.parameters = m.group(3)
self.positive = m.group(1)
self.negative = m.group(2)
self.parameters = m.group(3)
self.extra = None
self.settings = None
@ -43,5 +51,7 @@ class PngParser:
def init_re(cls):
if cls.re_top_level is None:
cls.re_top_level = re.compile(r'^(?P<positive>(?:.|\n)*)\nNegative prompt: (?P<negative>(?:.|\n)*)\n(?=Steps: )(?P<parameters>(?:.|\n)*)$')
cls.re_top_level2 = re.compile(r'^(?P<positive>(?:.|\n)*)\nSteps: (?P<parameters>(?:.|\n)*)$')
# cls.re_top_level2 = re.compile(r'^(?P<positive>(?:.|\n)*)\n(?=Steps: )(?P<parameters>(?:.|\n)*)$')
cls.re_extra_newline = re.compile(r'\n(?=(?:[^"]*"[^"]*")*[^"]*$)')
cls.re_parameters = re.compile(r'\s*(?P<param>[^:,]+):\s*(?P<quote>")?(?P<value>(?(2)(?:.)*?(?:(?<!\\)")|.*?))(?:\s*,\s*|$)')

View File

@ -226,3 +226,45 @@ function uiCopyElementText(el) {
el.classList.add('animate');
}, 0);
}
function uiCopyRawText(elid) {
var el = document.getElementById(elid);
if (el==null)
return null;
return el.innerText;
}
function uiCopyPngInfo(el, mode) {
var text = null;
if (mode=="Positive")
text = uiCopyRawText("pnginfo-positive");
else if (mode=="Negative")
text = uiCopyRawText("pnginfo-negative");
else if (mode=="Settings")
text = uiCopyRawText("pnginfo-settings");
else if (mode=="All") {
text = "";
var t2 = uiCopyRawText("pnginfo-positive");
if (t2!=null)
text += t2;
t2 = uiCopyRawText("pnginfo-negative");
if (t2!=null)
text += "\nNegative prompt:"+t2;
t2 = uiCopyRawText("pnginfo-settings");
if (t2!=null)
text += "\n"+t2;
if (text == "")
text = null;
}
if (text!=null) {
navigator.clipboard.writeText(text);
el.classList.remove('animate');
setTimeout(() => {
el.classList.add('animate');
}, 0);
}
}

View File

@ -1709,6 +1709,15 @@ body.resizing .resize-handle {
background-color: var(--pnginfo-string-hover);
}
.pnginfo-page p span.geninfo-quick-link {
color: var(--pnginfo-string-color);
cursor: pointer;
}
.pnginfo-page p span.geninfo-quick-link:hover {
background-color: var(--pnginfo-string-hover);
}
/* PngInfo animations */
@keyframes copyAnimationSettingValue {
0% {
@ -1740,4 +1749,9 @@ span.geninfo-setting-value.animate {
span.geninfo-setting-string.animate {
-webkit-animation: copyAnimationSettingString 1s 1;
animation: copyAnimationSettingString 1s 1;
}
span.geninfo-quick-link.animate {
-webkit-animation: copyAnimationSettingString 1s 1;
animation: copyAnimationSettingString 1s 1;
}