Dinamic numbering
-
- Posts: 4
- Joined: 2007-08-02 07:16:14
Dinamic numbering
I was wondering if there's a way to make a number present in the page (not in a footnote or in the summary) dependant on other numbers.
For instance, I'm including a series of examples in a chapter and they're all preceded by the sentence:
Example 1: how to do this
What I'm trying to achieve is to make the number "1" dynamic: this way, if I put an example before it, the current example nr. 1 will become nr. 2 and the new one will receive the nr. 1.
This would be a huge timesaver, since I won't have to review every chapter to see if someone made some changes.
Any suggestion?
For instance, I'm including a series of examples in a chapter and they're all preceded by the sentence:
Example 1: how to do this
What I'm trying to achieve is to make the number "1" dynamic: this way, if I put an example before it, the current example nr. 1 will become nr. 2 and the new one will receive the nr. 1.
This would be a huge timesaver, since I won't have to review every chapter to see if someone made some changes.
Any suggestion?
-----
ciao, ric
ciao, ric
- martin
- Official Nisus Person
- Posts: 5230
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
I suppose you could create a macro that would do what you wish, but you'd have to run it in post each time after your document was complete to fix up the counters.
So now whenever you want to have one of these counters in your document you insert the text "[Counter]" into your document. Later you can run the macro to generate the numbers.
One other possibly solution is via List Styles. The only issue is that NWP insists on adding a tab character after the automated list item. If you can find a way to live with that, then here's what to do:
1. Create a new List Style via the menu Format > Lists > New List Style.
2. Call the new style Equations (or whatever you like) and make sure the Continue throughout document option is checked. This ensures that all list items/bullets/markers are consecutively numbered even if their content is separated.
3. The list style should be applied automatically, so now use the Lists palette to configure it. You'll want to set the "before text" to "Example " and the "after text" to ":".
Really NWP needs an arbitrary automatic variable feature (which is definitely already on our todo list).
Code: Select all
# This macro searches your document for special bits of text that indicate where an ever
# increasing numeric counter should be placed.
$marker = '[Counter]'
$count = 0
Set Selection 1, 0
While Find $marker
Begin Perl
$count++;
End
Insert Text $count
End
One other possibly solution is via List Styles. The only issue is that NWP insists on adding a tab character after the automated list item. If you can find a way to live with that, then here's what to do:
1. Create a new List Style via the menu Format > Lists > New List Style.
2. Call the new style Equations (or whatever you like) and make sure the Continue throughout document option is checked. This ensures that all list items/bullets/markers are consecutively numbered even if their content is separated.
3. The list style should be applied automatically, so now use the Lists palette to configure it. You'll want to set the "before text" to "Example " and the "after text" to ":".
Really NWP needs an arbitrary automatic variable feature (which is definitely already on our todo list).
-
- Posts: 4
- Joined: 2007-08-02 07:16:14
- martin
- Official Nisus Person
- Posts: 5230
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
If you've upgraded to Pro 1.0.1 you could also use this (faster) macro instead:
Code: Select all
# This macro searches your document for special bits of text that indicate where an ever
# increasing numeric counter should be placed.
$marker = '[Counter]'
$count = 0
Set Selection 1, 0
While Find $marker
$count += 1
Insert Text $count
End
Thanks for this useful macro, Martin. Still I think it would be even more useful if, instead of replacing the marker by a serial number, you would leave the marker and append the serial number to it. This would make it possible then to upgrade the process from time to time while still continuing your work on the document. But I found that finding the $marker together with the appended serial number leads to an infinite regress. Can the find-replace process be stopped somehow at the end of the document?Code: Select all
# This macro searches your document for special bits of text that indicate where an ever # increasing numeric counter should be placed. $marker = '[Counter]' $count = 0 Set Selection 1, 0 While Find $marker $count += 1 Insert Text $count End
[/quote][/code]
- martin
- Official Nisus Person
- Posts: 5230
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
It can- you'll want to make two changes. The first is to specify that the Find command should not wrap around to the start of the document. The "wrap around" option is turned on with the "W" character, which you disable by prefixing the "W" with a minus:js wrote:I found that finding the $marker together with the appended serial number leads to an infinite regress. Can the find-replace process be stopped somehow at the end of the document?
Code: Select all
While Find $marker, '-W'
Code: Select all
Insert Text "$marker$count"
Select End
Code: Select all
Type Text "$marker$count"
Thank you. So I did this:
This works quite well. But if you repeat the process, numbers are added instead of replaced. To do replace them it would be necessary of doing a Find of the $marker together with any number following it. Of course you could achieve the desired result in a separate go, deleting any numbers following the [Counter] and then using your above macro. But I was wondering whether this could be done directly.
Code: Select all
$marker = '[Counter]'
$count = 0
Set Selection 1, 0
While Find $marker, '-W'
$count += 1
Type Text "$marker$count"
End
- martin
- Official Nisus Person
- Posts: 5230
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
It can be done directly, but will require the use of PowerFind Pro. Basically we want to change the find expression to match the marker plus any number of digits that follow it.
Things get a little tricky with those string literals because of the various meta-characters involved. In a PowerFind Pro expression the square brackets have a special meaning, so we must precede them with a backslash to indicate that we want to match actual bracket characters. But you'll see that I actually use two backslashes because in a double-quoted string literal the backslash also has a special meaning.
Following the translations the string takes will help. First the literal as typed into the macro file:
\\[$markerName\\]\\d*
..is parsed/interpolated by the macro interpreter to be:
\[Counter\]\d*
You'll see that each double-backslash has been collapsed to a single backslash and the value of the variable $markerName has been inserted. This string is then fed to PowerFind Pro. To the find engine "\[" and "\]" mean to match literal brackets, while "\d*" means match zero or more digits.
If all this makes no sense, then don't worry and just use the macro
Code: Select all
$markerName = 'Counter'
$count = 0
Set Selection 1, 0
While Find "\\[$markerName\\]\\d*", 'E-W'
$count += 1
Type Text "[$markerName]$count"
End
Following the translations the string takes will help. First the literal as typed into the macro file:
\\[$markerName\\]\\d*
..is parsed/interpolated by the macro interpreter to be:
\[Counter\]\d*
You'll see that each double-backslash has been collapsed to a single backslash and the value of the variable $markerName has been inserted. This string is then fed to PowerFind Pro. To the find engine "\[" and "\]" mean to match literal brackets, while "\d*" means match zero or more digits.
If all this makes no sense, then don't worry and just use the macro

Re: Dinamic numbering
Automatic numbers of that type is not available yet but, in recent versions of NWP, you can use a macro like this to update numbers. Let’s assume you have a document like this:riccardino wrote:For instance, I'm including a series of examples in a chapter and they're all preceded by the sentence:
Example 1: how to do this
What I'm trying to achieve is to make the number "1" dynamic: this way, if I put an example before it, the current example nr. 1 will become nr. 2 and the new one will receive the nr. 1.
… blah blah Example 1: blah … blah Example 2: blah … blah Example 3: blah … blah Example 4: blah …
If you want to add an example before Example 2, just add it with an arbitary number, e.g. 0.
… blah blah Example 1: blah … blah Example 0: blah … blah Example 2: blah … blah Example 3: blah … blah Example 4: blah …
After runing the macro, the text will be
… blah blah Example 1: blah … blah Example 2: blah … blah Example 3: blah … blah Example 4: blah … blah Example 5: blah …
Repeat the procedure above when you add new examples.
Code: Select all
### Update Numbers ###
# Update numbers having a prefix and/or a suffix defined in $prefix and $suffix.
# This macro works on selection(s). If there is no selection, the whole document will be processed.
# Cross-references are ignored.
$prefix = 'Example '
$suffix = ':'
$where = '-am' # in main body only (as to where argument, see "COMMANDS - Find and Replace" in Nisus Macro Reference)
Require Pro Version 1.3
$doc = Document.active
if $doc == undefined # if there is no open document...
exit # then, the macro was run accidentally
end
$findExpression = '(?<=\Q' & $prefix
$findExpression &= '\E)\d+(?=\Q' & $suffix
$findExpression &= '\E)'
# $findExpression: (?<=\Q$prefix\E)\d+(?=\Q$suffix\E)
# (?<=***): preceded by ***
# (?=***): followed by ***
# characters between \Q and \E are treated literally (i.e. not as metacharacters)
$options = 'E-i' # E: PowerFind Pro; -i: case-sensitive
if $doc.textSelection.length # if some text is selected...
$options &= 's' # s: in selections
end
$n = Find All $findExpression, $options, $where
if !$n # $n: number of founds
exit 'Nothing found, exiting...'
end
$sels = $doc.textSelections
Select Start # deslect selections to avoid performance hit
foreach $i, $sel in reversed $sels
$s = Cast to String $sel.subtext # $s: "[Referenced content is missing.]" if it is a cross-reference
if $s != $sel.substring # if it is a cross-reference...
$sels.removeValueAtIndex $i
end
end
foreach $i, $sel in reversed $sels
$sel.text.replaceInRange $sel.range, $i + 1
end
### end of macro ###
Code: Select all
$doc = Document.active
$sels = $doc.textSelections
$n = $sels.count
foreach $sel in reversed $sels
$sel.text.replaceInRange $sel.range, $n
$n -= 1
end
Edit2: fixed a stupid bug introduced by the modification of the macro.
Edit3: modified the explanation a bit.