Reply to topic  [ 13 posts ] 
Dinamic numbering 
Author Message

Joined: 2007-08-02 07:16:14
Posts: 4
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?

_________________
-----
ciao, ric


2007-08-02 07:25:08
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Post 
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.

Code:
# 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


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).


2007-08-02 13:38:15
Profile WWW

Joined: 2007-08-02 07:16:14
Posts: 4
Post 
martin wrote:
":".

Really NWP needs an arbitrary automatic variable feature (which is definitely already on our todo list).


In the meanwhile, both option are perfectly acceptable, to me.

Thanks a lot, Martin :-)

_________________
-----
ciao, ric


2007-08-02 23:08:02
Profile

Joined: 2007-09-22 11:07:40
Posts: 12
Post 
Hello Martin
Probably a bit late on this as I've only just joined, but I have a use for your counter macro coded above. Unfortunately I keep getting an error message on the $count line. Any help would be appreciated.
Thanks


2007-09-22 12:34:00
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Post 
Hi Tony- the problem is that the code copies from Safari with non-breaking spaces, which Perl does not care for. Try replacing all non-breaking spaces with regular spaces and then running the macro.


2007-09-22 16:28:31
Profile WWW
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Post 
If you've upgraded to Pro 1.0.1 you could also use this (faster) macro instead:

Code:
# 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


2007-09-22 16:32:36
Profile WWW

Joined: 2007-09-22 11:07:40
Posts: 12
Post 
Many thanks Martin - worked like a charm


2007-09-22 17:52:24
Profile

Joined: 2007-04-12 14:59:36
Posts: 229
Post 
Quote:
Code:
# 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?


[/quote][/code]


2007-09-25 04:27:34
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Post 
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?

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:
Code:
While Find $marker, '-W'


The second change you'll need to make is to deselect the text after the replacement has been made, otherwise that exact same instance will be found again. You have two ways to do this, either add a selection command after the replacement, eg:
Code:
Insert Text "$marker$count"
Select End


Or change "insert text" to "type text", which automatically places the caret after the inserted text:
Code:
Type Text "$marker$count"


2007-10-01 12:25:24
Profile WWW

Joined: 2007-04-12 14:59:36
Posts: 229
Post 
Thank you. So I did this:

Code:
$marker = '[Counter]'
$count = 0

Set Selection 1, 0
While Find $marker, '-W'
   $count += 1
   Type Text "$marker$count"
End


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.


2007-10-02 11:37:50
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Post 
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.
Code:
$markerName = 'Counter'
$count = 0

Set Selection 1, 0
While Find "\\[$markerName\\]\\d*", 'E-W'
   $count += 1
   Type Text "[$markerName]$count"
End


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 :)


2007-10-02 13:09:44
Profile WWW

Joined: 2007-04-12 14:59:36
Posts: 229
Post 
Great. This works just fine. A user might have to keep in mind that the counter in his text has to be put into brackets.
Thanks.


2007-10-02 23:27:43
Profile

Joined: 2008-05-17 04:02:32
Posts: 400
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.

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:

… 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:
### 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 ###

When the numbers do not have a prefix or a suffix distinguishing them from other numbers used in the document, I think a handy way would be to create a character style, e.g. Figure Number, and apply it on them. Then, you can update them by [1] selecting one of them, [2] selecting all of them using Select All in the Character Stlye tag on the statusbar and running the following macro.
Code:
 $doc = Document.active
$sels = $doc.textSelections
$n = $sels.count
foreach $sel in reversed $sels
   $sel.text.replaceInRange $sel.range, $n
   $n -= 1
end


Edit: added some explanation and modified the first macro so that cross-references are ignored.
Edit2: fixed a stupid bug introduced by the modification of the macro.
Edit3: modified the explanation a bit.


2009-12-26 21:58:14
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 13 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software