Problems with escaping < > characters in plugins

Posted by Eurotool on Mon 19 Dec 2022 03:32 AM — 5 posts, 15,645 views.

#0
Hello, I am attempting to use the Convert_Word plugin described here: http://www.gammon.com.au/forum/?id=8747&reply=4#reply4

My objective is to remove the "<Public> " statements that initiate chat lines in the public channel of a MUD.

Public = "",
on line 23 works fine, but does not remove the angle brackets.

I have tried the following, with no success:
<Public> = "",
-> Line 31: Elements terminated out of sequence, expected </Public>, got </script> (Cannot load)
\<Public\> = "",
-> Line 23: Attribute name must start with letter or underscore, but starts with "\" (Cannot load)
"<Public>" = "",
-> Line 31: Elements terminated out of sequence, expected </Public>, got </script> (Cannot load)
"\<Public\>" = "",
-> Line 23: Attribute name must start with letter or underscore, but starts with "\" (Cannot load)
&lt;Public&gt; = "",
-> [string "Plugin"]:2: unexpected symbol near '<'
\&lt\;Public\&gt\;
-> Line 31: No closing ";" in XML entity argument "&lt" (Cannot load)
-> [string "Plugin"]:2: unexpected symbol near '\'
\&lt;Public\&gt; = "",

<![CDATA[<Public>]]> = "",
-> [string "Plugin"]:2: unexpected symbol near '<'
<![CDATA[\<Public\>]]> = "",
-> [string "Plugin"]:2: unexpected symbol near '\'
<![CDATA[&lt;Public&gt;]]> = "",
-> [string "Plugin"]:2: unexpected symbol near '&'
<![CDATA[\&lt;Public\&gt;]]> = "",
-> [string "Plugin"]:2: unexpected symbol near '\'

I am out of options, not sure what to try next.
Australia Forum Administrator #1

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Convert_Word"
   author="Nick Gammon"
   id="9c0ed228bdb4a71c77e85ce0"
   language="Lua"
   purpose="Converts one word to another"
   date_written="2008-06-29"
   requires="4.00"
   version="1.0"
   >

</plugin>

<!--  Script  -->

<script>

conversions = {
  ["&lt;Public&gt;"] = "",
  foo = "bar",
  dog = "cat",
  horse = "donkey",

  -- add more here
  }
  
function OnPluginPacketReceived (s)
  return (string.gsub (s, "%a+", conversions))
end -- function OnPluginPacketReceived
</script>

</muclient>


Your problem is that in a Lua table, non-identifier type keys (like "<public>") have to be put into square brackets. And since it is a string you also quote it.

Then, since the plugin is in an XML file the < and > symbols have to be &lt; and &gt;.

Another approach, which saves you converting < and > symbols is to use CDATA, like this:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Convert_Word"
   author="Nick Gammon"
   id="9c0ed228bdb4a71c77e85ce0"
   language="Lua"
   purpose="Converts one word to another"
   date_written="2008-06-29"
   requires="4.00"
   version="1.0"
   >

</plugin>

<!--  Script  -->

<script>

<![CDATA[

conversions = {
  ["<Public>"] = "",
  foo = "bar",
  dog = "cat",
  horse = "donkey",

  -- add more here
  }
  
function OnPluginPacketReceived (s)
  return (string.gsub (s, "%a+", conversions))
end -- function OnPluginPacketReceived

]]>

</script>

</muclient>
Amended on Mon 19 Dec 2022 04:44 AM by Nick Gammon
Australia Forum Administrator #2
You tried a lot of stuff, you must almost have hit upon the correction solution yourself. :)

See here for more talk about tables: http://www.gammon.com.au/forum/?id=6036
#3
Unfortunately, nothing inside the brackets seem to be working.

["bar baz"] = "",

in both scripts does nothing when encountering the string -- so it's not just about the <>.
Australia Forum Administrator #4
OK, the replacement function is this:


  return (string.gsub (s, "%a+", conversions))


That is searching for an alphabetic string. If you wanted other stuff in there, you would need to make a set, like this:


  return (string.gsub (s, "[%a<> ]+", conversions))


That will match one or more of letters, less-than signs, greater-than signs, or a space.

That's if the whole thing is inside CDATA, otherwise replace < with &lt; and > with &gt;

Or maybe:


  return (string.gsub (s, "<?[%a ]+>?", conversions))


That would constrain the matches to the < optionally being at the start, and the > optionally being at the end.