Move Note URL to Rich Text Web Link.fh_lua

--[[
@Title:			Move Note URL to Rich Text Web Link
@Type:				Standard
@Author:			Mike Tate
@Contributors:	
@Version:			1.2
@Keywords: 
@LastUpdated:	29 Oct 2021
@Licence:			This plugin is copyright (c) 2021 Mike Tate and contributors, and is licensed under the MIT License which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description:	Convert unformatted Note URL to Rich Text Web Link catering for {value}, {individual} or {individual's} codes and "display text".
@V1.2:				Handle URL with embedded {value} or {individual's} codes and "display text"; Handle rich text Notes; Offer optional Result Set;
@V1.1:				Avoid 2nd run upsetting converted Rich Text URL;
@V1.0:				First published.
]]

fhInitialise(7,0,0,"save_recommended")									-- Check for FH v7.0

local strTitle = "Move Note URL to Rich Text Web Link  1.2"		-- UPDATE THIS FOR EACH VERSION!

local arrRec = {}															-- Result Set tables
local arrTag = {}
local arrRid = {}
local arrURL = {}

function Main()
	for intType = 1, fhGetRecordTypeCount() do						-- Loop through all record types
		local ptrItem = fhNewItemPtr()
		local strType = fhGetRecordTypeTag(intType)
		ptrItem:MoveToFirstRecord(strType)
		while ptrItem:IsNotNull() do										-- Loop through all data items until local Note found
			if fhGetTag(ptrItem) == "NOTE2" then
				local ptrNote = ptrItem:Clone()
				local strNote = ""
				if fhGetValueType(ptrNote) == "richtext" then
					strNote = fhGetValueAsRichText(ptrNote):GetText()
				else
					strNote = fhGetValueAsText(ptrNote)
				end
				-- URL preceeded by " is already converted, and adding the leading '~' allows that to be tested with pattern match ([^"])
				-- URL can start with ftp:// or http:// or https:// using Lua pattern match [hf]t?tps?://	
				-- URL may contain ! # $ % & ' ( ) * + , - . / 0-9 : ; < = > ? @ A-Z [ \ ] ^ _ ` a-z { | } ~ including 'unsafe' < > \ ^ ` { | } but not " or space
				-- Apart from ! that spans all from # to ~ so can be coded as Lua pattern match [#-~]
				-- ')
																				-- i.e.  https://URL/ becomes \n
				if intURL > 0 then											-- URL found and converted to \n rich text format
					strNote = strNote:sub(2)								-- Remove leading '~' inserted above
					FormURL(ptrNote,strNote,strType)					-- Format and save URL in Note
				end
			end
			ptrItem:MoveNextSpecial()
		end
	end
	if #arrURL == 0 then
		fhMessageBox("\nNo URL were converted to a rich text web link.\n")
	else
		if "Yes" == fhMessageBox("\n"..#arrURL.." URL converted to a rich text web link.\n\nDo you want a listing of all those URL?\n","MB_YESNO","MB_ICONQUESTION") then
			fhOutputResultSetTitles(strTitle)
			fhOutputResultSetColumn("Record", "item"  , arrRec, #arrURL, 200, "align_left")
			fhOutputResultSetColumn("Type"  , "text"  , arrTag, #arrURL,  40, "align_left", 1, true)
			fhOutputResultSetColumn("Rec Id","integer", arrRid, #arrURL,  40, "align_mid" , 2, true)
			fhOutputResultSetColumn("Note"  , "item"  , arrURL, #arrURL, 500, "align_left")
		end
	end
end -- function Main

function FormURL(ptrNote,strNote,strType)								-- Format and save URL in Note
	-- ptrNote ~ Pointer to Note field
	-- strNote ~ Note content with URL
	-- strType ~ Type of record tag

	strNote = strNote:gsub( '([%.:,;])">'  , '">%1' )				-- Move a trailing punctuation symbol ( . : , ; ) ouside URL
	strNote = strNote:gsub( '"> ("[^\n]-")', '",%1>')				-- Use quoted suffix as display text, i.e.  "text" makes 

	if strType == "INDI" then												-- For Individual records replace {value}, {individual}, {individual's} codes
		if strNote:match( "{value}" ) then
			local ptrFact = fhNewItemPtr()								-- Replace {value} code by attribute fact value
			ptrFact:MoveToParentItem(ptrNote)
			local strValue = fhGetValueAsText(ptrFact)				-- Get parent attribute fact value if any
			if #strValue == 0 then return end							-- If no attribute value then inhibit URL conversion
			strNote = strNote:gsub( "{value}", strValue )
		end
		if strNote:match( "{individual'?s?}" ) then					-- Replace {individual} code by name with optional apostrophe
			local ptrIndi = fhNewItemPtr()
			ptrIndi:MoveToRecordItem(ptrNote)
			local strName = fhGetDisplayText( ptrIndi, "~.NAME", "min" )
			if #strName == 0 then
				strName = "unamed person"									-- Ensure a name exists
			end
			strNote = strNote:gsub( "{individual('?s?)}", strName.."%1" )
		end
	end

	strNote = strNote:gsub( '\n

Source:Move-Note-URL-to-Rich-Text-Web-Link-2.fh_lua