This topic contains 0 replies, has 1 voice, and was last updated by  lev 4 years, 2 months ago.

How to split long report into fields of limited length

  • Quite often we have long report text in single field and have to split it to lines shorter than field length limit, to match limits of field length in say OBX-5 field.

    Having said that, the function splitText() below is universally good to split any type of ASCII text to lines shorter than length limit.

    In this example we take complete report from original single OBX-5 field as bulk text, and split it into chunks shorter than length limit, without changing the text, not even original ‘new lines’.

    Sometimes ‘new line’ in original text is indicated by tilde character, which is interpreted as repetitions of OBX-5 field.

    Sometimes ‘new line’ in original text is indicated by or or combination of both.

    We preserve all and any of above four cases for original text content.

    In this example, for each, less than N characters of length chunk of original text, we add another OBX segment to outbound HL7 message. Each such chunk of text is placed into OBX-5 field of next respective segment.

    Here is function splitText():

    function splitText(s, RS, max)
       -- split text into chunks of MAX length
       
       local function _g(s, i, c, RS) 
          -- recursively split text 
          
          local function _f(s , i, c)      
             -- recursively find words and add each word to a chunk     
             local w, i = findWord(s, i)                
             
             if i == #s then return c..w end
             
             if  #(c..w) < max  then
                c = c..w 
                s = s:sub(i + 1,#s,true)
                return _f(s, 1, c)
                
             else
                return c
             end
          end     
          
          
          RS[#RS + 1] = _f(s,1,'')
          i = i + #RS[#RS]      
          
          if i < #s then 
             local s = s:sub(i, #s, true)
             return _g(s, 1, '', RS)    
          
          else
             return RS          
          end
       end
       
    
       return _g(s, 1, '', RS)
    end

    Function splitText() is using helper function findWord()

    local function findWord(s, i)
       -- find first word in given text
       local j = i + 1
       while not _isWhite(s:byte(j)) and j < #s do
          j = j + 1
       end
       return s:sub(i,j), j
    end

    And here is complete example how we call it from main() to add OBX segments to our sample HL7 message

    require('stringutil')
    require('node')
    
    function main(Data)
    
       local MAX = 81 -- we wish to have maximum of 80 characters per line
       
       local In,Name = hl7.parse{vmd='Untitled.vmd', data=Data}
       local Out = hl7.message{vmd='Untitled.vmd', name=Name}
       
       Out:mapTree(In)
       -- in this example we have only 1st repetition of Observation, with very long OBX-5
       Out.Observation[1].OBX:remove(1) 
       
       local RS = {} 
       RS = splitText(In.Observation[1].OBX[1][5]:S(), RS, MAX)
       
       for i = 1,#RS do   
          Out.Observation[1].OBX[i][1] = i
          Out.Observation[1].OBX[i][2] = 'TX'
          Out.Observation[1].OBX[i][3][1] = In.Observation[1].OBX[1][3][1]
          Out.Observation[1].OBX[i][5][1] = RS[i]
       end
       
       return Out
    end

    And a complete Project file for impatient 🙂

    Attachments:
    You must be logged in to view attached files.

You must be logged in to reply to this topic.