Translate metadata to field content
Mark Waddingham
mark at livecode.com
Thu Feb 20 02:56:59 EST 2020
On 2020-02-19 21:40, Niggemann, Bernd via use-livecode wrote:
> here is Richard's script which I changed to get the number of words of
> the line with the tagged word, the number of lines are taken from the
> array.
>
> The tagged word is then: word tNumWords of line (current array key)
>
> ---------------------------------------------------------
> put item 2 of the extents of tDataA into tExtents
> repeat with i = 1 to tExtents
> put item 2 of the extents of tDataA[i]["runs"] into tCounter
> repeat with j = 1 to tCounter
> if tDataA[i]["runs"][j]["metadata"] is tSearchText then
> repeat with m = 1 to j
> add the number of words of tDataA[i]["runs"][m]["text"]
> to tNumWords
> end repeat
> put true into tFlagExit
> exit repeat
> end if
> end repeat
> if tFlagExit then exit repeat
> end repeat
> ---------------------------------------------------------
>
> select word tNumWords of line i of field "x"
That approach is much better than my suggested one, and is independent
of the soft breaks of the text as well :)
It can be made a little more efficient though...
[ DISCLAIMER: I don't have any test data to run these on - so the
following code snippets have not been tested in any way - or
syntax/error checked :D ]
NON-UNIQUE ANCHORS
If the anchors used are non-unique and you want the first matching
anchor in the page from top to bottom / left to right then...
1. Using 'the number of elements of' rather than 'the extents' saves
some time. As the arrays in question are known to be sequences, the
number of elements of SEQUENCE == item 2 of the extents of SEQUENCE
2. Factoring out the common array lookups will save some time.
With these two changes you'd have:
repeat with i = 1 to the number of elements in tDataA
local tRunsA
put tDataA[i]["runs"] into tRunsA
repeat with j = 1 to the number of elements in tRunsA
if tRunsA[j]["metadata"] is tSearchText then
repeat with m = 1 to j
add the number of words of tRunsA[m]["text"] to tNumWords
put true into tFlagExit
exit repeat
end repeat
end if
end repeat
if tFlagExit then
exit repeat
end if
end repeat
select word tNumWords of line i of field "x"
UNIQUE ANCHORS
If the anchors being searched for are unique in a document, then using
repeat for each key in both loops will save some time. Although the
search order in the runs and lines will be arbitrary (hash-order), as
the thing being searched for is unique this doesn't matter.
[ The reason this should be faster is that the engine doesn't need to
process the index vars (i / j) before looking up in the array. ]
repeat for each key i in tDataA
local tRunsA
put tDataA[i]["runs"] into tRunsA
repeat for each key j in tRunsA
if tRunsA[j]["metadata"] is tSearchText then
repeat with m = 1 to j
add the number of words of tRunsA[m]["text"] to tNumWords
put true into tFlagExit
exit repeat
end repeat
end if
end repeat
if tFlagExit then
exit repeat
end if
end repeat
select word tNumWords of line i of field "x"
RUN WITH METADATA DEFINES SELECTION - NON-UNIQUE SEARCH
If the area you want to select is defined by the run with metadata being
searched for, then you can avoid words altogether and just count
codeunits. Codeunits are the fastest chunk to count as they don't need
any iteration of the content of the string being queried:
repeat with i = 1 to the number of elements in tDataA
local tRunsA
put tDataA[i]["runs"] into tRunsA
repeat with j = 1 to the number of elements in tRunsA
local tRunA
put tRunsA[j] into tRunA
if tRunA["metadata"] is tSearchText then
repeat with m = 1 to j - 1
add the number of codeunits of tRunsA[m]["text"] to
tNumCodeunitsBefore
put the number of codeunits in tRunA["text"] into tNumCodeunits
put true into tFlagExit
exit repeat
end repeat
end if
end repeat
if tFlagExit then
exit repeat
end if
end repeat
select codeunit tNumCodeunitsBefore to tNumCodeunitsBefore +
tNumCodeunits - 1 of line i of field "x"
Mutatis mutandis for the unique case using repeat for each key.
Again - none of these methods require formattedStyledText, just
styledText (indeed formattedStyledText wouldn't work with this approach
as that adds extra codeunits - the VTABs - for the soft-breaks which
aren't actually there!).
Hope this helps!
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list