* Search and Replace Plugin - Calico
-
ikas
- Platinum
- Posts: 32
- Joined: 02 Sep 2011 14:37
- Family Historian: V7
- Location: West Coast of Scotland
Search and Replace Plugin - Calico
Hi,
I was hoping to use this plugin to replace all occurences of .tif with .jpg in a GEDCOM - previously used a text editor for this but it would be useful to run it within FH.
However it appears to replace all occurances of tif (without period at start) as well as .tif
Hence certified is changed to ce.jpgied
Can someone point me to the offending line in the plugin source - I cannot see it.
Thanks
ID:6058
I was hoping to use this plugin to replace all occurences of .tif with .jpg in a GEDCOM - previously used a text editor for this but it would be useful to run it within FH.
However it appears to replace all occurances of tif (without period at start) as well as .tif
Hence certified is changed to ce.jpgied
Can someone point me to the offending line in the plugin source - I cannot see it.
Thanks
ID:6058
- PeterR
- Megastar
- Posts: 1129
- Joined: 10 Jul 2006 16:55
- Family Historian: V7
- Location: Northumberland, UK
Search and Replace Plugin - Calico
There is a clue in that 'rtif' was replaced by '.jpg'. The dot '.' in the search string is a 'magic' character and stands for any character. If you precede the dot '.' in the search string (only) with a percent sign '%' it will escape the magic character and should find only the required occurrences.
I've tried '%.tif' as a search string and it works OK, with '.jpg' as a replace string.
I've tried '%.tif' as a search string and it works OK, with '.jpg' as a replace string.
-
ikas
- Platinum
- Posts: 32
- Joined: 02 Sep 2011 14:37
- Family Historian: V7
- Location: West Coast of Scotland
Search and Replace Plugin - Calico
Many thanks Peter. Did the trick.
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
I think this may be a deficiency in the Plugin.
I would not expect a user to have to know about the Regular Expression 'Magic' characters, and work around them.
There is a straight-forward function that can be incorporated into the Plugin to ensure all user entered 'Magic' characters are automatically hidden by the % character.
See the Plugin Code Snippet called Plain Text Substitution.
I would not expect a user to have to know about the Regular Expression 'Magic' characters, and work around them.
There is a straight-forward function that can be incorporated into the Plugin to ensure all user entered 'Magic' characters are automatically hidden by the % character.
See the Plugin Code Snippet called Plain Text Substitution.
-
ikas
- Platinum
- Posts: 32
- Joined: 02 Sep 2011 14:37
- Family Historian: V7
- Location: West Coast of Scotland
Search and Replace Plugin - Calico
Yes, agree. Knowledge of regular expressions should not be a pre-requistite to use this plug-in but can understand why it was missed.
- Jane
- Site Admin
- Posts: 8442
- Joined: 01 Nov 2002 15:00
- Family Historian: V7
- Location: Somerset, England
- Contact:
Search and Replace Plugin - Calico
I have finally got around to the Search and Replace plugin
It now has 'whole word' and 'plain text' options.
Please could a few brave souls give it a go before I upload it to the plugin store
http://dl.dropbox.com/u/1367679/plugins ... ace.fh_lua
It now has 'whole word' and 'plain text' options.
Please could a few brave souls give it a go before I upload it to the plugin store
http://dl.dropbox.com/u/1367679/plugins ... ace.fh_lua
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Have not run any in depth tests, but here are a couple of suggestions.
(1) Whole Word Concept
Tried replacing munro with manro in Family Historian Sample Project.
With default Plugin settings it did not find /Munro/ nor Munro, because the slashes and comma prevents the Whole Words only match.
Maybe the strSearchFor needs to use more than just %s space separators for words, such as any punctuation perhaps.
[%s%p] worked well.
(2) Dialogue Tooltips
I am sure there was also posting asking for details about which fields each replacement Class related to.
This could be assisted by adding Tooltips to the iup.GetParam dialogue.
These would list the most popular actual field names for each Class.
Tooltips would also be useful on some of the other options.
In particular, explain that the alternative to Plain Text Search is Regular Expression Search & Replace.
For example, Search for ([0-9])([0-9]) and Replace with %2%1 will swap any pair of digits.
(1) Whole Word Concept
Tried replacing munro with manro in Family Historian Sample Project.
With default Plugin settings it did not find /Munro/ nor Munro, because the slashes and comma prevents the Whole Words only match.
Maybe the strSearchFor needs to use more than just %s space separators for words, such as any punctuation perhaps.
[%s%p] worked well.
(2) Dialogue Tooltips
I am sure there was also posting asking for details about which fields each replacement Class related to.
This could be assisted by adding Tooltips to the iup.GetParam dialogue.
These would list the most popular actual field names for each Class.
Tooltips would also be useful on some of the other options.
In particular, explain that the alternative to Plain Text Search is Regular Expression Search & Replace.
For example, Search for ([0-9])([0-9]) and Replace with %2%1 will swap any pair of digits.
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Tooltips
Here are some suggestions for Tooltips in the iup.GetParam dialogue:I am not sure that the Text fields and Long Text tooltip lists are exhaustive.
I could not find any fields that matched the Key Words class. Certainly, the Multimedia Keywords are NOT in this class, but in the Text fields class.
Other Classes
Are there any pros or cons to adding the other classes such as:
enumword, enumlist, word, word2, rect, and age text types?
Also date and integer, which would need some specific processing?
Regular Expressions
Regular Expressions with (parenthesis) captures do NOT work in conjunction with the Whole Words only option.
I suggest that in Regular Expression Search mode, if the Search For string contains any (parenthesis) captures, then switch off the Whole Words only option.
Here are some suggestions for Tooltips in the iup.GetParam dialogue:
Code: Select all
'Replace in the following Classes %tn'..
'Text fields: %b{Title, Author, Type, Custom Id, Phone, E-mail, Website, Format, Keywords, etc.}n'..
'Long Text: %b{Address, Where Within Source, Text From Source, Note, etc.}n'..
'Names: %b{Name fields only.}n'..
'Places: %b{Place fields only.}n'..
'Key Words: %b{Word Lists??}n'..
'Extra Options %tn'..
'Whole Words only: %b{Whole words are delimited by spaces, tabs, and punctuation.}n'..
'Plain Text Search: %b{Plain Text or Regular Expression search & replace.}n'I could not find any fields that matched the Key Words class. Certainly, the Multimedia Keywords are NOT in this class, but in the Text fields class.
Other Classes
Are there any pros or cons to adding the other classes such as:
enumword, enumlist, word, word2, rect, and age text types?
Also date and integer, which would need some specific processing?
Regular Expressions
Regular Expressions with (parenthesis) captures do NOT work in conjunction with the Whole Words only option.
I suggest that in Regular Expression Search mode, if the Search For string contains any (parenthesis) captures, then switch off the Whole Words only option.
- Jane
- Site Admin
- Posts: 8442
- Joined: 01 Nov 2002 15:00
- Family Historian: V7
- Location: Somerset, England
- Contact:
Search and Replace Plugin - Calico
I have updated to use [%s%p] and to only do word if plain text is selected, same link as before.
I have also done the tool tips.
I am not sure about adding the other fields as they are not text. In some ways if you need to work on dates I would prefer to see a separate plugin to handle them.
I have also done the tool tips.
I am not sure about adding the other fields as they are not text. In some ways if you need to work on dates I would prefer to see a separate plugin to handle them.
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Do you know what fields match the Key Words class?
What about adding the text types of enumword, enumlist, word, word2, rect, and age?
What about adding the text types of enumword, enumlist, word, word2, rect, and age?
- Jane
- Site Admin
- Posts: 8442
- Joined: 01 Nov 2002 15:00
- Family Historian: V7
- Location: Somerset, England
- Contact:
Search and Replace Plugin - Calico
This is the wordlist value, but I don't know what fields return it.Do you know what fields match the Key Words class?
enumword a word (or short phrase) from a fixed choice of values textWhat about adding the text types of enumword, enumlist, word, word2, rect, and age?
This has fixed values so I would not want to replace items using a general plugin.
enumlist a comma-separated list of words (or short phrases) from a fixed choice of values text
This has fixed values so I would not want to replace items using a general plugin.
word a word (or short phrase) text
I am tempted to add this to the same value as text.
word2 a word (or short phrase), but more tightly restricted (e.g. brackets are not allowed) text
This needs special processing to make sure it can't have invalid data replaced into it.
rect a set of 4 coordinate values text
This is only used on ASIDs and again I can't see a good reason to want to search and replace this.
age age data (in months or years)
Again I can't see why you would want to search and replace this across a whole database.
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
I agree with above explanations.
Perhaps wordlist as well as word should be lumped in with text.
I have done a fairly thorough search of GEDCOM fields with the following results:
Found NO wordlist class fields anywhere.
The only word class I found was the Multimedia Format field.
The revised tooltips based on the search results:
'Text fields: %b{Name Prefix/Suffix/Given/Nickname, Attribute values, Cause, Where Within Source, Title, Type, Custom Id, City, State, Postcode, Country, Phone, E-mail, Website, File, Format, Keywords, Sentence, etc.}n'..
'Long Text: %b{Note, Address, Author, Text From Source, Publication Info, Link/Note.}n'..
Perhaps wordlist as well as word should be lumped in with text.
I have done a fairly thorough search of GEDCOM fields with the following results:
Found NO wordlist class fields anywhere.
The only word class I found was the Multimedia Format field.
The revised tooltips based on the search results:
'Text fields: %b{Name Prefix/Suffix/Given/Nickname, Attribute values, Cause, Where Within Source, Title, Type, Custom Id, City, State, Postcode, Country, Phone, E-mail, Website, File, Format, Keywords, Sentence, etc.}n'..
'Long Text: %b{Note, Address, Author, Text From Source, Publication Info, Link/Note.}n'..
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Two things I have spotted need correcting.
(1)should be
(2)should bei.e. remove duplicated {
(1)
Code: Select all
if pWhole == 1 then
-- Special Case search for last word and first wordCode: Select all
if pWhole == 1 and pPlain == 1 then
-- Special Case search for last word and first wordCode: Select all
'Text fields: %b{{Name Prefix ...Code: Select all
'Text fields: %b{Name Prefix ...- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Here is another refinement you might like in function srPrompt.
becomesWhat this does is calculate how many visiblelines are needed to display the text.
It iterates over the text line by line, and guesses how many GUI lines each text line it will wrap over, assuming about 100 chars per GUI line.
The math.ceil function rounds up to next integer, so even short text lines will register as one GUI line.
Code: Select all
inp_from_string.multiline = 'YES'
inp_from_string.size = '0x80'
inp_from_string.wordwrap = 'YES'
inp_to_string.multiline = 'YES'
inp_to_string.size = '0x80'
inp_to_string.wordwrap = 'YES'Code: Select all
local intLines = 1
for strLine in string.gmatch(strFrom..'n','(.-)n') do
intLines = intLines + math.ceil(string.len(strLine)/100)
end
inp_from_string.visiblelines = intLines
inp_from_string.multiline = 'YES'
inp_from_string.wordwrap = 'YES'
intLines = 1
for strLine in string.gmatch(strTo..'n','(.-)n') do
intLines = intLines + math.ceil(string.len(strLine)/100)
end
inp_to_string.visiblelines = intLines
inp_to_string.multiline = 'YES'
inp_to_string.wordwrap = 'YES'It iterates over the text line by line, and guesses how many GUI lines each text line it will wrap over, assuming about 100 chars per GUI line.
The math.ceil function rounds up to next integer, so even short text lines will register as one GUI line.
- Jane
- Site Admin
- Posts: 8442
- Joined: 01 Nov 2002 15:00
- Family Historian: V7
- Location: Somerset, England
- Contact:
Search and Replace Plugin - Calico
I'll think about the visible lines, as it won't work if there are very long notes as you could easily end up with a dialogue bigger than the viewport, so it needs more complex maths to work out the height of lines for the selected font to compare with the height of the available screen size.
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Fair point, so change as follows, so number of GUI lines is limited to 9 or whatever you think is a reasonable limit:
inp_from_string.visiblelines = math.min(intLines,9)
inp_to_string.visiblelines = math.min(intLines,9)
inp_from_string.visiblelines = math.min(intLines,9)
inp_to_string.visiblelines = math.min(intLines,9)
- tatewise
- Megastar
- Posts: 27088
- Joined: 25 May 2010 11:00
- Family Historian: V7
- Location: Torbay, Devon, UK
- Contact:
Search and Replace Plugin - Calico
Further comments on function srPrompt().
(1) The following two statements need deleting, otherwise the visiblelines value has no effect:
inp_from_string.size = '0x80'
inp_to_string.size = '0x80'
(2) There is a snag with the statement dlg.minsize = dlg.size because minsize units are pixels whereas size units are fractions of character.
One solution is to use the actual screen size to set the GUI size.
Add this function:
-- Split a string into numbers using separators space or comma or x --
function string:SplitNumbers()
local tblNum = {}
self:gsub('([^%s,x]+)', function(c) tblNum[#tblNum+1] = c end)
for i=1, #tblNum do
tblNum = tonumber(tblNum)
end
return tblNum
end -- function string:SplitNumbers
In function srPrompt() remove ,minsize='150' from:
local inp_from_string = iup.text{expand='HORIZONTAL'}
Add the following statements just before local dlg = ....
local tblScrn = iup.GetGlobal('VIRTUALSCREEN'):SplitNumbers()
-- tblScrn[1] = origin x, tblScrn[2] = origin y, tblScrn[3] = width, tblScrn[4] = height
local intWidth = tblScrn[3]
In local dlg = ... replace size='HALF' with rastersize=intWidth/2.
Later on replace dlg.minsize = dlg.size with dlg.minsize = dlg.rastersize.
(3) In function Replace(ptr) the second test is redundant in:
if pConfirm == 1 and strFromString ~= strToString then
because it is immediately preceded by:
if strFromString ~= strToString then
(1) The following two statements need deleting, otherwise the visiblelines value has no effect:
inp_from_string.size = '0x80'
inp_to_string.size = '0x80'
(2) There is a snag with the statement dlg.minsize = dlg.size because minsize units are pixels whereas size units are fractions of character.
One solution is to use the actual screen size to set the GUI size.
Add this function:
-- Split a string into numbers using separators space or comma or x --
function string:SplitNumbers()
local tblNum = {}
self:gsub('([^%s,x]+)', function(c) tblNum[#tblNum+1] = c end)
for i=1, #tblNum do
tblNum = tonumber(tblNum)
end
return tblNum
end -- function string:SplitNumbers
In function srPrompt() remove ,minsize='150' from:
local inp_from_string = iup.text{expand='HORIZONTAL'}
Add the following statements just before local dlg = ....
local tblScrn = iup.GetGlobal('VIRTUALSCREEN'):SplitNumbers()
-- tblScrn[1] = origin x, tblScrn[2] = origin y, tblScrn[3] = width, tblScrn[4] = height
local intWidth = tblScrn[3]
In local dlg = ... replace size='HALF' with rastersize=intWidth/2.
Later on replace dlg.minsize = dlg.size with dlg.minsize = dlg.rastersize.
(3) In function Replace(ptr) the second test is redundant in:
if pConfirm == 1 and strFromString ~= strToString then
because it is immediately preceded by:
if strFromString ~= strToString then