Address Reformatting.fh_lua

--[[
@Title:			Address Reformatting
@Author:			Peter Richmond
@LastUpdated:	08Feb2015
@Version:			1.3
@Description:	Convert all Addresses to either single-line or multi-line format.
@V1.3:				(Thanks to Mike Tate) Unicode characters outside the ANSI/CP1252 set now preserved.
@V1.2:				(Thanks to Mike Tate) All Addresses converted to one of three possible formats with parts separated by:
(a) a comma and a space (Single-Line); (b) just a newline (Multi-Line); (c) a comma and a newline.
@V1.1:				Caters for optional comma and whitespace before newline when going to single-line,
and provides a third option for a comma preceding each newline when going to multi-line.
]]

require("iuplua")	-- To access GUI window builder

if fhGetAppVersion() > 5 then	--	To preserve Unicode characters outside the ANSI/CP1252 set.
   fhSetStringEncoding("UTF-8")
   iup.SetGlobal("UTF8MODE","YES")
end

sTitle = "Address Reformatting"
-- Dialog for user to specify required format.
iOption = 0
iComma = 0
bOK, iOption, iComma = iup.GetParam(sTitle, param_action,
"Please choose new Address format: %o|Multi-Line|Single-Line (with comma + space)|{Please choose the required format}\n" ..
"Insert a Comma before each Newline?: %b[No,Yes]{i.e. a Comma at the end of every line except the last}\n",
iOption, iComma)

if iOption == 1 then						-- Result is "Single-Line".
   sFind1 = "[ \t]*,?[ \t]*\n[ \t]*"		-- Will find newline (\n) including any whitespace ([ \t]*) and preceding optional comma (,?).
	sFind2 = "[ \t]*,[ \t]*"					-- Will find a comma and any surrounding whitespace.
   sReplace = ", "								-- Will replace with a comma followed by a single space.
elseif iOption == 0 then  				-- Result is "Multi-Line".
   sFind1 = "[ \t]*,[ \t]*\n?[ \t]*"		-- Will find comma optionally followed by newline and adjacent whitespace.
	if iComma == 1 then						-- Result is "Multi-Line with Commas".
		sFind2 = "[ \t^,]*\n[ \t]*"			-- Will find any multi-line Address.
		sReplace = ",\n"						-- Will replace with comma and newline character (,\n).
   else										-- Result is "Multi-Line" (no commas).
		sFind2 = "[ \t]*\n[ \t]*"				-- Will find any newline. 
		sReplace = "\n"							-- Will replace with only a newline.
	end
end

if bOK then	-- Declare tables for reporting changes.
   tAddressList = {}
   tResultList = {}
   tFactList = {}
   tRecordList = {}

   tTypes = {"INDI","FAM","REPO","SUBM"}	-- Record Types that may contain ADDR tags
   pi = fhNewItemPtr()
   pFact = fhNewItemPtr()			-- Fact (or Repository or Submitter record) which contains Address
   pOwner = fhNewItemPtr()		-- Owner (Individual or Family) which contains Fact
   iCount = 0
   iChanges = 0

   for iType,sTypeDesc in ipairs(tTypes) do		-- Scan the four Record Types
      pi:MoveToFirstRecord(sTypeDesc)
      while pi:IsNotNull() do
         sType = fhGetTag(pi)
         if sType == 'ADDR' then
            sAddr = fhGetValueAsText(pi)
            if (sAddr ~= nil) and (sAddr ~= "") then		-- Process a non-blank Address
               iCount = iCount + 1											-- Increment count of Addresses
               if string.find(sAddr, sFind1) or string.find(sAddr, sFind2) then		-- Only Addresses with something to change   
                  sResult = string.gsub(sAddr, sFind1, sReplace)		-- Make 1st change
                  sResult = string.gsub(sResult, sFind2, sReplace)		-- Make 2nd change
					  if sResult ~= sAddr then							-- Check that something changed
						  fhSetValueAsText(pi,sResult)					-- Update FH
						  fhUpdateDisplay()
						  pFact:MoveToParentItem(pi)						-- Get the "Fact"
						  pOwner:MoveToParentItem(pFact)				-- Get the Owner 
	                  table.insert(tRecordList,pOwner:Clone())	-- Add to Owner column
	                  table.insert(tFactList,pFact:Clone())		-- Add to Fact column
	                  table.insert(tResultList,pi:Clone())			-- Add to Result "New Address" column
	                  table.insert(tAddressList,sAddr)				-- Add to Old Address column
	                  iChanges = iChanges + 1							-- Increment count of changed Addresses
					  end	
               end
            end
         end
         pi:MoveNextSpecial()
      end
   end

	sUndo = ""
	if iChanges > 0 then
		sUndo = "\n\nYou can use FH menu option Edit > Undo Plugin Updates if you don't like the result."
	end
	if iCount > 0 then			-- Notify result
      fhMessageBox(iChanges.." out of "..iCount.." Addresses reformatted." .. sUndo)
      if iChanges > 0 then		-- Send the Tables to Query Window columns.
         fhOutputResultSetColumn("Owner", "item", tRecordList, #tRecordList)
         fhOutputResultSetColumn("Fact (or Repo/Subm)", "item", tFactList, #tFactList)
         fhOutputResultSetColumn("New Address", "item", tResultList, #tResultList,160)
         fhOutputResultSetColumn("Old Address", "text", tAddressList, #tAddressList,160)
      end
   else
      fhMessageBox("No Addresses Found")
   end
else
   iup.Message(sTitle, "Cancelled")
end

Source:Address-Reformatting4.fh_lua