Skip to content

Commit 7b69ec0

Browse files
committed
quick-syntax for multirandom, for #196
1 parent c1bdb04 commit 7b69ec0

File tree

3 files changed

+72
-8
lines changed

3 files changed

+72
-8
lines changed

docs/Basic Usage.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ Prompting is, primarily, just text input. However, there are some special option
8080
- This random is seeded by the main seed - so if you have a static seed, this won't change.
8181
- You can use `,` to separate the entries, or `|`, or `||`. Whichever is most unique gets used - so if you want random options with `,` in them, just use `|` as a separator, and `,` will be ignored (eg `<random:red|blue|purple>`).
8282
- An entry can contain the syntax of eg `1-5` to automatically select a number from 1 to 5. For example, `<random:1-3, blue>` will give back any of: `1`, `2`, `3`, or `blue`.
83+
- You can repeat random choices via `<random[1-3]:red, blue, purple>` which might return for example `red blue` or `red blue purple` or `blue`.
84+
- You can use a comma at the end like `random[1-3,]` to specify the output should have a comma eg `red, blue`.
85+
- You can use the syntax `<wildcard:my/wildcard/name>` to randomly select from a wildcard file, which is basically a pre-saved text file of random options, 1 per line.
86+
- Edit these in the UI at the bottom in the "Wildcards" tab.
87+
- You can also import wildcard files from other UIs (ie text file collections) by just adding them into `Data/Wildcards` folder.
88+
- This supports the same syntax as `random` to get multiple, for example `<wildcard[1-3]:animals>` might return `cat dog` or `elephant leopard dog`.
8389
- You can use the syntax `<repeat:3, cat>` to get the word "cat" 3 times in a row (`cat cat cat`).
8490
- You can use for example like `<repeat:1-3, <random:cat, dog>>` to get between 1 and 3 copies of either `cat` or `dog`, for example it might return `cat dog cat`.
8591
- You can use `<embed:filename>` to use a Textual Inversion embedding anywhere.

src/Text2Image/T2IParamInput.cs

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ public class PromptTagContext
2424

2525
public int Depth = 0;
2626

27+
/// <summary>If the current syntax usage has a pre-data block, it will be here. This will be null otherwise.</summary>
28+
public string PreData;
29+
2730
public string Parse(string text)
2831
{
2932
if (Depth > 1000)
@@ -76,26 +79,63 @@ public static bool TryInterpretNumberRange(string inputVal, out string number)
7679
return null;
7780
}
7881

82+
public static (int, string) InterpretPredataForRandom(string prefix, string preData, string data)
83+
{
84+
int count = 1;
85+
string separator = " ";
86+
if (preData is not null)
87+
{
88+
if (preData.EndsWithFast(','))
89+
{
90+
separator = ", ";
91+
preData = preData[0..^1];
92+
}
93+
double? countVal = InterpretNumber(preData);
94+
if (!countVal.HasValue)
95+
{
96+
Logs.Warning($"Random input '{prefix}[{preData}:{data}' has invalid predata count (not a number) and will be ignored.");
97+
return (0, null);
98+
}
99+
count = (int)countVal.Value;
100+
}
101+
return (count, separator);
102+
}
103+
79104
static T2IParamInput()
80105
{
81106
PromptTagProcessors["random"] = (data, context) =>
82107
{
108+
(int count, string partSeparator) = InterpretPredataForRandom("random", context.PreData, data);
109+
if (partSeparator is null)
110+
{
111+
return null;
112+
}
83113
string separator = data.Contains("||") ? "||" : (data.Contains('|') ? "|" : ",");
84114
string[] vals = data.Split(separator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
85115
if (vals.Length == 0)
86116
{
87117
Logs.Warning($"Random input '{data}' is empty and will be ignored.");
88118
return null;
89119
}
90-
string choice = vals[context.Random.Next(vals.Length)];
91-
if (TryInterpretNumberRange(choice, out string number))
120+
string result = "";
121+
for (int i = 0; i < count; i++)
92122
{
93-
return number;
123+
string choice = vals[context.Random.Next(vals.Length)];
124+
if (TryInterpretNumberRange(choice, out string number))
125+
{
126+
return number;
127+
}
128+
result += context.Parse(choice).Trim() + partSeparator;
94129
}
95-
return context.Parse(choice);
130+
return result.Trim();
96131
};
97132
PromptTagProcessors["wildcard"] = (data, context) =>
98133
{
134+
(int count, string partSeparator) = InterpretPredataForRandom("random", context.PreData, data);
135+
if (partSeparator is null)
136+
{
137+
return null;
138+
}
99139
string card = T2IParamTypes.GetBestInList(data, WildcardsHelper.ListFiles);
100140
if (card is null)
101141
{
@@ -104,8 +144,13 @@ static T2IParamInput()
104144
}
105145
List<string> usedWildcards = context.Input.ExtraMeta.GetOrCreate("used_wildcards", () => new List<string>()) as List<string>;
106146
usedWildcards.Add(card);
107-
string choice = WildcardsHelper.PickRandom(card, context.Random);
108-
return context.Parse(choice);
147+
string result = "";
148+
for (int i = 0; i < count; i++)
149+
{
150+
string choice = WildcardsHelper.PickRandom(card, context.Random);
151+
result += context.Parse(choice).Trim() + partSeparator;
152+
}
153+
return result.Trim();
109154
};
110155
PromptTagProcessors["repeat"] = (data, context) =>
111156
{
@@ -410,6 +455,12 @@ void processSet(Dictionary<string, Func<string, PromptTagContext, string>> set)
410455
val = StringConversionHelper.QuickSimpleTagFiller(val, "<", ">", tag =>
411456
{
412457
(string prefix, string data) = tag.BeforeAndAfter(':');
458+
string preData = null;
459+
if (prefix.EndsWith(']') && prefix.Contains('['))
460+
{
461+
(prefix, preData) = prefix.BeforeLast(']').BeforeAndAfter('[');
462+
}
463+
context.PreData = preData;
413464
if (!string.IsNullOrWhiteSpace(data) && set.TryGetValue(prefix, out Func<string, PromptTagContext, string> proc))
414465
{
415466
string result = proc(data, context);

src/wwwroot/js/genpage/params.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,13 +1007,20 @@ class PromptTabCompleteClass {
10071007
this.registerPrefix('random', 'Select from a set of random words to include', (prefix) => {
10081008
return ['\nSpecify a comma-separated list of words to choose from, like "<random:cat,dog,elephant>". You can use "||" instead of "," if you need to include commas in your values. You can use eg "1-5" to pick a random number in a range.'];
10091009
});
1010-
this.registerPrefix('repeat', 'Repeat a value several times', (prefix) => {
1011-
return ['\nUse for example like "<repeat:3,very> big" to get "very very very big", or "<repeat:1-3,very>" to get randomly between 1 to 3 "very"s, or <repeat:3,<random:cat,dog>>" to get "cat" or "dog" 3 times in a row eg "cat dog cat".'];
1010+
this.registerPrefix('random[2-4]', 'Selects multiple options from a set of random words to include', (prefix) => {
1011+
return ['\nSpecify a comma-separated list of words to choose from, like "<random[2]:cat,dog,elephant>". You can use "||" instead of "," if you need to include commas in your values. You can use eg "1-5" to pick a random number in a range. Put a comma in the input (eg "random[2,]:") to make the output have commas too.'];
10121012
});
10131013
this.registerPrefix('wildcard', 'Select a random line from a wildcard file (presaved list of options)', (prefix) => {
10141014
let prefixLow = prefix.toLowerCase();
10151015
return allWildcards.filter(w => w.toLowerCase().startsWith(prefixLow));
10161016
});
1017+
this.registerPrefix('wildcard[2-4]', 'Select multiple random lines from a wildcard file (presaved list of options) (works same as "random" but for wildcards)', (prefix) => {
1018+
let prefixLow = prefix.toLowerCase();
1019+
return allWildcards.filter(w => w.toLowerCase().startsWith(prefixLow));
1020+
});
1021+
this.registerPrefix('repeat', 'Repeat a value several times', (prefix) => {
1022+
return ['\nUse for example like "<repeat:3,very> big" to get "very very very big", or "<repeat:1-3,very>" to get randomly between 1 to 3 "very"s, or <repeat:3,<random:cat,dog>>" to get "cat" or "dog" 3 times in a row eg "cat dog cat".'];
1023+
});
10171024
this.registerPrefix('preset', 'Forcibly apply a preset onto the current generation (useful eg inside wildcards or other automatic inclusions - normally use the Presets UI tab)', (prefix) => {
10181025
let prefixLow = prefix.toLowerCase();
10191026
return allPresets.filter(p => p.title.toLowerCase().startsWith(prefixLow)).map(p => p.title);

0 commit comments

Comments
 (0)