--[[ @Title: Fact Calendar @Author: Jane Taubman @Version: 1.0 @LastUpdated: 08 Mar 2019 @Description: Create an Html Page for a 12 Month Calendar ]] function main() if fhGetAppVersion() > 5 then fhSetStringEncoding("UTF-8") end if fhGetContextInfo('CI_APP_MODE') ~= 'Project Mode' then fhMessageBox('Sorry this plugin needs to be run on a Project') return end local tblIndi = fhPromptUserForRecordSel('INDI') local tblIndiFactList = {'BIRT','DEAT','BURI','BAPM'} local tblFamFactList = {'MARR'} local tblMonths = {'January','February','March','April','May','June','July','August','September','October','November','December'} local tblFacts = {} if tblIndi[1] then for i,ptrIndi in pairs(tblIndi) do print(fhGetDisplayText(ptrIndi)) -- Indivdual Facts for px in facts(ptrIndi) do if inList(tblIndiFactList,fhGetTag(px)) then table.insert(tblFacts, px:Clone()) end end -- Family As Spouse Facts ptrFamLink = fhNewItemPtr() ptrFam = fhNewItemPtr() ptrFamLink:MoveTo(ptrIndi,'~.FAMS') while ptrFamLink:IsNotNull() do ptrFam = fhGetValueAsLink(ptrFamLink) for px in facts(ptrFam) do if inList(tblFamFactList,fhGetTag(px)) then table.insert(tblFacts, px:Clone()) end end ptrFamLink:MoveNext('SAME_TAG') end end end -- Convert Fact List to exclude those with out a day no and month number or that have complex dates local tblCalendarList = {} local tblDays = {31,29,31,30,31,30,31,31,30,31,30,31} local iId = 0 for i = 1,12 do tblCalendarList[i] = {} for j = 1,tblDays[i] do tblCalendarList[i][j] = {} end end for i,px in pairs(tblFacts) do local ptrDate = fhNewItemPtr() local ptrParent = fhNewItemPtr() local ptrSpou = fhNewItemPtr() ptrDate:MoveTo(px,'~.DATE') dDate = fhGetValueAsDate(ptrDate) if not(dDate:IsNull()) then if dDate:GetType() == 'Simple' then dpDatePt = dDate:GetDatePt1() dDay = dpDatePt:GetDay() dMonth = dpDatePt:GetMonth() dYear = dpDatePt:GetYear() if dDay > 0 and dMonth > 0 then print(dDate:GetDisplayText()) ptrParent:MoveToRecordItem(px) local sName = "" if fhGetTag(ptrParent) == 'FAM' then ptrSpou:MoveTo(ptrParent,'~.~SPOU[1]>') sName = fhGetDisplayText(ptrSpou)..' '..fhCallBuiltInFunction('LifeDates',ptrSpou) ptrSpou:MoveTo(ptrParent,'~.~SPOU[2]>') if ptrSpou:IsNotNull() then sName = sName..' and '..fhGetDisplayText(ptrSpou)..' '..fhCallBuiltInFunction('LifeDates',ptrSpou) end print(sName) else sName = fhGetDisplayText(ptrParent)..' '..fhCallBuiltInFunction('LifeDates',ptrParent) end local sLabel = fhCallBuiltInFunction('FactLabel',px) bFound = false for k,tblfact in pairs(tblCalendarList[dMonth][dDay]) do if px:IsSame(tblfact[4]) then bFound = true end end if not(bFound) then iId = iId + 1 tblCalendarList[dMonth][dDay][iId] = {sName,sLabel,dYear,px:Clone()} end end end end end local tblHtml = {} for i = 1,12 do table.insert(tblHtml,"\n

"..tblMonths[i]..'

') for j = 1,tblDays[i] do table.insert(tblHtml,"\n"..'

'..j.."

") tblDates = {} -- Sort Table By Date for k,tblfact in pairs(tblCalendarList[i][j]) do table.insert(tblDates,tblfact) end table.sort(tblDates, compare) for k,tblfact in ipairs(tblDates) do sData = facttemplate:gsub('{year}',tblfact[3]) sData = sData:gsub('{name}',tblfact[1]) sData = sData:gsub('{event}',tblfact[2]) table.insert(tblHtml,sData) end table.insert(tblHtml,'
') end table.insert(tblHtml,'
 
') end sHtml = table.concat(tblHtml) sHtml = htmltemplate:gsub('{data}',sHtml) sFileName= fhGetContextInfo('CI_PROJECT_PUBLIC_FOLDER')..'\\FactCalendar'..fhGetContextInfo('CI_PROJECT_NAME')..'.html' SaveStringToFile(sHtml,sFileName) fhShellExecute(sFileName) end ------------------------------------------------------ functions function facts(pi) local pf = fhNewItemPtr() local pf2 = fhNewItemPtr() pf:MoveToFirstChildItem(pi) return function () while pf:IsNotNull() do pf2:MoveTo(pf) pf:MoveNext() if fhIsFact(pf2) then return pf2 end end end end function inList(tblList,value) bRet = false for _,v in pairs(tblList) do if v == value then bRet = true break end end return bRet end function compare(a,b) return a[3] < b[3] end -- Open File and return Handle -- function OpenFile(strFileName,strMode) local fileHandle, strError = io.open(strFileName,strMode) if not fileHandle then error("\n Unable to open file in \""..strMode.."\" mode. \n "..strFileName.." \n "..tostring(strError).." \n") end return fileHandle end -- function OpenFile -- Save string to file -- function SaveStringToFile(strString,strFileName) local fileHandle = OpenFile(strFileName,"w") fileHandle:write(strString) assert(fileHandle:close()) end -- function SaveStringToFile ------------------------------------------------------ templates htmltemplate = [[ Family History Fact Calendar {data} ]] facttemplate = [[

{year} {event}: {name}

]] ------------------------------------------------------ main main()