Parenthesis and brackets now convert to weightings
Might have some weird issues when combining composable diffusion with square bracketing. It converts, but may not be correct.pull/18/head
parent
1695f72821
commit
c394787c3d
|
|
@ -4,10 +4,6 @@ import unicodedata
|
|||
|
||||
from modules import script_callbacks
|
||||
|
||||
|
||||
brackets_opening = '([{<'
|
||||
brackets_closing = ')]}>'
|
||||
|
||||
brackets_opening = '([{<'
|
||||
brackets_closing = ')]}>'
|
||||
|
||||
|
|
@ -23,7 +19,9 @@ re_tokenize = re.compile(r',')
|
|||
re_brackets_fix_whitespace = re.compile(r'([\(\[{<])\s*|\s*([\)\]}>}])')
|
||||
re_opposing_brackets = re.compile(r'([)\]}>])([([{<])')
|
||||
re_networks = re.compile(r'<.+?>')
|
||||
re_brackets_open = re.compile(r'[(\[{]+')
|
||||
re_bracket_open = re.compile(r'[(\[]')
|
||||
re_brackets_open = re.compile(r'\(+|\[+')
|
||||
re_brackets_closing = re.compile(r'\)+|\]+')
|
||||
# re_colon_spacing_composite = re.compile(r'(?P<A>[^:]*?)\s*?(?P<COLON>:)\s*?(?P<B>\S*)(?P<S>\s*)(?(S)\s*?)(?P<AND>AND)')
|
||||
re_colon_spacing_composite = re.compile(r'\s*(:)\s*(?=\d*?\.?\d*?\s*?AND)')
|
||||
re_colon_spacing = re.compile(r'\s*(:)\s*')
|
||||
|
|
@ -88,7 +86,7 @@ def align_colons(prompt: str):
|
|||
return ' ' + match.group(1)
|
||||
|
||||
def composite_end(match: re.Match):
|
||||
print(f'match: {match}')
|
||||
# print(f'match: {match}')
|
||||
return ' ' + match.group(1)
|
||||
|
||||
ret = re_colon_spacing.sub(normalize, prompt)
|
||||
|
|
@ -128,15 +126,15 @@ def align_commas(prompt: str):
|
|||
return ', '.join(split)
|
||||
|
||||
|
||||
def brackets_to_weights(tokens: list, power: int = 0):
|
||||
print(tokens)
|
||||
ret = []
|
||||
re_opening_paren = re.compile('\([^\(]')
|
||||
re_opening_square = re.compile('\[[^\[]')
|
||||
# def brackets_to_weights(tokens: list, power: int = 0):
|
||||
# print(tokens)
|
||||
# ret = []
|
||||
# re_opening_paren = re.compile('\([^\(]')
|
||||
# re_opening_square = re.compile('\[[^\[]')
|
||||
|
||||
for token in tokens:
|
||||
if re_opening_paren.match(token):
|
||||
pass
|
||||
# for token in tokens:
|
||||
# if re_opening_paren.match(token):
|
||||
# pass
|
||||
|
||||
|
||||
# Assumes colons have already been spaced corretly
|
||||
|
|
@ -252,10 +250,10 @@ def remove_mismatched_brackets(prompt: str):
|
|||
|
||||
def space_bracekts(prompt: str):
|
||||
def helper(match : re.Match):
|
||||
print(' '.join(match.groups()))
|
||||
# print(' '.join(match.groups()))
|
||||
return ' '.join(match.groups())
|
||||
|
||||
print(prompt)
|
||||
# print(prompt)
|
||||
return re_opposing_brackets.sub(helper, prompt)
|
||||
|
||||
|
||||
|
|
@ -266,8 +264,199 @@ def align_alternating(prompt:str):
|
|||
return re_alternating.sub(helper, prompt)
|
||||
|
||||
|
||||
def bracket_to_weights(prompt: str):
|
||||
"""
|
||||
when scanning, we need a way to ignore prompt editing, composable, and alternating
|
||||
we still need to weigh their individual words within them, however...
|
||||
|
||||
use a depth counter to ensure that we find closing brackets
|
||||
|
||||
the problem is that as we modify the string, we will be changing it's length,
|
||||
which will mess with iterations...
|
||||
we can simply edit the string backwards, that way the operations don't effect
|
||||
the length of the parts we're working on... however, if we do this, then we can't
|
||||
remove consecutive brackets of the same type, we we would need to remove bracketing
|
||||
to the left of the part of the string we're working on.
|
||||
|
||||
well, i think we should be fine with a while pos != end of string, and if we find
|
||||
a weight to add, break from the enumerate loop and resume at position to re-enumerate
|
||||
the new string
|
||||
|
||||
go until we reach a [(, ignore networks < and wildcards {
|
||||
if (
|
||||
count if consecutive repeating bracket
|
||||
look forward to find its corresponding closing bracket
|
||||
check if those closing brackets are also consecutive
|
||||
add weighting at the end
|
||||
remove excessive bracket
|
||||
convert bracket to ()
|
||||
if [
|
||||
count if consecutive repeating bracket
|
||||
look forward
|
||||
if we find a : or |, return/break from this weight search
|
||||
else, to find its corresponding closing bracket
|
||||
check if those closing brackets are also consecutive
|
||||
add weighting at the end
|
||||
remove excessive bracket
|
||||
convert bracket to ()
|
||||
|
||||
IF BRACKETS ARE CONSECUTIVE, AND AFTER THEIR SLOPE, BOTH THEIR
|
||||
INNER-NEXT DEPTH ARE THE SAME, IT IS A WEIGHT.
|
||||
|
||||
Example using map_depth.
|
||||
c, ((a, b))
|
||||
(( ))
|
||||
00012222210
|
||||
---^^----vv
|
||||
2 ____ 2
|
||||
1 /===>\ 1
|
||||
0___/=====>\0
|
||||
Because 01 can meet on the other side, these are matching
|
||||
|
||||
c, (a, (b))
|
||||
( ( ))
|
||||
00011112210
|
||||
---^---^-vv
|
||||
2 _ 2
|
||||
1 ___/>\ 1
|
||||
0___/=====>\0
|
||||
0 and 1 match, but since gradients are not exactly mirrored,
|
||||
thier weights should not be combined.
|
||||
|
||||
c, ((a), b)
|
||||
(( ) )
|
||||
00012211110
|
||||
---^^-v---v
|
||||
2 _ 2
|
||||
1 /=\___ 1
|
||||
0___/=====>\0
|
||||
Similar idea to above example.
|
||||
|
||||
c, ((a), ((b)))
|
||||
(( ) (( )))
|
||||
000122111233210
|
||||
---^^-v--^^-vvv
|
||||
3 _ 3
|
||||
2 _ />\ 2
|
||||
1 />\__/==>\ 1
|
||||
0___/=========>\0
|
||||
Tricky one. Here, 01 open together, so there's a potential that their
|
||||
weights should be combined if they close together, but instead 1 closes
|
||||
early. We only need to check for closure initial checking depth - 1.
|
||||
|
||||
"""
|
||||
re_existing_weight = re.compile(r'(:\d+.?\d*)[)\]]$')
|
||||
depths, gradients, brackets = get_mappings(prompt)
|
||||
|
||||
pos = 0
|
||||
ret = prompt
|
||||
gradient_search = []
|
||||
|
||||
while pos < len(ret):
|
||||
current_position = ret[pos:]
|
||||
if ret[pos] in '([':
|
||||
open_bracketing = re_brackets_open.match(ret, pos)
|
||||
consecutive = len(open_bracketing.group(0))
|
||||
gradient_search = ''.join(map(str, reversed(range(int(depths[pos])-1, int(depths[pos])+consecutive))))
|
||||
is_square_brackets = True if '[' in open_bracketing.group(0) else False
|
||||
|
||||
insert_at, weight, valid_consecutive = get_weight(
|
||||
ret,
|
||||
gradients,
|
||||
depths,
|
||||
brackets,
|
||||
open_bracketing.end(),
|
||||
consecutive,
|
||||
gradient_search,
|
||||
is_square_brackets)
|
||||
|
||||
# Check if weight already exists
|
||||
if weight:
|
||||
if re_existing_weight.search(ret[:insert_at + 1]):
|
||||
ret = ret[:open_bracketing.start()] + '(' + ret[open_bracketing.start()+valid_consecutive:insert_at] + ')' + ret[insert_at + consecutive:]
|
||||
else:
|
||||
ret = ret[:open_bracketing.start()] + '(' + ret[open_bracketing.start()+valid_consecutive:insert_at] + f':{weight:.2f}' + ')' + ret[insert_at + consecutive:]
|
||||
# offset = len(str(f'{weight:.2f}'))
|
||||
|
||||
depths, gradients, brackets = get_mappings(ret)
|
||||
pos += 1
|
||||
|
||||
match = re_bracket_open.search(ret, pos)
|
||||
|
||||
if not match: # no more potential weight brackets to parse
|
||||
return ret
|
||||
|
||||
pos = match.start()
|
||||
|
||||
|
||||
def depth_to_map(s: str):
|
||||
ret = ''
|
||||
depth = 0
|
||||
for c in s:
|
||||
if c in '([':
|
||||
depth += 1
|
||||
if c in ')]':
|
||||
depth -= 1
|
||||
ret += str(depth)
|
||||
return ret
|
||||
|
||||
|
||||
def depth_to_gradeint(s: str):
|
||||
ret = ''
|
||||
for c in s:
|
||||
if c in '([':
|
||||
ret += str('^')
|
||||
elif c in ')]':
|
||||
ret += str('v')
|
||||
else:
|
||||
ret += str('-')
|
||||
return ret
|
||||
|
||||
|
||||
def filter_brackets(s: str):
|
||||
return ''.join(list(map(lambda c : c if c in '[]()' else ' ', s)))
|
||||
|
||||
|
||||
def get_mappings(s: str):
|
||||
return depth_to_map(s), depth_to_gradeint(s), filter_brackets(s)
|
||||
|
||||
|
||||
def calculate_weight(d: str, is_square_brackets: bool):
|
||||
return 1 / 1.1 ** int(d) if is_square_brackets else 1 * 1.1 ** int(d)
|
||||
|
||||
|
||||
def get_weight(prompt: str, map_gradient: list, map_depth: list, map_brackets: list, pos: int, ctv: int, gradient_search: str, is_square_brackets :bool=False):
|
||||
'''
|
||||
Returns 0 if bracket was recognized as prompt editing, alternation, or composable
|
||||
'''
|
||||
# CURRENTLY DOES NOT TAKE INTO ACCOUNT COMPOSABLE?? DO WE EVEN NEED TO?
|
||||
# E.G. [a AND B :1.2] == (a AND B:1.1) != (a AND B:1.1) ????
|
||||
while pos+ctv <= len(prompt):
|
||||
if ctv == 0:
|
||||
return prompt, 0, 1
|
||||
a, b = pos, pos+ctv
|
||||
if prompt[a] in ':|' and is_square_brackets:
|
||||
if map_depth[-2] == map_depth[a]:
|
||||
return prompt, 0, 1
|
||||
if map_depth[a] in gradient_search:
|
||||
gradient_search = gradient_search.replace(map_depth[a], '')
|
||||
ctv -= 1
|
||||
elif (map_gradient[a:b] == 'v' * ctv and
|
||||
map_depth[a-1:b] == gradient_search):
|
||||
return a, calculate_weight(ctv, is_square_brackets), ctv
|
||||
elif ('v' == map_gradient[a] and
|
||||
map_depth[a-1:b-1] in gradient_search):
|
||||
narrowing = map_gradient[a:b].count('v')
|
||||
gradient_search = gradient_search[narrowing:]
|
||||
ctv -= 1
|
||||
pos += 1
|
||||
|
||||
raise Exception(f'Somehow weight index searching has gone outside of prompt length with prompt: {prompt}')
|
||||
|
||||
|
||||
def format_prompt(*prompts: list):
|
||||
ret = []
|
||||
|
||||
for prompt in prompts:
|
||||
# Clean up the string
|
||||
prompt = normalize_characters(prompt)
|
||||
|
|
@ -281,6 +470,7 @@ def format_prompt(*prompts: list):
|
|||
prompt = align_colons(prompt)
|
||||
prompt = align_commas(prompt)
|
||||
prompt = align_alternating(prompt)
|
||||
prompt = bracket_to_weights(prompt)
|
||||
|
||||
# Further processing for usability
|
||||
# prompt = brackets_to_weights(prompt)
|
||||
|
|
|
|||
Loading…
Reference in New Issue