Hi Allen,
right, so you want to identify, for a given location, the chapter/section/sub-section that you are currently located in. One approach is indeed to just search backward to the nearest heading and report.
The alternative in macro language will be to find all the headings and determine which is the closest (by comparing the locations in a loop).
The latter approach may strike you as excessively complicated, but due to some powerful constructs that Nisus Macro language has you can probably write it in a half-dozen lines. But what I was really driving at was actually the question: "Why are you starting from a given selection?". Is it because you want a macro that the user can trigger at any given moment for just one location, or is it just because you are trying to divide and conquer a bigger task? If the latter, than obviously you could write a macro to do just one case, and then put that in a loop that runs a hundred times, but that would be
very inefficient. Instead it would be much better to create a macro that processes hundreds of locations in one go. In that case the macro language approach will be far superior.
Anyhow let me start with your last question, which can serve as an introduction into how the macro language approach works:
allenwatson wrote:How can I determine whether the first character of a selection is a digit or an alphabetic character?
If your current selection is only one paragraph long, you could use Find like this:
Code: Select all
if Find '^\d+', 'Es'
prompt 'Starts with a digit'
end
By adding the '^' (caret) to the search expression, I am asking it to find only characters at the beginning of the line, and by limiting the search to the selection, I stop Nisus from finding matches outside of the selection. But this approach will probably not quite do what you are looking for. For example it won't work, if the selection does not start at the beginning of a line.
The alternative is to directly ask what the character is at the beginning of the selection. You can do this like this:
Code: Select all
$sel = TextSelection.active
$firstChar = $sel.text.characterAtIndex $sel.location
prompt $firstChar
This will show you the first character, but it will show it as a character value (so "1" will give the result "49"). So if you want to know if it's a digit you will have to check, whether the character value is between 48 and 57 inclusive.
Instead you could get the actual first character as a string and then check to see if it contains any digits. That would look like this:
Code: Select all
$sel = TextSelection.active
$range = Range.new 0,1
$firstChar = $sel.substring.substringInRange $range
if $firstChar.find('\d', 'E')
prompt 'First Character is a digit'
end
This code starts by creating a range object which it uses to "slice out" the first character from the selection. It then runs a Find command on just that sliced out bit.