Automatically chunk formparagraph output

I have a formparagraph called "Message" that I use to craft messages that I want to send. However, my messaging software has a limit of 185 characters per message. There are many times I need to send a lot more than 185 characters though. So, I need whatever I type in my Message to be automatically broken up into outputs that are each capped at 185 characters. For example, if the message I type has 420 characters in it, I would end up with 3 outputs where Message 1 shows the first 185 characters of my message, Message 2 shows the next 185 characters of my message, and Message 3 shows the remaining 50 characters of my message.

I came up with the following snippet that seems like it may be headed in the right direction, but it feels clunky to me. I made the default formparagraph content a ChatGPT generated prompt that is 420 characters to keep with the above example.

{note: preview=no; insert=no; trim=yes}
Variables:
Message Length: {message_length={=len(message)}}{=message_length}
Message Length - 186: {message_length_minus_186=message_length-186}{=message_length_minus_186}
{endnote: trim=left}
{formparagraph: name=message; cols=65; rows=8; default=At Creative Solutions, we blend work with a touch of fun to keep things lively. Every Friday, we host a "Cheerful Chats" where we share jokes, enjoy snacks, and catch up. This weekly ritual not only lifts our spirits but also sparks new ideas and strengthens our team bond. We have found that these moments of lightheartedness make our workdays more enjoyable and enhance our overall productivity. Cheers to fun at work!}

Character Counter: {=message_length} {if: {=185-{=message_length}<15}}
Characters Remaining: {=185-{=message_length}}{else}Characters Remaining: {=185-{=message_length}}{endif}{if: (186-{=message_length})<=0}
{error: MAX CHARACTERS REACHED!; block=yes; show=default}{endif}

Messages 1 and 2 below are a test of having Text Blaze automatically take what you are typing in the field above, and splitting it into 2 messages, as you type, if it exceeds 185 characters.

Message_1: {message_1=left(message,185)}{=message_1}

Message_2: {if: {=message_length}>185}{message_2=right(message,message_length_minus_186)}{=message_2}{endif}

See, the split seems to work fine for Message 1, but I have not figured out how to do this for a 2nd, 3rd or even 4th message if needed. Also, it would be ideal if the automatic split happened at a word break before hitting the 185th character in each message. How would any of y'all go about doing this? Love to hear your ideas!

Hey @Brad_Hedinger, here's one way to do it:

  1. You calculate the number of messages required
  2. You create a sequence of that number (1,2,..., last message)
  3. You map each item in that sequence to the relevant section in the original message (the first 185 characters, the 2nd 185 characters, etc)

Here's the snippet:

{note: preview=no; insert=no; trim=yes}
Variables:
Message Length: {message_length={=len(message)}}{=message_length}
Message Length - 186: {message_length_minus_186=message_length-186}{=message_length_minus_186}
{endnote: trim=left}
{formparagraph: name=message; cols=65; rows=8; default=At Creative Solutions, we blend work with a touch of fun to keep things lively. Every Friday, we host a "Cheerful Chats" where we share jokes, enjoy snacks, and catch up. This weekly ritual not only lifts our spirits but also sparks new ideas and strengthens our team bond. We have found that these moments of lightheartedness make our workdays more enjoyable and enhance our overall productivity. Cheers to fun at work!}

Character Counter: {=message_length} {if: {=185-{=message_length}<15}}
Characters Remaining: {=185-{=message_length}}{else}Characters Remaining: {=185-{=message_length}}{endif}{if: (186-{=message_length})<=0}
{error: MAX CHARACTERS REACHED!; block=yes; show=default}{endif}

Messages 1 and 2 below are a test of having Text Blaze automatically take what you are typing in the field above, and splitting it into 2 messages, as you type, if it exceeds 185 characters.

{`number of messages`=ceil(message_length/185)}{messages=map(seq(1,{=`number of messages`}),(x)->left(right(message,message_length-185*(x-1)),185))}

{repeat: for item in messages}
{=item}
{endrepeat}

2 Likes

@Dan_Barak1 This is a great solution, Dan! Thank you! My teams absolutely love it. Curious your thoughts on this other part of the original ask:

"Also, it would be ideal if the automatic split happened at a word break before hitting the 185th character in each message."

I tried to figure it out but hit a wall. Any ideas?

Hi Brad, try this:

{note: preview=no; insert=no; trim=yes}
Variables:
Message Length: {message_length={=len(message)}}{=message_length}
Message Length - 186: {message_length_minus_186=message_length-186}{=message_length_minus_186}
{endnote: trim=left}
{formparagraph: name=message; cols=65; rows=8; default=At Creative Solutions, we blend work with a touch of fun to keep things lively. Every Friday, we host a "Cheerful Chats" where we share jokes, enjoy snacks, and catch up. This weekly ritual not only lifts our spirits but also sparks new ideas and strengthens our team bond. We have found that these moments of lightheartedness make our workdays more enjoyable and enhance our overall productivity. Cheers to fun at work!}

Character Counter: {=message_length} {if: {=185-{=message_length}<15}}
Characters Remaining: {=185-{=message_length}}{else}Characters Remaining: {=185-{=message_length}}{endif}{if: (186-{=message_length})<=0}
{error: MAX CHARACTERS REACHED!; block=yes; show=default}{endif}

{splitter=(string, max_chunk_size) -> block
var chunks = [ ] # our final output
var words = split(string, " ") # get individual words from the string
var current_chunk = "" # our current chunk
for index in seq(1, count(words))
var word = words[index]
var prepend = " " if index > 1 else ""
var new_chunk = current_chunk & prepend & word
if len(new_chunk) > max_chunk_size
if len(current_chunk) > 0
chunks = merge(chunks, [current_chunk])
endif
current_chunk = word
else
current_chunk = new_chunk
endif
endfor
if len(current_chunk) > 0
chunks = merge(chunks, [current_chunk])
endif
return chunks
endblock}


Split at 185 characters:{messages_185=splitter(message, 185)}

{repeat: for item in messages_185}
{=item} (length: {=len(item)})
{endrepeat}


Split at 100 characters:{messages_100=splitter(message, 100)}
{repeat: for item in messages_100}
{=item} (length: {=len(item)})
{endrepeat}

I have written a code block to run the split algorithm (see function splitter) and output the chunks. I first split the input string by spaces into a list of words. The core logic is in the loop (see docs) that visits each word sequentially and adds it to the current chunk if we're within the limit, or adds it to the next chunk if we're exceeding the limit.

:exploding_head: This melts my brain, @Gaurang_Tandon! Unreal! Let me have some folks take this for a spin. I'll let you know how it works out. Thank you!

1 Like