Files
ausboss-ComfyUI-AusBoss/nodes/node_show_text.py
T
ausboss 05038baaa3 Five basics the normal nodes have: sums, any wire into Show Text, name tokens, word weights, Image Size's numbers
Found in a sweep of the pack against ComfyUI's own nodes: things the normal
node does that the pack's node did not.

- Every number box takes a sum. Click a number, type 1024*1.5 or
  (1920-64)/2 and press Enter, as in ComfyUI's own number boxes: + - * / %,
  brackets and a sign. The reader is the pack's own (sumValue in
  js/shared/scrub_input.mjs) and is only asked when the text is not a plain
  number.
- Show Text takes any wire. Its input was STRING only. A number, an on/off
  value or a list is shown too; a picture or a latent is shown by its size.
  The output stays STRING and carries the text that is shown, so text
  passes through unchanged and a number comes out as text.
- Save Image takes name tokens in the file name, as ComfyUI's own Save
  Image does: %date:yyyy-MM-dd% and %Node.setting% are filled in the
  browser when a run is sent (js/shared/name_tokens.mjs, now shared with
  Save Video), %width% %height% and the time tokens on the server. The
  path preview shows them. A linked filename is never read for tokens.
- Ctrl + Up and Ctrl + Down change a word's weight in the pack's prompt
  boxes (Text, Krea 2 Encode). The card's text box stopped the key before
  ComfyUI's own listener saw it; those two keys now go on from a multiline
  box, and from nowhere else.
- Image Size shows what it measured beside its outputs after a run
  ("width: 1024"). The numbers go into the output labels, so the node keeps
  its size. ComfyUI says nothing about a node whose answer came from its
  cache, so the numbers are kept in the node's properties and come back
  when a workflow is opened again; a changed picture wire clears them.

No input was added, renamed or reordered. Help pages, README lines, tests
and CHANGELOG entries are included.
2026-10-11 17:10:52 -05:00

98 lines
3.3 KiB
Python

"""Show Text 🆎."""
from __future__ import annotations
import json
from ._memory_helpers import WILDCARD
def _by_size(value) -> str | None:
"""A picture, mask or latent as its size, or None for anything else."""
shape = getattr(value, "shape", None)
if shape is None:
return None
try:
sizes = [int(side) for side in shape]
except (TypeError, ValueError):
return None
if not sizes:
# A single number held in a tensor reads as that number.
try:
return str(value.item())
except Exception: # noqa: BLE001 - any odd object falls back to its own text
return None
kind = str(getattr(value, "dtype", "")).replace("torch.", "")
return "tensor " + " x ".join(str(side) for side in sizes) + (f", {kind}" if kind else "")
def as_text(value) -> str:
"""What the panel shows, and the output carries, for a value.
Text stays as it is. A number or a switch becomes its digits or its
word. A list or a dict becomes JSON. A picture, a mask or a latent is
named by its size, since its numbers would fill the panel.
"""
if isinstance(value, str):
return value
if value is None or isinstance(value, (bool, int, float)):
return str(value)
sized = _by_size(value)
if sized is not None:
return sized
if isinstance(value, (dict, list, tuple)):
try:
return json.dumps(value, indent=2, ensure_ascii=False, default=lambda inner: _by_size(inner) or str(inner))
except (TypeError, ValueError):
pass
return str(value)
class AusBossShowText:
CATEGORY = "🆎 AusBoss/Utility"
DESCRIPTION = (
"Shows what arrives on a wire, on the node itself: a prompt, an LLM "
"reply, a file name, a number. Text passes through unchanged, so "
"the node can sit in the middle of a wire. A number or any other "
"value comes out as the text that is shown. The text can be "
"selected and copied."
)
SEARCH_ALIASES = [
"show text", "display text", "preview text", "print string",
"preview any", "show any", "show number", "to string", "ausboss",
]
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"text": (
WILDCARD,
{
"forceInput": True,
"tooltip": "What to show. Text, a number, or any other wire.",
},
),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("text",)
OUTPUT_TOOLTIPS = ("The text that is shown. Text that came in passes through unchanged.",)
FUNCTION = "show"
OUTPUT_NODE = True
def show(self, text):
# The ui payload is what the frontend panel renders (delivered to
# onExecuted). The output is the same text: a string that came in
# is passed on untouched, anything else as what the panel shows, so
# the STRING output never carries a value that is not text.
shown = as_text(text)
return {"ui": {"text": [shown]}, "result": (shown,)}
NODE_CLASS_MAPPINGS = {"AUSBOSS_NODES_ShowText": AusBossShowText}
NODE_DISPLAY_NAME_MAPPINGS = {"AUSBOSS_NODES_ShowText": "Show Text 🆎"}
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]