Script to remove HTML tags from String?
hydramystic
10 Jun 2021, 02:44Hi, I've been trying to create a pop-up menu using the show menu command but it seems like it can't process text.
I have a List and the entries look like this:
<img src='" + GetFileURL("example.png") + "' /> <font color='red'>Text Example</font>
It works with Print or the ShowMenu function but not with the show menu command.
I can't change the entries text itself so I need a way to strip the HTML tags from it and then pass it to another list or maybe something else... any ideas?
K.V.
10 Jun 2021, 14:33Hello.
Hi, I've been trying to create a pop-up menu using the
show menu
[commandscript] but it seems like it can't process text.
That menu only displays a raw string; in other words, it doesn't translate the HTML code.
It works with
ShowMenu
function but not with theshow menu
[commandscript].
This is because both of these add your HTML code to the web page, where it is displayed as you would expect. (Meaning the HTML is translated when properly added to the web page.)
I can't change the entries text itself
Why not?
Where do these text entries come from?
so I need a way to strip the HTML tags from it and then pass it to another list or maybe something else... any ideas?
EDIT
This function's code has been updated once since originally posted. I forgot to do subtract start
from end
and then add 1, because the third parameter in Mid
is for the character count from the second parameter, not the actual position of the end character in the string.
<function name="TagStripper" parameters="str" type="string"><![CDATA[
str = Trim(str)
start = Instr (str, "<")
end = Instr (str, ">")
tag = ""
if (start > 0 and end > 0) {
tag = Mid (str, start, end - start + 1)
}
str = Replace (str, tag, "")
start = Instr (str, "<")
end = Instr (str, ">")
if (start > 0 and end > 0) {
str = TagStripper (str)
}
return (str)
]]></function>
Making up stuff to try to emulate what I am guessing you might probably have going on in your code (without really knowing very much):
// You don't need this part.
s = "<img src='" + GetFileURL("example.png") + "' /> <font color='red'>Text Example</font>"
s2 = "<img src='" + GetFileURL("example2.png") + "' /> <font color='green'>Text Example 2</font>"
s3 = "<img src='" + GetFileURL("example3.png") + "' /> <font color='blue'>Text Example 3</font>"
strings = NewStringList()
list add (strings, s)
list add (strings, s2)
list add (strings, s3)
// Now the fake environment has been created.
// The rest of the code is all that should be required (replacing "strings" in the foreach with the real list).
choices = NewStringList()
foreach (str, strings) {
list add (choices, TagStripper(str))
}
show menu ("Whatever question?", choices, false) {
msg (result)
}
K.V.
10 Jun 2021, 14:41PS
Use my code at your own risk!
Best case scenario: everything will work.
Worst case scenario: your computer will spontaneously combust!
EDIT
This is the test game I created to test things:
<!--Saved by Quest 5.8.7753.35184-->
<asl version="580">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="In-room Description Example">
<gameid>232ffbf9-b40a-44b3-88c5-5f8bed042232</gameid>
<version>1.2</version>
<firstpublished>2021</firstpublished>
<appendobjectdescription />
</game>
<object name="room">
<inherit name="editor_room" />
<isroom />
<enter type="script"><![CDATA[
// You don't need this part.
s = "<img src='" + GetFileURL("example.png") + "' /> <font color='red'>Text Example</font>"
s2 = "<img src='" + GetFileURL("example2.png") + "' /> <font color='green'>Text Example 2</font>"
s3 = "<img src='" + GetFileURL("example3.png") + "' /> <font color='blue'>Text Example 3</font>"
strings = NewStringList()
list add (strings, s)
list add (strings, s2)
list add (strings, s3)
// Now the fake environment has been created.
// The rest of the code is all that should be required (replacing "strings" in the foreach with the real list).
choices = NewStringList()
foreach (str, strings) {
list add (choices, TagStripper(str))
}
show menu ("Whatever question?", choices, false) {
msg (result)
}
]]></enter>
<description type="string"></description>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="frob">
<inherit name="editor_object" />
<inroomdescription><![CDATA[{if frob.scenery: <br/>WOW! There is a {object:frob} here!}]]></inroomdescription>
<scenery />
<take />
</object>
</object>
<function name="TagStripper" parameters="str" type="string"><![CDATA[
str = Trim(str)
start = Instr (str, "<")
end = Instr (str, ">")
tag = ""
if (start > 0 and end > 0) {
tag = Mid (str, start, end - start + 1)
}
str = Replace (str, tag, "")
start = Instr (str, "<")
end = Instr (str, ">")
if (start > 0 and end > 0) {
str = TagStripper (str)
}
return (str)
]]></function>
</asl>
K.V.
10 Jun 2021, 14:47Oh, and I forgot to post this bit:
Trim
https://docs.textadventures.co.uk/quest/functions/string/trim.html
Instr
https://docs.textadventures.co.uk/quest/functions/string/instr.html
Mid
https://docs.textadventures.co.uk/quest/functions/string/mid.html
Replace
https://docs.textadventures.co.uk/quest/functions/string/replace.html
NewStringList
https://docs.textadventures.co.uk/quest/functions/newstringlist.html
foreach
https://docs.textadventures.co.uk/quest/scripts/foreach.html
list add
https://docs.textadventures.co.uk/quest/scripts/list_add.html
show menu
https://docs.textadventures.co.uk/quest/scripts/show_menu.html
mrangel
10 Jun 2021, 15:27EDIT: Fixed a silly error in the code snippet
Use my code at your own risk!
You put Mid (str, start, end)
instead of Mid (str, start, 1+end-start)
. The 3rd parameter to Mid
is the length of the string to extract, not the end position.
However, it would be more efficient to replace:
tag = ""
if (start > 0 and end > 0) {
tag = Mid (str, start, end)
}
str = Replace (str, tag, "")
with:
str = Left (str, start-1) + Mid (str, end+1)
sticking the bit before the <
and the bit after the >
together, rather than finding the whole tag and then doing another bunch of string comparisons to remove it.
You probably also want to check for the case where there is a >
before the <
; which in your script would remove part of the tag, and with my modified code would duplicate the area in between them.
A more efficient version of this would be:
<function name="TagStripper" parameters="str" type="string"><![CDATA[
str = Trim(str)
while (true) {
start = Instr (str, "<") - 1
end = Instr (start + 1, str, ">") + 1
if (start = -1 or end = 1) {
return (str)
}
str = RTrim (Left (str, start)) + " " + LTrim (Mid (str, end))
}
]]></function>
K.V.
10 Jun 2021, 15:58I had too many tabs open, each with a different forum thread, and I failed to refresh this one before updating my function, which I found had problems after a little more testing. :)
Now, I see that I could have saved myself 10 minutes of troubleshooting had I refreshed this page first and seen mrangel's post. (hehehe)
@mrangel
I tried your version of TagStripper
, and I get:
Error running script: Error compiling expression 'Instr (str, ">", start + 1) + 1': FunctionCallElement: Could find not function 'Instr(String, String, Int32)'
Error running script: Error compiling expression 'Instr (str, ">", start + 1) + 1': FunctionCallElement: Could find not function 'Instr(String, String, Int32)'
Error running script: Error compiling expression 'Instr (str, ">", start + 1) + 1': FunctionCallElement: Could find not function 'Instr(String, String, Int32)'
Error running script: Value cannot be null.Parameter name: key
I agree with every point made about my code. Even after fixing the issue with the third parameter in Mid
, my code is still inefficient and only really tested with the strings I posted in the examples.
So, I want to use mrangel's, but I can't figure out what's throwing the error.
mrangel
10 Jun 2021, 16:10Sorry, I was expecting it to be the same as in other languages. Usually if you have one optional parameter to a function it goes at the end, but it seems Quest's Instr
puts it at the beginning.
Fixed :)
hydramystic
10 Jun 2021, 20:07Thanks a lot for the responses, this is exactly what I needed.
Sorry for not explaining properly, I couldn't find an easy way to do it with my poor English skills haha
I'm still getting an error with mrangel's version tho
Error running script: Error evaluating expression 'Instr (start + 1, str, ">") + 1': The argument 'Start' must be greater than zero.
Error running script: Error evaluating expression 'Instr (start + 1, str, ">") + 1': The argument 'Start' must be greater than zero.
Error running script: Error evaluating expression 'Instr (start + 1, str, ">") + 1': The argument 'Start' must be greater than zero.
Error running script: Value cannot be null. Parameter name: key
mrangel
10 Jun 2021, 21:24Sorry, my fault for answering on my phone without checking.
<function name="TagStripper" parameters="str" type="string"><![CDATA[
str = Trim(str)
while (true) {
start = Instr (str, "<") - 1
if (start < 0) {
return (str)
}
end = Instr (start + 1, str, ">") + 1
if (end = 1) {
return (str)
}
str = RTrim (Left (str, start)) + " " + LTrim (Mid (str, end))
}
]]></function>