* Iterating over a source's citations

For users to report plugin bugs and request plugin enhancements; and for authors to test new/new versions of plugins, and to discuss plugin development (in the Programming Technicalities sub-forum). If you want advice on choosing or using a plugin, please ask in General Usage or an appropriate sub-forum.
Post Reply
avatar
stanm
Platinum
Posts: 34
Joined: 02 May 2014 17:46
Family Historian: V7
Location: California, USA

Iterating over a source's citations

Post by stanm » 28 Dec 2020 20:28

I am working on a plugin that converts generic sources to template sources.

Once the conversion of source records is complete, the citation references also need adjustment. There may be insertions of _FIELD items. In many cases, it is necessary to parse the contents of PAGE items.

I'm wondering if the code below is the best way to approach this. The function visitSourceReferences() is called with the target source record Id. The unlisted function, processSourceCitationTag(), prints out a debug message.

Code: Select all

local function visitSourceReferences(sourceRecordId)
  local pi = fhNewItemPtr()
  local recordsWithSources = {"INDI", "FAM", "OBJE", "NOTE", "_RNOT"}

  for i, tag in ipairs(recordsWithSources) do
    pi:MoveToFirstRecord(tag)

    while not pi:IsNull() do
      if fhGetTag(pi) == "SOUR" then
        local ptrSourceRef = fhGetValueAsLink(pi)
        if fhGetRecordId(ptrSourceRef) == sourceRecordId then
          -- This source matches "sourceRecordId"
          local childPtr = fhNewItemPtr()
          if fhHasChildItem(pi) then
            childPtr:MoveToFirstChildItem(pi)
            while not childPtr:IsNull() do
              -- Process child items of the citation
			  -- or insert new _FIELD items
              processSourceCitationTag(childPtr)
              childPtr:MoveNext()
            end
          end
        end
      end

      pi:MoveNextSpecial()
    end
  end
end
Thanks for any suggestions.
Stan Mitchell

User avatar
tatewise
Megastar
Posts: 27088
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Iterating over a source's citations

Post by tatewise » 28 Dec 2020 20:53

Yes, that is the correct approach using pi:MoveNextSpecial()

BTW: More record tags than you have listed can have Citations but perhaps you are only interested in your Citations.

There are some slight enhancements.

Instead of while not pi:IsNull() do use while pi:IsNotNull() do that is slightly neater.

To scan the Citation children use:
local childPtr = fhNewItemPtr()
childPtr:MoveToFirstChildItem(pi)
while childPtr:IsNotNull() do

There is no need to test with fhHasChildItem(pi) as if none the childPtr will start Null and never enter the while loop.

Bear in mind that to reach a Citation ~ Text From Source that will be in ...SOUR.DATA.TEXT
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

avatar
stanm
Platinum
Posts: 34
Joined: 02 May 2014 17:46
Family Historian: V7
Location: California, USA

Re: Iterating over a source's citations

Post by stanm » 28 Dec 2020 21:19

Thank you Mike for your suggestions. I will incorporate them. I thought it prudent to have someone else look at the code early on. Having someone with your expertise -- even better!

I will probably keep the test of fhHasChildItem(pi) and add an else clause for when a _FIELD child needs to be added and no child items yet exist.
Stan Mitchell

User avatar
tatewise
Megastar
Posts: 27088
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Iterating over a source's citations

Post by tatewise » 28 Dec 2020 22:21

That all looks good.

It does bring into focus what those of us who promote using Method 1 'splitter' Sources have said about the multiple Citations associated with Method 2 'lumper' Sources. I suspect that if Method 1 had been used then only Source records would need updating and not all those Citations.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

avatar
stanm
Platinum
Posts: 34
Joined: 02 May 2014 17:46
Family Historian: V7
Location: California, USA

Re: Iterating over a source's citations

Post by stanm » 29 Dec 2020 01:18

The database I am converting is from Ancestry.com by way of FTM to GEDCOM.
I'm using it because it is the most complete I have.

I have done preliminary work to split many of the lumped sources,
e. g. split a census decade into census households for that decade.
For the census records, that approach is allowing me to avoid citation-specific fields.

While I appreciate the simplicity that the "splitter" approach provides,
I haven't decided yet whether it will be necessary to use a "lumper" source in some situations.
That is why I'm at least considering some support for lumped sources in my conversion plugin.
Stan Mitchell

User avatar
tatewise
Megastar
Posts: 27088
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Iterating over a source's citations

Post by tatewise » 29 Dec 2020 10:16

Yes, imports from other products do tend to use 'lumped' Sources, and there are other scenarios where they are best, such as GRO BMD Index entries. I just thought it worth mentioning, especially for others who may be following this thread.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

avatar
stanm
Platinum
Posts: 34
Joined: 02 May 2014 17:46
Family Historian: V7
Location: California, USA

Re: Iterating over a source's citations

Post by stanm » 29 Dec 2020 19:04

tatewise wrote:
28 Dec 2020 20:53
BTW: More record tags than you have listed can have Citations ...
I overlooked that comment. What other record types can have citations?
This is what I have now:

Code: Select all

  local recordsWithSources = {"INDI", "FAM", "OBJE", "NOTE", "_RNOT"}
Thanks
Stan Mitchell

User avatar
tatewise
Megastar
Posts: 27088
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: Iterating over a source's citations

Post by tatewise » 29 Dec 2020 20:46

They can all have Source Citations except for the HEADer record.
That is because they can all have a Note, and a Note can have Source Citations.

So you could use the Plugin Code Snippet Loop Through All Record Types or your own loop based on that.
BTW: The HEAD record is not included in that process.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

Post Reply