diff --git a/readme.md b/readme.md index 629896c..fe46179 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,12 @@ # ComfyUI Multi-Clip Text Script Nodes +**Version:** 1.1.0 + Multi-Clip Text Script - Main overview +Multi-Clip Text Script - Main Simple overview + ## How to use it (visual) @@ -21,10 +25,11 @@ This ComfyUI node was created while I was making Wan 2.2 videos with 81 frames a This node was generated with ChatGPT 5.1, and this README was also written by ChatGPT. -Two simple nodes that help you author sequence-friendly prompts from a single script that contains multiple clips. You write one text block with (clip01), (clip02), … sections, then select one clip at a time to produce a clean prompt (with shared prefix/suffix and negative prompt). +Three simple nodes that help you author sequence-friendly prompts from a single script that contains multiple clips. You write one text block with (clip01), (clip02), … sections, then select one clip at a time to produce a clean prompt. Nodes -- Multi-Clip Text Script: Main +- Multi-Clip Text Script: Main (with prefix/suffix/negative) +- Multi-Clip Text Script: Main Simple (simple version, no prefix/suffix/negative) - Multi-Clip Text Script: Clip Selector Category @@ -54,8 +59,7 @@ or Copy sequence_prompt_nodes.py and __init__.py into your ComfyUI/custom_nodes/ComfyUI-MultiClip-Text-Script. Restart ComfyUI. Search for: - - “Multi-Clip Text Script: Main” - - “Multi-Clip Text Script: Clip Selector” + - “Multi-Clip Text Script: Main” - "Multi-Clip Text Script: Main Simple" - “Multi-Clip Text Script: Clip Selector” ## Script format @@ -102,6 +106,31 @@ Details - Leading/trailing whitespace is trimmed from all pieces. +## Node: Multi-Clip Text Script: Main Simple + +Purpose +- Simplified version of Main without prefix/suffix options. Parse the multi-clip script and store per-clip texts in pair_data. +- Ideal when you only need the clip content without additional prefix/suffix/negative modifiers. + +Inputs (required) +- multi_clip_script (STRING, multiline): Your script with (clipXX) sections. + +Outputs +- pair_data (MULTICLIP_PAIR_DATA): Internal encoded data with all clips (no prefix/suffix). +- num_clips (INT): Number of parsed clips. + +Details +- Internally, prefix and suffix are empty strings, so the pair_data contains only the clip texts. +- Connect pair_data to Clip Selector's pair_data input for clip selection. +- Simpler workflow when you only need basic clip sequencing without decorators. + +Typical usage +- Multi-Clip Text Script: Main Simple + - pair_data → Multi-Clip Text Script: Clip Selector.pair_data +- Multi-Clip Text Script: Clip Selector + - clip_text → your text encoder's positive prompt input + + ## Node: Multi-Clip Text Script: Clip Selector Purpose @@ -171,16 +200,24 @@ Clip Selector - negative_text: “low quality, blurry, artifacts” -## Typical workflow +## Typical workflows +### Workflow 1: Full Featured (Main with prefix/suffix/negative) - Multi-Clip Text Script: Main - pair_data → Multi-Clip Text Script: Clip Selector.pair_data - multi_clip_negative → Multi-Clip Text Script: Clip Selector.negative - Multi-Clip Text Script: Clip Selector - - clip_text → your text encoder’s positive prompt input - - negative_text → your text encoder’s negative prompt input + - clip_text → your text encoder's positive prompt input + - negative_text → your text encoder's negative prompt input - Render per-clip by changing clip_number or automating it in a loop. +### Workflow 2: Simple (Main Simple for basic clip sequences) +- Multi-Clip Text Script: Main Simple + - pair_data → Multi-Clip Text Script: Clip Selector.pair_data +- Multi-Clip Text Script: Clip Selector + - clip_text → your text encoder's positive prompt input +- Render per-clip by changing clip_number. + ## Internal encoding (for reference) @@ -215,13 +252,28 @@ Clip Selector - Use auto_format = True to remove trailing commas/semicolons/spaces from each part before joining. +## Changelog + +### v1.1.0 (January 2, 2026) +- **NEW:** Added "Multi-Clip Text Script: Main Simple" node - simplified version without prefix/suffix/negative options +- **IMPROVED:** Updated README with two workflow examples (full-featured and simple) +- **IMPROVED:** Better documentation for users choosing between Main and Main Simple nodes + +### v1.0.0 (Initial Release) +- Multi-Clip Text Script: Main node with prefix/suffix/negative support +- Multi-Clip Text Script: Clip Selector node with auto-format option +- Full documentation and usage examples + + ## Development notes - Node classes: - MultiClipTextScriptMain + - MultiClipTextScriptPositiveOnly (Main Simple) - MultiClipTextScriptClipSelector - Display names: - - “Multi-Clip Text Script: Main” + - "Multi-Clip Text Script: Main" + - "Multi-Clip Text Script: Main Simple" - “Multi-Clip Text Script: Clip Selector” - Category: “Text / Multi-Clip” - Regex used to parse clips: diff --git a/sequence_prompt_nodes.py b/sequence_prompt_nodes.py index cfc592e..7bc7cf3 100644 --- a/sequence_prompt_nodes.py +++ b/sequence_prompt_nodes.py @@ -142,6 +142,76 @@ class MultiClipTextScriptMain: return (payload, num_clips, negative_clean) +class MultiClipTextScriptPositiveOnly: + """ + Multi-Clip Text Script: Main Simple + + Förenklad version av Main utan prefix/suffix/negativ. + + Tar endast scriptet med (clip01)(clip02)... och konverterar det till pair_data. + + Användning: + - Scriptet med (clip01), (clip02), osv + - Utdata pair_data → Clip Selector (din befintliga nod) + + Output: + pair_data (MULTICLIP_PAIR_DATA) – intern sträng med alla clips + num_clips (INT) – hur många klipp som hittades + """ + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "multi_clip_script": ( + "STRING", + { + "multiline": True, + "default": "(clip01)\nwoman walks forward and waves to the camera\n\n" + "(clip02)\nwoman walks forward and gets angry\n\n" + "(clip03)\nwoman throws the phone", + }, + ), + }, + } + + RETURN_TYPES = ("MULTICLIP_PAIR_DATA", "INT") + RETURN_NAMES = ("pair_data", "num_clips") + FUNCTION = "parse_simple" + CATEGORY = "Text / Multi-Clip" + + def parse_simple(self, multi_clip_script: str): + # Hitta alla (clipXX) + text fram till nästa (clipYY) eller slutet + pattern = r"\(clip(\d+)\)\s*(.*?)(?=\n\(clip\d+\)|\Z)" + matches = re.findall(pattern, multi_clip_script, flags=re.DOTALL | re.IGNORECASE) + + clips = [] + for idx, text in matches: + text = text.strip() + if text: + clips.append((int(idx), text)) + + # Sortera efter clip-nummer + clips.sort(key=lambda x: x[0]) + + if not clips: + # Inga klipp hittade + payload = META_SEP.join(["", "", ""]) + return (payload, 0) + + # Själva klipp-texterna i ordning + clip_texts = [t for _, t in clips] + clips_blob = CLIP_SEP.join(clip_texts) + + # Kodning i pair_data (samma format som Main, men utan prefix/suffix): + # "" <> "" <> clip1 <> clip2 <> ... + payload = META_SEP.join(["", "", clips_blob]) + num_clips = len(clip_texts) + + return (payload, num_clips) + + + class MultiClipTextScriptClipSelector: """ Multi-Clip Text Script: Clip Selector @@ -309,9 +379,11 @@ class MultiClipTextScriptClipSelector: NODE_CLASS_MAPPINGS = { "MultiClipTextScriptMain": MultiClipTextScriptMain, "MultiClipTextScriptClipSelector": MultiClipTextScriptClipSelector, + "MultiClipTextScriptPositiveOnly": MultiClipTextScriptPositiveOnly, } NODE_DISPLAY_NAME_MAPPINGS = { "MultiClipTextScriptMain": "Multi-Clip Text Script: Main", "MultiClipTextScriptClipSelector": "Multi-Clip Text Script: Clip Selector", + "MultiClipTextScriptPositiveOnly": "Multi-Clip Text Script: Main Simple", } diff --git a/simple.PNG b/simple.PNG new file mode 100644 index 0000000..e4cefc2 Binary files /dev/null and b/simple.PNG differ