<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss">
  <channel>
    <title>Recent posts - iNTERFACEWARE Help Center</title>
    <description>The most recent 20 listings and reviews in Code Repository</description>
    <link>https://help.interfaceware.com/code/feed</link>
    <lastBuildDate>Mon, 04 May 2026 12:37:28 +0000</lastBuildDate>
    <atom:link href="https://help.interfaceware.com/code/feed.xml" rel="self" type="application/rss+xml" />
 
    <item>
      <title>store2.lua</title>
      <description><![CDATA[<p><a href="https://github.com/interfaceware/iguana-tools/blob/master/shared/store2.lua" rel="nofollow">https://github.com/interfaceware/iguana-tools/blob/master/shared/store2.lua</a></p>
]]></description>
      <content:encoded><![CDATA[<p><a href="https://github.com/interfaceware/iguana-tools/blob/master/shared/store2.lua" rel="nofollow">https://github.com/interfaceware/iguana-tools/blob/master/shared/store2.lua</a></p>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/store2-lua</link>
      <guid>https://help.interfaceware.com/code/details/store2-lua</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 15 Feb 2016 23:21:00 +0000</pubDate>
    </item>
 
    <item>
      <title>hl7.zsegment.lua</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- Generic Z segment parser
-- http://help.interfaceware.com/kb/generic-z-segment-parser

hl7.zsegment = {}

local function ParseDelim(Data, DelimArray, Index, Compact)
   if Index == 0 then
      return Data
   end
   local Children = Data:split(DelimArray[Index])
   local Result = {}
   if #Children &gt; 1  then
      for i =1, #Children do
         Result[i] = ParseDelim(Children[i], DelimArray, Index-1, Compact)   
      end
   else
      if Compact then
         Result = ParseDelim(Data, DelimArray, Index-1, Compact)
      else
         Result[1] = ParseDelim(Data, DelimArray, Index-1, Compact)
      end
   end
   
   return Result
end

local function AddZSegment(List, Segment, Compact)
   local Fields = Segment:split('|')
   local SegmentName = Fields[1]
   for i=2, #Fields do 
      Fields[i-1] = ParseDelim(Fields[i], {'&amp;','^','~'}, 3, Compact)
   end
   if not List[SegmentName] then
      List[SegmentName] = {} 
   end
   List[SegmentName][#List[SegmentName]+1] = Fields
end

function hl7.zsegment.parse(T)
   local Segments = T.data:split("\r")
   local ZSegments = {}
   for i = 1,#Segments do
      if Segments[i]:sub(1,1) == 'Z' then
         AddZSegment(ZSegments, Segments[i], T.compact)
      end
   end
   return ZSegments
end

local HELP_DEF=[[{
   "Desc": "Parses an HL7/EDI/X12 message and extracts Z segments which it returns in a Lua table. 
   &lt;p&gt;This module gives us two parsing options: \"Expanded\" (compact=false) which pushes all the
   data down to the leaf level, \"Compact\" (compact=true) where we keep the data at a higher 
   level (this assumes there are no sub fields and repeating fields) 
   &lt;p&gt;Using the \"Expanded\" mode is safer as it gives consistent results for messages with/without
   sub-fields and repeating fields. \"Compact\" mode however will fail (give different results) for
   messages with/without sub-fields and repeating fields. &lt;p&gt;If you have optional sub-fields or 
   repeats then you need to use the \"Expanded\" mode.",
   "Returns": [
      {
         "Desc": "A lua table with the Z segments parsed out &lt;u&gt;table&lt;/u&gt;."
      }
   ],
   "SummaryLine": "Parses an HL7/EDI/X12 message for Z-zegments without a vmd.",
   "SeeAlso": [
      {
         "Title": "hl7.zsegment.lua - in our code repository.",
         "Link": "http://help.interfaceware.com/code/details/hl7-zsegment-lua"
      },
      {
         "Title": "Z Segment Parser.",
         "Link": "http://help.interfaceware.com/v6/z-segment-parser"
      }
   ],
   "Title": "hl7.zsegment.parse",
   "Usage": "hl7.zsegment.parse{data=&#060;value&#062;, compact=&#060;true|false&#062;}",
   "Parameters": [
      {
         "data": {
            "Desc": "A message to be parsed &lt;u&gt;string&lt;/u&gt;. "
         }
      },
      {
         "compact": {
            "Desc": "If &lt;b&gt;false&lt;/b&gt; then the parsed tree will push all data to the lowest level &lt;u&gt;boolean&lt;/u&gt;. "
         }
      }
   ],
   "Examples": [
      "&lt;pre&gt;local Msg = hl7.zsegment.parse{data=Data, compact=false}&lt;/pre&gt;"
   ],
   "ParameterTable": true
}]]

help.set{input_function=hl7.zsegment.parse, help_data=json.parse{data=HELP_DEF}}</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- Generic Z segment parser
-- http://help.interfaceware.com/kb/generic-z-segment-parser

hl7.zsegment = {}

local function ParseDelim(Data, DelimArray, Index, Compact)
   if Index == 0 then
      return Data
   end
   local Children = Data:split(DelimArray[Index])
   local Result = {}
   if #Children &gt; 1  then
      for i =1, #Children do
         Result[i] = ParseDelim(Children[i], DelimArray, Index-1, Compact)   
      end
   else
      if Compact then
         Result = ParseDelim(Data, DelimArray, Index-1, Compact)
      else
         Result[1] = ParseDelim(Data, DelimArray, Index-1, Compact)
      end
   end
   
   return Result
end

local function AddZSegment(List, Segment, Compact)
   local Fields = Segment:split('|')
   local SegmentName = Fields[1]
   for i=2, #Fields do 
      Fields[i-1] = ParseDelim(Fields[i], {'&amp;','^','~'}, 3, Compact)
   end
   if not List[SegmentName] then
      List[SegmentName] = {} 
   end
   List[SegmentName][#List[SegmentName]+1] = Fields
end

function hl7.zsegment.parse(T)
   local Segments = T.data:split("\r")
   local ZSegments = {}
   for i = 1,#Segments do
      if Segments[i]:sub(1,1) == 'Z' then
         AddZSegment(ZSegments, Segments[i], T.compact)
      end
   end
   return ZSegments
end

local HELP_DEF=[[{
   "Desc": "Parses an HL7/EDI/X12 message and extracts Z segments which it returns in a Lua table. 
   &lt;p&gt;This module gives us two parsing options: \"Expanded\" (compact=false) which pushes all the
   data down to the leaf level, \"Compact\" (compact=true) where we keep the data at a higher 
   level (this assumes there are no sub fields and repeating fields) 
   &lt;p&gt;Using the \"Expanded\" mode is safer as it gives consistent results for messages with/without
   sub-fields and repeating fields. \"Compact\" mode however will fail (give different results) for
   messages with/without sub-fields and repeating fields. &lt;p&gt;If you have optional sub-fields or 
   repeats then you need to use the \"Expanded\" mode.",
   "Returns": [
      {
         "Desc": "A lua table with the Z segments parsed out &lt;u&gt;table&lt;/u&gt;."
      }
   ],
   "SummaryLine": "Parses an HL7/EDI/X12 message for Z-zegments without a vmd.",
   "SeeAlso": [
      {
         "Title": "hl7.zsegment.lua - in our code repository.",
         "Link": "http://help.interfaceware.com/code/details/hl7-zsegment-lua"
      },
      {
         "Title": "Z Segment Parser.",
         "Link": "http://help.interfaceware.com/v6/z-segment-parser"
      }
   ],
   "Title": "hl7.zsegment.parse",
   "Usage": "hl7.zsegment.parse{data=&#060;value&#062;, compact=&#060;true|false&#062;}",
   "Parameters": [
      {
         "data": {
            "Desc": "A message to be parsed &lt;u&gt;string&lt;/u&gt;. "
         }
      },
      {
         "compact": {
            "Desc": "If &lt;b&gt;false&lt;/b&gt; then the parsed tree will push all data to the lowest level &lt;u&gt;boolean&lt;/u&gt;. "
         }
      }
   ],
   "Examples": [
      "&lt;pre&gt;local Msg = hl7.zsegment.parse{data=Data, compact=false}&lt;/pre&gt;"
   ],
   "ParameterTable": true
}]]

help.set{input_function=hl7.zsegment.parse, help_data=json.parse{data=HELP_DEF}}</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/hl7-zsegment-lua</link>
      <guid>https://help.interfaceware.com/code/details/hl7-zsegment-lua</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Fri, 25 Dec 2015 13:11:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Create a Generic ACK</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">   local R = ack.generate(Msg)
   ack.send(R)
</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">   local R = ack.generate(Msg)
   ack.send(R)
</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/create-a-generic-ack</link>
      <guid>https://help.interfaceware.com/code/details/create-a-generic-ack</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 18 Aug 2015 15:10:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Dehydrate (serialize) as XML</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">local Vmd = 'example/demo.vmd'

function main(Data)
   local H = hl7.parse{vmd=Vmd,data=Data}
   local D = MyTemplate()

   D.data.ssn = H.PID[19]
   D.data.dob = H.PID[7][1]
   D.data.ascension_num = H.PID[3][1][1]

   local SerializedXml = D:S()

   D = DehydrateXml(SerializedXml)
   trace(D.data.ssn:nodeValue())
end

function MyTemplate()
   return xml.parse{data="&lt;data ssn='' dob='' ascension_num=''/&gt;"}
end

function DehydrateXml(Xml)
   return xml.parse{data=Xml}
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">local Vmd = 'example/demo.vmd'

function main(Data)
   local H = hl7.parse{vmd=Vmd,data=Data}
   local D = MyTemplate()

   D.data.ssn = H.PID[19]
   D.data.dob = H.PID[7][1]
   D.data.ascension_num = H.PID[3][1][1]

   local SerializedXml = D:S()

   D = DehydrateXml(SerializedXml)
   trace(D.data.ssn:nodeValue())
end

function MyTemplate()
   return xml.parse{data="&lt;data ssn='' dob='' ascension_num=''/&gt;"}
end

function DehydrateXml(Xml)
   return xml.parse{data=Xml}
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/dehydrate-serialize-as-xml</link>
      <guid>https://help.interfaceware.com/code/details/dehydrate-serialize-as-xml</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 18 Aug 2015 12:55:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Dehydrate (serialize) as JSON</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua"> function main(Data)   
  -- serialize data as JSON
   
   -- this is the original JSON data:
   -- "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"
   
   -- JSON data as a Lua table
   local JT = {['int_test']=1.23, ['string_test']='a', ['boolean_test']=true}

   -- serialize the Lua table into JSON
   local JS = json.serialize{data=JT}   
   --&gt; '{ "int_test": 1.230000, "boolean_test": true, "string_test": "a" }'
   -- notice the changed order and added decimal places for int_test
   -- when compared to our original JSON data:
   -- "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"
   
   -- parse the JSON string back to a Lua table for comparison
   local JT = json.parse{data=JS}
   --&gt; {['int_test']=1.230000, ['boolean_test']=true, ['string_test']='a'}
   -- again notice the changed order and added decimal places for int_test
   -- when compared to our original table:
   -- {['int_test']=1.23, ['string_test']='a', ['boolean_test']=true}
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua"> function main(Data)   
  -- serialize data as JSON
   
   -- this is the original JSON data:
   -- "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"
   
   -- JSON data as a Lua table
   local JT = {['int_test']=1.23, ['string_test']='a', ['boolean_test']=true}

   -- serialize the Lua table into JSON
   local JS = json.serialize{data=JT}   
   --&gt; '{ "int_test": 1.230000, "boolean_test": true, "string_test": "a" }'
   -- notice the changed order and added decimal places for int_test
   -- when compared to our original JSON data:
   -- "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"
   
   -- parse the JSON string back to a Lua table for comparison
   local JT = json.parse{data=JS}
   --&gt; {['int_test']=1.230000, ['boolean_test']=true, ['string_test']='a'}
   -- again notice the changed order and added decimal places for int_test
   -- when compared to our original table:
   -- {['int_test']=1.23, ['string_test']='a', ['boolean_test']=true}
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/dehydrate-serialize-as-json</link>
      <guid>https://help.interfaceware.com/code/details/dehydrate-serialize-as-json</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 18 Aug 2015 12:36:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Using a DB with an autoincrementing ID</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">local conn = db.connect{
   api=db.MY_SQL, 
   name='test', 
   user='root', 
   password='', 
   live = true
}
  
-- We assume that:
--  1. The auto ID column is Id
--  2. Mrn is the medical record number - i.e. the external patient ID
function main(Data) 
   local Msg, Name = hl7.parse{vmd='demo-autoinc.vmd', data=Data}
   local T = db.tables{vmd='demo-autoinc.vmd',name=Name}
 
   T = mapPatient(Msg.PID, T)
 
   local Q = conn:query{
      sql="SELECT * FROM Patient WHERE Mrn = '"..T.patient[1].Mrn.."'",
      live=true
   }
   if #Q &gt; 0 then
      trace("Patient exists: "..Q[1].LastName..', '..Q[1].GivenName)
      T.patient[1].Id = Q[1].Id
   else
      trace("Patient is new.")
      T.patient[1]:remove('Id')
   end
   conn:merge{data=T, live=true}
end
 
-- We map Mrn to the Patient ID Number
function mapPatient(PID, t)
   -- map patient ID to Mrn
   t.patient[1].Mrn = tonumber(PID[3][1][1]:nodeValue())
 
   -- map other patient fields
   t.patient[1].LastName      = PID[5][1][1][1]
   t.patient[1].GivenName     = PID[5][1][1][1]
   t.patient[1].Race          = PID[10][1][1]
   t.patient[1].PhoneHome     = PID[13][1][1]
   t.patient[1].PhoneBusiness = PID[14][1][1]
   t.patient[1].Religion      = PID[17][2]
   t.patient[1].MaritalStatus = PID[16][2]
   t.patient[1].Ssn           = PID[19]
   t.patient[1].LicenseNumber = PID[20][1]
   return t
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">local conn = db.connect{
   api=db.MY_SQL, 
   name='test', 
   user='root', 
   password='', 
   live = true
}
  
-- We assume that:
--  1. The auto ID column is Id
--  2. Mrn is the medical record number - i.e. the external patient ID
function main(Data) 
   local Msg, Name = hl7.parse{vmd='demo-autoinc.vmd', data=Data}
   local T = db.tables{vmd='demo-autoinc.vmd',name=Name}
 
   T = mapPatient(Msg.PID, T)
 
   local Q = conn:query{
      sql="SELECT * FROM Patient WHERE Mrn = '"..T.patient[1].Mrn.."'",
      live=true
   }
   if #Q &gt; 0 then
      trace("Patient exists: "..Q[1].LastName..', '..Q[1].GivenName)
      T.patient[1].Id = Q[1].Id
   else
      trace("Patient is new.")
      T.patient[1]:remove('Id')
   end
   conn:merge{data=T, live=true}
end
 
-- We map Mrn to the Patient ID Number
function mapPatient(PID, t)
   -- map patient ID to Mrn
   t.patient[1].Mrn = tonumber(PID[3][1][1]:nodeValue())
 
   -- map other patient fields
   t.patient[1].LastName      = PID[5][1][1][1]
   t.patient[1].GivenName     = PID[5][1][1][1]
   t.patient[1].Race          = PID[10][1][1]
   t.patient[1].PhoneHome     = PID[13][1][1]
   t.patient[1].PhoneBusiness = PID[14][1][1]
   t.patient[1].Religion      = PID[17][2]
   t.patient[1].MaritalStatus = PID[16][2]
   t.patient[1].Ssn           = PID[19]
   t.patient[1].LicenseNumber = PID[20][1]
   return t
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/using-a-db-with-an-autoincrementing-id</link>
      <guid>https://help.interfaceware.com/code/details/using-a-db-with-an-autoincrementing-id</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 17 Aug 2015 15:35:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Escape a SQL query string</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- create connections once when channel starts

local conn_SQLite = db.connect{
   api=db.SQLITE, 
   name='Test', 
   user='root',         -- not required - ignored by SQLite
   password='password', -- not required - ignored by SQLite
   live = true
}

local conn_MySQL = db.connect{
   api=db.SQL_SERVER, 
   name='Test', 
   user='root', 
   password='password', 
   live = true
}

function main()
   local V1, V2
   V1=conn_SQLite:quote("Data with ' character")
   V1=conn_SQLite:quote('Data with " character')

   V2=conn_MySQL:quote("Data with ' character")
   V2=conn_MySQL:quote('Data with " character')

   local surname = "Smith"   
   -- CORRECT way to create the query string
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ]]..conn_SQLite:quote(surname))
   -- INCORRECT no escaping works for "Smith" but not for "O'Toole" (below)
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..surname.."'")
   -- INCORRECT way to create the query string
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..conn_SQLite:quote(surname).."'")
   
   local surname = "O'Toole"   
   -- "O'Toole" query "manually" escaped for reference
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = 'O''Toole']]) -- SQLite
   conn_MySQL:query([[SELECT * FROM Patient WHERE LastName = 'O\'Toole']])  -- MySQL
   -- CORRECT
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ]]..conn_SQLite:quote(surname))
   -- INCORRECT no escaping worked for "Smith" but not for "O'Toole" (try it)
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..surname.."'")
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- create connections once when channel starts

local conn_SQLite = db.connect{
   api=db.SQLITE, 
   name='Test', 
   user='root',         -- not required - ignored by SQLite
   password='password', -- not required - ignored by SQLite
   live = true
}

local conn_MySQL = db.connect{
   api=db.SQL_SERVER, 
   name='Test', 
   user='root', 
   password='password', 
   live = true
}

function main()
   local V1, V2
   V1=conn_SQLite:quote("Data with ' character")
   V1=conn_SQLite:quote('Data with " character')

   V2=conn_MySQL:quote("Data with ' character")
   V2=conn_MySQL:quote('Data with " character')

   local surname = "Smith"   
   -- CORRECT way to create the query string
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ]]..conn_SQLite:quote(surname))
   -- INCORRECT no escaping works for "Smith" but not for "O'Toole" (below)
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..surname.."'")
   -- INCORRECT way to create the query string
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..conn_SQLite:quote(surname).."'")
   
   local surname = "O'Toole"   
   -- "O'Toole" query "manually" escaped for reference
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = 'O''Toole']]) -- SQLite
   conn_MySQL:query([[SELECT * FROM Patient WHERE LastName = 'O\'Toole']])  -- MySQL
   -- CORRECT
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ]]..conn_SQLite:quote(surname))
   -- INCORRECT no escaping worked for "Smith" but not for "O'Toole" (try it)
   conn_SQLite:query([[SELECT * FROM Patient WHERE LastName = ']]..surname.."'")
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/escape-an-sql-query-string</link>
      <guid>https://help.interfaceware.com/code/details/escape-an-sql-query-string</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 17 Aug 2015 15:17:00 +0000</pubDate>
    </item>
 
    <item>
      <title>hex.lua (pre 5.0.5)</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">hex = {}

local HexToDec={
 ['0'] = 0,  ['1'] = 1,  ['2'] = 2,  ['3'] = 3,
 ['4'] = 4,  ['5'] = 5,  ['6'] = 6,  ['7'] = 7,
 ['8'] = 8,  ['9'] = 9,  ['A'] = 10, ['B'] = 11,
 ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15,
 ['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13,
 ['E'] = 14, ['F'] = 15
}

local DecToHex='0123456789ABCDEF'

local function char(S, i)  
   local B1 = HexToDec[S:sub(i,i)]
   local B2 = HexToDec[S:sub(i+1,i+1)]
   local C = B1 *16 + B2
   return C
end

-- Public interface
function hex.dec(S)
   print(#S)
   local D = S:gsub("%s", '')
   D = D:gsub("\n", '')
   print(#D)

   local T = {}
   local i = 1
   local c = 1
   while (i &lt; #D ) do
      local C = char(D,i)
      i = i + 2
      T[c] = string.char(C)
      c = c + 1
   end
   return table.concat(T)
end

function hex.enc(S)
   local T = {}
   local j = 1
   local B
   for i=1, #S do
      B = S:byte(i) / 16 + 1
      T[j] = DecToHex:sub(B,B)
      B = S:byte(i) % 16 + 1
      T[j+1] = DecToHex:sub(B,B)
      j = j + 2
   end
   return table.concat(T)
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">hex = {}

local HexToDec={
 ['0'] = 0,  ['1'] = 1,  ['2'] = 2,  ['3'] = 3,
 ['4'] = 4,  ['5'] = 5,  ['6'] = 6,  ['7'] = 7,
 ['8'] = 8,  ['9'] = 9,  ['A'] = 10, ['B'] = 11,
 ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15,
 ['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13,
 ['E'] = 14, ['F'] = 15
}

local DecToHex='0123456789ABCDEF'

local function char(S, i)  
   local B1 = HexToDec[S:sub(i,i)]
   local B2 = HexToDec[S:sub(i+1,i+1)]
   local C = B1 *16 + B2
   return C
end

-- Public interface
function hex.dec(S)
   print(#S)
   local D = S:gsub("%s", '')
   D = D:gsub("\n", '')
   print(#D)

   local T = {}
   local i = 1
   local c = 1
   while (i &lt; #D ) do
      local C = char(D,i)
      i = i + 2
      T[c] = string.char(C)
      c = c + 1
   end
   return table.concat(T)
end

function hex.enc(S)
   local T = {}
   local j = 1
   local B
   for i=1, #S do
      B = S:byte(i) / 16 + 1
      T[j] = DecToHex:sub(B,B)
      B = S:byte(i) % 16 + 1
      T[j+1] = DecToHex:sub(B,B)
      j = j + 2
   end
   return table.concat(T)
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/hex-lua-pre-5-0-5</link>
      <guid>https://help.interfaceware.com/code/details/hex-lua-pre-5-0-5</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Wed, 12 Aug 2015 19:34:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Working with XML</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">myXML = [[
&lt;myXml&gt;
   &lt;elem1&gt;
      &lt;sub1&gt;&lt;/sub1&gt;
   &lt;/elem1&gt;
   &lt;elem2&gt;&lt;/elem2&gt;
   &lt;elem3&gt;&lt;/elem3&gt;
   &lt;elem4&gt;&lt;/elem4&gt;
   &lt;elem5&gt;&lt;/elem5&gt;
   &lt;elem6&gt;
      &lt;sub1&gt;valuable data&lt;/sub1&gt;
      &lt;sub2&gt;more valuable data&lt;/sub2&gt;
   &lt;/elem6&gt;
&lt;/myXml&gt;
]]

function main()
   local X = xml.parse(myXML)
     
   --------------------------------------------
   -- Use append to add a TEXT field
   --------------------------------------------

   -- RECOMMENDED 
   X.myXml.elem1:append(xml.TEXT, 'encodes &lt;&amp;&gt; correctly')
   
   -- or can create an empty TEXT field and assign a value later
   X.myXml.elem2:append(xml.TEXT, '')
   X.myXml.elem2[1] = 'encodes &lt;&amp;&gt; correctly'
   
   -- NOT RECOMMENDED 
   --  - use setInner() to set the TEXT value
   --  - works because setInner() does escaping when 
   --    applied to an XML TEXT field
   -- ISSUE: you can accidentally apply it to an ELEMENT
   --        and then it will "work sometimes" see below:
   --        "Incorrect use of setInner() to add a TEXT field" 
   X.myXml.elem3:append(xml.TEXT, '')
   -- apply setInner() to the TEXT field escapes correctly
   X.myXml.elem3[1]:setInner('encodes &lt;&amp;&gt; correctly')  

   -------------------------------------------------------------
   -- Incorrect use of setInner() to add a TEXT field
   -------------------------------------------------------------
   -- NOTE: this is a easy mistake to make (see point XXX below)
   -------------------------------------------------------------

   -- THIS DOES NOT WORK!
   -- FAILS BECAUSE: setInner() parses XML when loading an ELEMENT
   -- ISSUE: fails when you use XML special characters &lt;&amp;&gt;

   -- plain text parses successfully - SEEMS to work
   X.myXml.elem4:setInner('DECEPTIVE: works with no special characters')

   -- until you add special characters - then the XML parse fails
   -- uncommenting the line below will produce an ERROR
   --X.myXml.elem4:setInner('fails when you add &lt;&amp;&gt;') 

   ---------------------------------------
   -- How to update an existing text field
   ---------------------------------------
   
   -- it is simple find and update an existing TEXT field
   local x = X.myXml.elem1
   for i=1,#x do
      if x[i]:nodeType() == 'text' then
         x[i] = x[i]..' - and I changed the text'
      end
   end
  
   ------------------------------------------------------------
   -- Correct use of setInner() to set an ELEMENT field
   ------------------------------------------------------------
   -- NOTE: this is the **only** recommended use of setInnner()
   ------------------------------------------------------------

   -- add sub elements to elem6
   X.myXml.elem5:setInner('&lt;sub1&gt;&lt;/sub1&gt;&lt;sub2&gt;&lt;/sub2&gt;')
   
   -- WARNING: setInner() will overwrite all data in the ELEMENT
   -- be careful in case this is NOT what you want...
   X.myXml.elem6:setInner('OOPs overwrote valuable data...')
   trace(X:S())
   
   --------------------------------------------------------------
   -- Using append() or setInner() to create multiple TEXT fields
   --------------------------------------------------------------
   -- NOTE: both methods are valid, using setInner() is a bit 
   --       more concise
   --------------------------------------------------------------
   -- NOTE: creating 3 ELEMENTS each with a TEXT sub-field
   --       saves 5 lines of codes, the more ELEMENTS
   --       the more lines of code you save
   --------------------------------------------------------------
    
   -- ###### first we do "long-hand" using append() ######
   
   -- first we add a new elem7 with append
   X.myXml:append(xml.ELEMENT, 'elem7')
   local x = X.myXml.elem7
   -- then we create three ELEMENT sub-fields with append
   x:append(xml.ELEMENT, 'sub1')
   x:append(xml.ELEMENT, 'sub2')
   x:append(xml.ELEMENT, 'sub3') 
   -- then we create a TEXT an empty TEXT field in each ELEMENT
   x.sub1:append(xml.TEXT, '')
   x.sub2:append(xml.TEXT, '')
   x.sub3:append(xml.TEXT, '')   
   trace(x)
   -- then we can assign values later as we need to
   for i=1,#x do
      x[i][1] = 'hello '..i
   end   
   trace(x)
   
   -- ###### now the shorter way using setInner () ######
   
    -- first we add a new elem8 with append
   X.myXml:append(xml.ELEMENT, 'elem8')
   x = X.myXml.elem8
   -- then we create three ELEMENT sub-fields with append
   -- the placeholder "#" symbols create the TEXT sub fields
   x:setInner([[&lt;sub1&gt;#&lt;/sub1&gt;&lt;sub2&gt;#&lt;/sub2&gt;&lt;sub3&gt;#&lt;/sub3&gt;]])
   trace(x)
   -- then we can assign values later as we need to
   for i=1,#x do
      x[i][1] = 'hello '..i
   end   
   -- or even make the text fields empty to directly mimic
   -- the behaviour of the "append() code" above
   for i=1,#x do
      x[i][1] = ''
   end      
   trace(x)
   
   -- NOTE: there is no way to directly create empty TEXT fields using setInner()
   -- removing the "#" symbols = empty ELEMENTS (no TEXT sub fields)
   x:setInner([[&lt;sub1&gt;&lt;/sub1&gt;&lt;sub2&gt;&lt;/sub2&gt;&lt;sub3&gt;&lt;/sub3&gt;]])
   trace(x)
   -- if we attempt to assign values directly now it will fail
   
   -- WARNING! this is when/where we might tempted to wrongly use setInner()
   -- to create our TEXT subfields DO NOT DO IT!!! (see point XXX above)
   for i=1,#x do
      x[i]:setInner('UNSAFE: will fail with XML special characters')
      --x[i]:setInner('this will fail &lt;&amp;&gt; try it!')
   end   
  
   ----------------------------------------------
   -- Adding other fields is very similar to TEXT
   ----------------------------------------------

   -- add a CDATA
   X.myXml.elem1:append(xml.CDATA, 'CDATA does not encode &lt;&amp;&gt;')
   
   -- add an ELEMENT
   X.myXml.elem1:append(xml.ELEMENT, 'myElement')

   -- add an ATTRIBUTE
   X.myXml.elem1.myElement:append(xml.ATTRIBUTE, 'myAttribute')
   X.myXml.elem1.myElement['myAttribute'] = 'hello'   
   trace(X:S())
end</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">myXML = [[
&lt;myXml&gt;
   &lt;elem1&gt;
      &lt;sub1&gt;&lt;/sub1&gt;
   &lt;/elem1&gt;
   &lt;elem2&gt;&lt;/elem2&gt;
   &lt;elem3&gt;&lt;/elem3&gt;
   &lt;elem4&gt;&lt;/elem4&gt;
   &lt;elem5&gt;&lt;/elem5&gt;
   &lt;elem6&gt;
      &lt;sub1&gt;valuable data&lt;/sub1&gt;
      &lt;sub2&gt;more valuable data&lt;/sub2&gt;
   &lt;/elem6&gt;
&lt;/myXml&gt;
]]

function main()
   local X = xml.parse(myXML)
     
   --------------------------------------------
   -- Use append to add a TEXT field
   --------------------------------------------

   -- RECOMMENDED 
   X.myXml.elem1:append(xml.TEXT, 'encodes &lt;&amp;&gt; correctly')
   
   -- or can create an empty TEXT field and assign a value later
   X.myXml.elem2:append(xml.TEXT, '')
   X.myXml.elem2[1] = 'encodes &lt;&amp;&gt; correctly'
   
   -- NOT RECOMMENDED 
   --  - use setInner() to set the TEXT value
   --  - works because setInner() does escaping when 
   --    applied to an XML TEXT field
   -- ISSUE: you can accidentally apply it to an ELEMENT
   --        and then it will "work sometimes" see below:
   --        "Incorrect use of setInner() to add a TEXT field" 
   X.myXml.elem3:append(xml.TEXT, '')
   -- apply setInner() to the TEXT field escapes correctly
   X.myXml.elem3[1]:setInner('encodes &lt;&amp;&gt; correctly')  

   -------------------------------------------------------------
   -- Incorrect use of setInner() to add a TEXT field
   -------------------------------------------------------------
   -- NOTE: this is a easy mistake to make (see point XXX below)
   -------------------------------------------------------------

   -- THIS DOES NOT WORK!
   -- FAILS BECAUSE: setInner() parses XML when loading an ELEMENT
   -- ISSUE: fails when you use XML special characters &lt;&amp;&gt;

   -- plain text parses successfully - SEEMS to work
   X.myXml.elem4:setInner('DECEPTIVE: works with no special characters')

   -- until you add special characters - then the XML parse fails
   -- uncommenting the line below will produce an ERROR
   --X.myXml.elem4:setInner('fails when you add &lt;&amp;&gt;') 

   ---------------------------------------
   -- How to update an existing text field
   ---------------------------------------
   
   -- it is simple find and update an existing TEXT field
   local x = X.myXml.elem1
   for i=1,#x do
      if x[i]:nodeType() == 'text' then
         x[i] = x[i]..' - and I changed the text'
      end
   end
  
   ------------------------------------------------------------
   -- Correct use of setInner() to set an ELEMENT field
   ------------------------------------------------------------
   -- NOTE: this is the **only** recommended use of setInnner()
   ------------------------------------------------------------

   -- add sub elements to elem6
   X.myXml.elem5:setInner('&lt;sub1&gt;&lt;/sub1&gt;&lt;sub2&gt;&lt;/sub2&gt;')
   
   -- WARNING: setInner() will overwrite all data in the ELEMENT
   -- be careful in case this is NOT what you want...
   X.myXml.elem6:setInner('OOPs overwrote valuable data...')
   trace(X:S())
   
   --------------------------------------------------------------
   -- Using append() or setInner() to create multiple TEXT fields
   --------------------------------------------------------------
   -- NOTE: both methods are valid, using setInner() is a bit 
   --       more concise
   --------------------------------------------------------------
   -- NOTE: creating 3 ELEMENTS each with a TEXT sub-field
   --       saves 5 lines of codes, the more ELEMENTS
   --       the more lines of code you save
   --------------------------------------------------------------
    
   -- ###### first we do "long-hand" using append() ######
   
   -- first we add a new elem7 with append
   X.myXml:append(xml.ELEMENT, 'elem7')
   local x = X.myXml.elem7
   -- then we create three ELEMENT sub-fields with append
   x:append(xml.ELEMENT, 'sub1')
   x:append(xml.ELEMENT, 'sub2')
   x:append(xml.ELEMENT, 'sub3') 
   -- then we create a TEXT an empty TEXT field in each ELEMENT
   x.sub1:append(xml.TEXT, '')
   x.sub2:append(xml.TEXT, '')
   x.sub3:append(xml.TEXT, '')   
   trace(x)
   -- then we can assign values later as we need to
   for i=1,#x do
      x[i][1] = 'hello '..i
   end   
   trace(x)
   
   -- ###### now the shorter way using setInner () ######
   
    -- first we add a new elem8 with append
   X.myXml:append(xml.ELEMENT, 'elem8')
   x = X.myXml.elem8
   -- then we create three ELEMENT sub-fields with append
   -- the placeholder "#" symbols create the TEXT sub fields
   x:setInner([[&lt;sub1&gt;#&lt;/sub1&gt;&lt;sub2&gt;#&lt;/sub2&gt;&lt;sub3&gt;#&lt;/sub3&gt;]])
   trace(x)
   -- then we can assign values later as we need to
   for i=1,#x do
      x[i][1] = 'hello '..i
   end   
   -- or even make the text fields empty to directly mimic
   -- the behaviour of the "append() code" above
   for i=1,#x do
      x[i][1] = ''
   end      
   trace(x)
   
   -- NOTE: there is no way to directly create empty TEXT fields using setInner()
   -- removing the "#" symbols = empty ELEMENTS (no TEXT sub fields)
   x:setInner([[&lt;sub1&gt;&lt;/sub1&gt;&lt;sub2&gt;&lt;/sub2&gt;&lt;sub3&gt;&lt;/sub3&gt;]])
   trace(x)
   -- if we attempt to assign values directly now it will fail
   
   -- WARNING! this is when/where we might tempted to wrongly use setInner()
   -- to create our TEXT subfields DO NOT DO IT!!! (see point XXX above)
   for i=1,#x do
      x[i]:setInner('UNSAFE: will fail with XML special characters')
      --x[i]:setInner('this will fail &lt;&amp;&gt; try it!')
   end   
  
   ----------------------------------------------
   -- Adding other fields is very similar to TEXT
   ----------------------------------------------

   -- add a CDATA
   X.myXml.elem1:append(xml.CDATA, 'CDATA does not encode &lt;&amp;&gt;')
   
   -- add an ELEMENT
   X.myXml.elem1:append(xml.ELEMENT, 'myElement')

   -- add an ATTRIBUTE
   X.myXml.elem1.myElement:append(xml.ATTRIBUTE, 'myAttribute')
   X.myXml.elem1.myElement['myAttribute'] = 'hello'   
   trace(X:S())
end</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/working-with-xml</link>
      <guid>https://help.interfaceware.com/code/details/working-with-xml</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 11 Aug 2015 13:01:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Remove duplicate words with PCRE regex</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- remove duplicate words using rxsub
local s = "hello hello  hello world world"
x = s:rxsub("(\\b\\w+\\b)(\\W+\\1)+","$1") -- by using a word boundary \b PCRE regex
trace(x) --&gt; hello world                   -- can remove multiple repeats (unlike gsub)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- remove duplicate words using rxsub
local s = "hello hello  hello world world"
x = s:rxsub("(\\b\\w+\\b)(\\W+\\1)+","$1") -- by using a word boundary \b PCRE regex
trace(x) --&gt; hello world                   -- can remove multiple repeats (unlike gsub)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/remove-duplicate-words-with-pcre-regex</link>
      <guid>https://help.interfaceware.com/code/details/remove-duplicate-words-with-pcre-regex</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 11 Aug 2015 11:45:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Extract html tags with PCRE regex</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- extract HTML tags from a string
local s = '&lt;a href="#hello_world"&gt;Hello world link&lt;/a&gt;'
local tags = ''
for k in s:rxmatch('(&lt;[^&gt;]+&gt;)') do
trace(k)
tags = tags..k
end
trace(tags)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- extract HTML tags from a string
local s = '&lt;a href="#hello_world"&gt;Hello world link&lt;/a&gt;'
local tags = ''
for k in s:rxmatch('(&lt;[^&gt;]+&gt;)') do
trace(k)
tags = tags..k
end
trace(tags)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/extract-html-tags</link>
      <guid>https://help.interfaceware.com/code/details/extract-html-tags</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Tue, 11 Aug 2015 10:58:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Convert HL7 messages to/from XML</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- convert an HL7 message to XML representation
local xml = chm.toXml{vmd='example/demo.vmd', data=Data}

-- convert XML to an HL7 message
local Data = chm.fromXml{vmd='example/demo.vmd', data=xml}

-- convert an HL7 node tree to XML
local Msg = hl7.parse{vmd='example/demo.vmd', data=Data}
local xml = chm.toXml{vmd='example/demo.vmd', data=Msg:S()}</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- convert an HL7 message to XML representation
local xml = chm.toXml{vmd='example/demo.vmd', data=Data}

-- convert XML to an HL7 message
local Data = chm.fromXml{vmd='example/demo.vmd', data=xml}

-- convert an HL7 node tree to XML
local Msg = hl7.parse{vmd='example/demo.vmd', data=Data}
local xml = chm.toXml{vmd='example/demo.vmd', data=Msg:S()}</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/convert-hl7-messages-tofrom-xml</link>
      <guid>https://help.interfaceware.com/code/details/convert-hl7-messages-tofrom-xml</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 21:46:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Format a string</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">string.format("%f, %g", math.pi,math.pi)       -- float and compact float
--&gt;3.141593, 3.14159

string.format("%s %q", "Hello", "Lua user!")   -- string and quoted string
--&gt;Hello "Lua user!"

string.format("%c%c%c", 76,117,97)             -- char
--&gt;Lua

string.format("%e, %E", math.pi,math.pi)       -- exponent
--&gt;3.141593e+000, 3.141593E+000

string.format("%f, %g", math.pi,math.pi)       -- float and compact float
--&gt;3.141593, 3.14159

string.format("%d, %i, %u", -100,-100,-100)    -- signed, signed, unsigned integer
--&gt;-100, -100, 4294967196

string.format("%o, %x, %X", -100,-100,-100)    -- octal, hex, hex
--&gt;37777777634, ffffff9c, FFFFFF9C</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">string.format("%f, %g", math.pi,math.pi)       -- float and compact float
--&gt;3.141593, 3.14159

string.format("%s %q", "Hello", "Lua user!")   -- string and quoted string
--&gt;Hello "Lua user!"

string.format("%c%c%c", 76,117,97)             -- char
--&gt;Lua

string.format("%e, %E", math.pi,math.pi)       -- exponent
--&gt;3.141593e+000, 3.141593E+000

string.format("%f, %g", math.pi,math.pi)       -- float and compact float
--&gt;3.141593, 3.14159

string.format("%d, %i, %u", -100,-100,-100)    -- signed, signed, unsigned integer
--&gt;-100, -100, 4294967196

string.format("%o, %x, %X", -100,-100,-100)    -- octal, hex, hex
--&gt;37777777634, ffffff9c, FFFFFF9C</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/format-a-string</link>
      <guid>https://help.interfaceware.com/code/details/format-a-string</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 21:16:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Parse and serialize JSON</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">   -- parse and serialize a JSON string
   
   -- sample JSON string
   local JS = "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"

   -- parse the JSON string into a Lua table
   local JT = json.parse{data=JS}
   
   -- serialize the Lua table into JSON
   local JS = json.serialize{data=JT}</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">   -- parse and serialize a JSON string
   
   -- sample JSON string
   local JS = "{'int_test': 1.23, 'string_test':'a', 'boolean_test' : true}"

   -- parse the JSON string into a Lua table
   local JT = json.parse{data=JS}
   
   -- serialize the Lua table into JSON
   local JS = json.serialize{data=JT}</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/parse-and-serialize-json</link>
      <guid>https://help.interfaceware.com/code/details/parse-and-serialize-json</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 17:18:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Get the floor or ceiling for a number</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- get the floor for a number
local floor = math.floor(99.5)
trace(floor)

-- get the ceiling for a number
local ceil = math.ceil(99.5)
trace(ceil)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- get the floor for a number
local floor = math.floor(99.5)
trace(floor)

-- get the ceiling for a number
local ceil = math.ceil(99.5)
trace(ceil)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/get-the-floor-or-ceiling-for-a-number</link>
      <guid>https://help.interfaceware.com/code/details/get-the-floor-or-ceiling-for-a-number</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 14:34:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Get the absolute value of a number</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- get the absolute value of a number
local abs = math.abs(-99)
trace(abs)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- get the absolute value of a number
local abs = math.abs(-99)
trace(abs)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/get-the-absolute-value-of-a-number</link>
      <guid>https://help.interfaceware.com/code/details/get-the-absolute-value-of-a-number</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 14:27:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Using uuencoding</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- uuencode a string

-- encode a string
local enc = filter.uuencoding.enc('Hello World', 'test.txt')
trace(enc)

-- decode the encoded string
local dec = filter.uuencoding.dec(enc)
trace(dec)

-- uuencode a stream

-- create a sample text file in the Iguana install directory
local f = io.open('test.txt', 'w')
f:write('Hello World')
f:close()

-- encode a stream
local inp = stream.fromFile('test.txt')
local out = filter.uuencoding.enc(inp, 'test.txt')

-- save the stream to a file
stream.toFile('test-uuencode.txt', out)

-- decode the saved uuencode stream
local inp = stream.fromFile('test-uuencode.txt')
local out = filter.uuencoding.dec(inp, 'test.txt')
trace(stream.toString(out))</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- uuencode a string

-- encode a string
local enc = filter.uuencoding.enc('Hello World', 'test.txt')
trace(enc)

-- decode the encoded string
local dec = filter.uuencoding.dec(enc)
trace(dec)

-- uuencode a stream

-- create a sample text file in the Iguana install directory
local f = io.open('test.txt', 'w')
f:write('Hello World')
f:close()

-- encode a stream
local inp = stream.fromFile('test.txt')
local out = filter.uuencoding.enc(inp, 'test.txt')

-- save the stream to a file
stream.toFile('test-uuencode.txt', out)

-- decode the saved uuencode stream
local inp = stream.fromFile('test-uuencode.txt')
local out = filter.uuencoding.dec(inp, 'test.txt')
trace(stream.toString(out))</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/using-uuencoding</link>
      <guid>https://help.interfaceware.com/code/details/using-uuencoding</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 09:31:00 +0000</pubDate>
    </item>
 
    <item>
      <title>stream.lua</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">    -- 
    -- Basic Streams: Strings, Files, Pipes and Sockets
    --
    -- Copyright (c) 2011-2012 iNTERFACEWARE Inc.
    --
     
    -- How much data to buffer between reads.
    local buffer_size = 64*1024
     
    -- Throw errors reported by io.open().
    local function open(path, mode)
       local file, err = io.open(path, mode)
       if not file then
          error(err, 3)
       end
       return file
    end
     
    -- Throw errors reported by io.popen().
    local function popen(cmd, mode)
       local file, err = io.popen(cmd, mode)
       if not file then
          error(err, 3)
       end
       return file
    end
     
    -- Stream from some open file (see fromFile, fromPipe).
    local function fromFile(file)
       return function()
          local out
          if file then
             out = file:read(buffer_size)
             if not out then
                file:close()
                file = nil
             end
          end
          return out
       end
    end
     
    -- Stream to some open file (see toFile, toPipe).
    local function toFile(file, from, ...)
       local chunk
       repeat
          chunk = from(...)
          if chunk then
             file:write(chunk)
          end
       until not chunk
       file:close()
    end
     
    --
    -- Public API
    --
     
    stream = {}
     
    -- stream.fromString(s)
    --
    -- Create a stream from a string.
    --   's' - the string
    --
    -- e.g. stream.toFile('out.txt', stream.fromString(Data))
    --
    function stream.fromString(s)
       return function()
          local out
          if #s &gt; 0 then
             out = s:sub(1,buffer_size)
             s = s:sub(buffer_size+1)
          end
          return out
       end
    end
     
    -- stream.toString(from, ...)
    --
    -- Write a stream to a string.
    --   'from(...)' - the stream to read from
    --
    -- e.g. local s = stream.toString(stream.fromFile('in.txt'))
    --
    function stream.toString(from, ...)
       local out, chunk = {}, nil
       repeat
          chunk = from(...)
          if chunk then
             out[#out+1] = chunk
          end
       until not chunk
       return table.concat(out)
    end
     
    -- stream.fromFile(path [,mode])
    --
    -- Create a stream from a file.
    --   'path' - the path of the file
    --   'mode' - the mode to use (defaults to 'rb')
    --
    -- e.g. local s = stream.toString(stream.fromFile('in.txt'))
    --
    function stream.fromFile(path, mode)
       local file = open(path, mode or 'rb')
       return fromFile(file)
    end
     
    -- stream.toFile(path, from, ...)
    -- stream.toFile(path, mode, from, ...)
    --
    -- Write a stream to a file.
    --   'path'      - the path of the file
    --   'mode'      - the mode to use (defaults to 'wb')
    --   'from(...)' - the stream to read from
    --
    -- e.g. stream.toFile('out.txt', stream.fromString(Data))
    --
    function stream.toFile(path, mode, from, ...)
       if type(mode) == 'function' then
          return stream.toFile(path, 'wb', mode, from, ...)
       end
       local file = open(path, mode)
       return toFile(file, from, ...)
    end
     
    -- stream.fromPipe(cmd)
    --
    -- Create a stream from an external process.
    --   'cmd' - the command to run and read from
    --
    -- e.g. local s = stream.toString(stream.fromPipe('ls -1'))
    --
    function stream.fromPipe(cmd)
       local file = popen(cmd, 'r')
       return fromFile(file)
    end
     
    -- stream.toPipe(cmd, from, ...)
    --
    -- Write a stream to an external process.
    --   'cmd'       - the command to run and write to
    --   'from(...)' - the stream to read from
    --
    -- e.g. stream.toPipe('openssl des -out out.tmp -k '..Key,
    --                    stream.fromString(Data))
    --
    function stream.toPipe(cmd, from, ...)
       local file = popen(cmd, 'w')
       return toFile(file, from, ...)
    end
     
    -- stream.fromSocket(sock)
    --
    -- Create a stream from a TCP/IP connection.
    --   'sock' - the connection to read from
    --
    -- e.g. local s = net.tcp.connect{...}
    --      stream.toFile('big.hl7', stream.fromSocket(s))
    --
    function stream.fromSocket(sock)
       return function()
          return sock:recv()
       end
    end
     
    -- stream.toSocket(sock, from, ...)
    --
    -- Write a stream to a TCP/IP connection.
    --   'sock'      - the connection to write to
    --   'from(...)' - the stream to read from
    --
    -- e.g. local s = net.tcp.connect{...}
    --      stream.toSocket(s, stream.fromFile('big.hl7'))
    --
    function stream.toSocket(sock, from, ...)
       while true do
          local chunk = from(...)
          if not chunk then break end
          sock:send(chunk)
       end
    end
     
    -- stream.filter(from, f)
    --
    -- Create a stream by attaching a filter to another stream.
    --   'from' - the stream to read from
    --   'f'    - the filter function
    --
    -- The filter (f) is called with each chunk (or nil) read
    -- from the stream (from) and must return chunks (or nil)
    -- to be sent downstream.
    --
    -- e.g. local Out = stream.toString(
    --         stream.filter(stream.fromString(Data),
    --             function(s)
    --                return s and s:upper()
    --             end))
    --      assert(Out == Data:upper())
    --
    function stream.filter(from, f)
       return function(...)
          local out = from(...)
          return f(out, ...)
       end
    end

    return stream</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">    -- 
    -- Basic Streams: Strings, Files, Pipes and Sockets
    --
    -- Copyright (c) 2011-2012 iNTERFACEWARE Inc.
    --
     
    -- How much data to buffer between reads.
    local buffer_size = 64*1024
     
    -- Throw errors reported by io.open().
    local function open(path, mode)
       local file, err = io.open(path, mode)
       if not file then
          error(err, 3)
       end
       return file
    end
     
    -- Throw errors reported by io.popen().
    local function popen(cmd, mode)
       local file, err = io.popen(cmd, mode)
       if not file then
          error(err, 3)
       end
       return file
    end
     
    -- Stream from some open file (see fromFile, fromPipe).
    local function fromFile(file)
       return function()
          local out
          if file then
             out = file:read(buffer_size)
             if not out then
                file:close()
                file = nil
             end
          end
          return out
       end
    end
     
    -- Stream to some open file (see toFile, toPipe).
    local function toFile(file, from, ...)
       local chunk
       repeat
          chunk = from(...)
          if chunk then
             file:write(chunk)
          end
       until not chunk
       file:close()
    end
     
    --
    -- Public API
    --
     
    stream = {}
     
    -- stream.fromString(s)
    --
    -- Create a stream from a string.
    --   's' - the string
    --
    -- e.g. stream.toFile('out.txt', stream.fromString(Data))
    --
    function stream.fromString(s)
       return function()
          local out
          if #s &gt; 0 then
             out = s:sub(1,buffer_size)
             s = s:sub(buffer_size+1)
          end
          return out
       end
    end
     
    -- stream.toString(from, ...)
    --
    -- Write a stream to a string.
    --   'from(...)' - the stream to read from
    --
    -- e.g. local s = stream.toString(stream.fromFile('in.txt'))
    --
    function stream.toString(from, ...)
       local out, chunk = {}, nil
       repeat
          chunk = from(...)
          if chunk then
             out[#out+1] = chunk
          end
       until not chunk
       return table.concat(out)
    end
     
    -- stream.fromFile(path [,mode])
    --
    -- Create a stream from a file.
    --   'path' - the path of the file
    --   'mode' - the mode to use (defaults to 'rb')
    --
    -- e.g. local s = stream.toString(stream.fromFile('in.txt'))
    --
    function stream.fromFile(path, mode)
       local file = open(path, mode or 'rb')
       return fromFile(file)
    end
     
    -- stream.toFile(path, from, ...)
    -- stream.toFile(path, mode, from, ...)
    --
    -- Write a stream to a file.
    --   'path'      - the path of the file
    --   'mode'      - the mode to use (defaults to 'wb')
    --   'from(...)' - the stream to read from
    --
    -- e.g. stream.toFile('out.txt', stream.fromString(Data))
    --
    function stream.toFile(path, mode, from, ...)
       if type(mode) == 'function' then
          return stream.toFile(path, 'wb', mode, from, ...)
       end
       local file = open(path, mode)
       return toFile(file, from, ...)
    end
     
    -- stream.fromPipe(cmd)
    --
    -- Create a stream from an external process.
    --   'cmd' - the command to run and read from
    --
    -- e.g. local s = stream.toString(stream.fromPipe('ls -1'))
    --
    function stream.fromPipe(cmd)
       local file = popen(cmd, 'r')
       return fromFile(file)
    end
     
    -- stream.toPipe(cmd, from, ...)
    --
    -- Write a stream to an external process.
    --   'cmd'       - the command to run and write to
    --   'from(...)' - the stream to read from
    --
    -- e.g. stream.toPipe('openssl des -out out.tmp -k '..Key,
    --                    stream.fromString(Data))
    --
    function stream.toPipe(cmd, from, ...)
       local file = popen(cmd, 'w')
       return toFile(file, from, ...)
    end
     
    -- stream.fromSocket(sock)
    --
    -- Create a stream from a TCP/IP connection.
    --   'sock' - the connection to read from
    --
    -- e.g. local s = net.tcp.connect{...}
    --      stream.toFile('big.hl7', stream.fromSocket(s))
    --
    function stream.fromSocket(sock)
       return function()
          return sock:recv()
       end
    end
     
    -- stream.toSocket(sock, from, ...)
    --
    -- Write a stream to a TCP/IP connection.
    --   'sock'      - the connection to write to
    --   'from(...)' - the stream to read from
    --
    -- e.g. local s = net.tcp.connect{...}
    --      stream.toSocket(s, stream.fromFile('big.hl7'))
    --
    function stream.toSocket(sock, from, ...)
       while true do
          local chunk = from(...)
          if not chunk then break end
          sock:send(chunk)
       end
    end
     
    -- stream.filter(from, f)
    --
    -- Create a stream by attaching a filter to another stream.
    --   'from' - the stream to read from
    --   'f'    - the filter function
    --
    -- The filter (f) is called with each chunk (or nil) read
    -- from the stream (from) and must return chunks (or nil)
    -- to be sent downstream.
    --
    -- e.g. local Out = stream.toString(
    --         stream.filter(stream.fromString(Data),
    --             function(s)
    --                return s and s:upper()
    --             end))
    --      assert(Out == Data:upper())
    --
    function stream.filter(from, f)
       return function(...)
          local out = from(...)
          return f(out, ...)
       end
    end

    return stream</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/stream-lua</link>
      <guid>https://help.interfaceware.com/code/details/stream-lua</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Mon, 10 Aug 2015 09:26:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Using uri encoding</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- encode string for safe use in a uri/url
local Enc = filter.uri.enc('the #1 &amp; #2 (more later)')
trace(Enc)

-- decode uri encoded string
local Dec = filter.uri.dec(Enc)
trace(Dec)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- encode string for safe use in a uri/url
local Enc = filter.uri.enc('the #1 &amp; #2 (more later)')
trace(Enc)

-- decode uri encoded string
local Dec = filter.uri.dec(Enc)
trace(Dec)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/using-uri-encoding</link>
      <guid>https://help.interfaceware.com/code/details/using-uri-encoding</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Sun, 09 Aug 2015 20:08:00 +0000</pubDate>
    </item>
 
    <item>
      <title>Using html encoding</title>
      <description><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- encode string for html
local Enc = filter.html.enc('Encodes html special characters like: &lt;&gt;&amp;')
trace(Enc)</pre>
]]></description>
      <content:encoded><![CDATA[<pre class="noescape prettyprint linenums lang-lua">-- encode string for html
local Enc = filter.html.enc('Encodes html special characters like: &lt;&gt;&amp;')
trace(Enc)</pre>
]]></content:encoded>
      <link>https://help.interfaceware.com/code/details/using-html-encoding</link>
      <guid>https://help.interfaceware.com/code/details/using-html-encoding</guid>
      <dc:creator>iNTERFACEWARE</dc:creator>
      <pubDate>Sun, 09 Aug 2015 19:49:00 +0000</pubDate>
    </item>
  </channel>
</rss>
