It cuts off the k in the first bit of text, but works fine on other text without a k
specifically the second k gets cut off weirdly enough
thereās also supposed to be an ! after it
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local plainText = ""
local colorSegments = {}
local currentIndex = 1
local cleanText = richText:gsub("<[^>]+>", "")
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. cleanText:sub(currentIndex)
break
end
plainText = plainText .. cleanText:sub(currentIndex, tagStart - 1)
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
plainText = plainText .. cleanText:sub(contentStart)
break
end
local content = cleanText:sub(#plainText + 1, #plainText + (contentEnd - contentStart))
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return plainText, colorSegments
end
local plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Clean text length:", #richText:gsub("<[^>]+>", ""))
print("Plain text length:", #plainText)
print("Final plain text (should have no HTML tags):", plainText)
return plainText
end
local richText = '<font color="rgb(255,0,0)">Welcome to Shork</font> <font color="rgb(0,255,0)">Shipwreck!</font>'
local frameWithImageLabels = -- Your frame containing ImageLabels
local plainText = applyRichTextColors(richText, frameWithImageLabels)
print("Plain text:", plainText)
for match in richText:gmatch("rgb%((%d+),%s*(%d+),%s*(%d+)%)") do
print("RGB values found:", match)
end
not sure whatās the issue i cleaned the html tags again
Itās no longer coloring the text, weirdly enough, and itās still cutting off the k! in the first string of text
hopefully the output in the video helps you solve the issue
i think i got the issue probably because the contentend math
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local plainText = ""
local colorSegments = {}
local currentIndex = 1
local cleanText = richText:gsub("<[^>]+>", "")
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. cleanText:sub(currentIndex)
break
end
plainText = plainText .. cleanText:sub(currentIndex, tagStart - 1)
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
contentEnd = #richText
else
contentEnd = contentEnd - 1
end
local content = cleanText:sub(#plainText + 1, #plainText + (contentEnd - contentStart) + 1)
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return plainText, colorSegments
end
local plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Clean text:", cleanText)
print("Plain text:", plainText)
print("Number of color segments:", #colorSegments)
return plainText
end
local richText = '<font color="rgb(160,97,0)">Welcome to Shork</font> <font color="rgb(0,255,0)">Shipwreck!</font>'
local frameWithImageLabels = -- Your frame containing ImageLabels
local plainText = applyRichTextColors(richText, frameWithImageLabels)
for match in richText:gmatch("rgb%((%d+),%s*(%d+),%s*(%d+)%)") do
print("RGB values found:", match)
end
if that doesnāt work let me know
also I should clarify I have it run it once with the frame inputted as nil in order to return just the unformatted text, and I then feed that unformatted text to my text generator, and once the frame is created I call your function again this time sending the frame to it
Hereās what that looks like
you forgot to return the variable for cleanText so it can properly print it, so I fixed that real quick, Iāll give it a test run now and send the results
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local cleanText = richText:gsub("<[^>]+>", "")
local plainText = ""
local colorSegments = {}
local currentIndex = 1
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. cleanText:sub(currentIndex)
break
end
plainText = plainText .. cleanText:sub(currentIndex, tagStart - 1)
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
contentEnd = #richText
else
contentEnd = contentEnd - 1
end
local content = cleanText:sub(#plainText + 1, #plainText + (contentEnd - contentStart) + 1)
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return cleanText, plainText, colorSegments
end
local cleanText, plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Clean text:", cleanText)
print("Plain text:", plainText)
print("Number of color segments:", #colorSegments)
return plainText
end
it looks like it got the cleanText right but still gets the plainText wrong
Alright
i can give it one more try or two because i am really confused i added a lot of debugging please copy me the results in case doesnāt work
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local plainText = ""
local colorSegments = {}
local currentIndex = 1
local cleanText = richText:gsub("<[^>]+>", "")
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. cleanText:sub(currentIndex)
break
end
plainText = plainText .. cleanText:sub(currentIndex, #plainText + (tagStart - currentIndex))
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
contentEnd = #richText
else
contentEnd = contentEnd - 1
end
local content = cleanText:sub(#plainText + 1, #plainText + (contentEnd - contentStart) + 1)
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return cleanText, plainText, colorSegments
end
local cleanText, plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Original rich text:", richText)
print("Clean text:", cleanText)
print("Plain text:", plainText)
print("Number of color segments:", #colorSegments)
-- Additional checks
assert(#cleanText == #plainText, "Clean text and plain text lengths don't match")
assert(cleanText == plainText, "Clean text and plain text content don't match")
for i, segment in ipairs(colorSegments) do
print("Segment", i, "Start:", segment.startPosition, "End:", segment.endPosition, "Color:", segment.color)
assert(segment.startPosition <= segment.endPosition, "Invalid segment range")
assert(segment.endPosition <= #plainText, "Segment end exceeds text length")
end
return plainText, cleanText, colorSegments
end
local richText = '<font color="rgb(160,97,0)">Welcome to Shork</font> <font color="rgb(0,255,0)">Shipwreck!</font>'
local frameWithImageLabels = yourframe -- your frame here
local plainText, cleanText, colorSegments = applyRichTextColors(richText, frameWithImageLabels)
print("\nFinal results:")
print("Clean text:", cleanText)
print("Plain text:", plainText)
for match in richText:gmatch("rgb%((%d+),%s*(%d+),%s*(%d+)%)") do
print("RGB values found:", match)
end
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local plainText = ""
local colorSegments = {}
local currentIndex = 1
local cleanText = richText:gsub("<[^>]+>", "")
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. richText:sub(currentIndex):gsub("</?font>", "")
break
end
plainText = plainText .. richText:sub(currentIndex, tagStart - 1):gsub("</?font>", "")
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
contentEnd = #richText
else
contentEnd = contentEnd - 1
end
local content = richText:sub(contentStart, contentEnd):gsub("</?font>", "")
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return cleanText, plainText, colorSegments
end
local cleanText, plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Original rich text:", richText)
print("Clean text:", cleanText)
print("Plain text:", plainText)
print("Number of color segments:", #colorSegments)
assert(#cleanText == #plainText, "Clean text and plain text lengths don't match")
assert(cleanText == plainText, "Clean text and plain text content don't match")
for i, segment in ipairs(colorSegments) do
print("Segment", i, "Start:", segment.startPosition, "End:", segment.endPosition, "Color:", segment.color)
end
return plainText, cleanText, colorSegments
end
local richText = 'Welcome to <font color="rgb(160, 193, 255)">Shork</font> <font color="rgb(97, 134, 255)">Shipwreck</font>!'
local frameWithImageLabels = yourframehere
local plainText, cleanText, colorSegments = applyRichTextColors(richText, frameWithImageLabels)
print("\nFinal results:")
print("Clean text:", cleanText)
print("Plain text:", plainText)
for match in richText:gmatch("rgb%((%d+),%s*(%d+),%s*(%d+)%)") do
print("RGB values found:", match)
end
Alrgiht could you try again and give me the results in case doesnāt work?
good to hear i updated the code again could you try ? give me the output in-case
local function applyRichTextColors(richText, frameWithImageLabels)
local function parseAndApply()
local plainText = ""
local colorSegments = {}
local currentIndex = 1
local cleanText = richText:gsub("<[^>]+>", "")
while currentIndex <= #richText do
local tagStart, tagEnd = richText:find("<font%s+color=\"rgb%((%d+),%s*(%d+),%s*(%d+)%)\">", currentIndex)
if not tagStart then
plainText = plainText .. richText:sub(currentIndex):gsub("</?font>", ""):gsub("[<>]", "")
break
end
plainText = plainText .. richText:sub(currentIndex, tagStart - 1):gsub("</?font>", ""):gsub("[<>]", "")
local r, g, b = richText:match("(%d+),%s*(%d+),%s*(%d+)", tagStart)
local color = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
local contentStart = tagEnd + 1
local contentEnd = richText:find("</font>", contentStart, true)
if not contentEnd then
contentEnd = #richText
else
contentEnd = contentEnd - 1
end
local content = richText:sub(contentStart, contentEnd):gsub("</?font>", ""):gsub("[<>]", "")
table.insert(colorSegments, {
startPosition = #plainText + 1,
endPosition = #plainText + #content,
color = color
})
plainText = plainText .. content
currentIndex = contentEnd + 7
end
return cleanText, plainText, colorSegments
end
local cleanText, plainText, colorSegments = parseAndApply()
if frameWithImageLabels then
for _, segment in ipairs(colorSegments) do
for i = segment.startPosition, segment.endPosition do
local frame = frameWithImageLabels:FindFirstChild(tostring(i))
if frame and frame:IsA("Frame") then
local imageLabel = frame:FindFirstChildOfClass("ImageLabel")
if imageLabel then
imageLabel.ImageColor3 = segment.color
print("Applied color", segment.color, "to letter at position", i, "frame", frame.Name)
end
end
end
end
end
print("Original rich text:", richText)
print("Clean text:", cleanText)
print("Plain text:", plainText)
print("Number of color segments:", #colorSegments)
assert(#cleanText == #plainText, "Clean text and plain text lengths don't match")
assert(cleanText == plainText, "Clean text and plain text content don't match")
for i, segment in ipairs(colorSegments) do
print("Segment", i, "Start:", segment.startPosition, "End:", segment.endPosition, "Color:", segment.color)
end
return plainText, cleanText, colorSegments
end
It works flawlessly now, thank you SO MUCH!
Hereās what it printed when I ran it on the first piece of dialog
and here it is in action
There is one flaw with it, which is that it doesnāt support formatting within formatting, but itās easy to work around, I just had to add some conditional statements to my formatting code to make sure thereās not formatting within formatting (for example formatting on shork then formatting on the s, and the formatting for the s also wraps around the formatting for the shork), solved it by checking for one or the other instead of formatting both shork and shorks, very easy.
Once again thanks for the code, it works well enough for what Iāll use it for! Iām mainly just mentioning this detail for anyone else who might find this post useful in the future.
I also did some more work on my dialog system and Iām really proud of how itās turning out
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.