Listing documents presently open

Get help using and writing Nisus Writer Pro macros.
Post Reply
js
Posts: 229
Joined: 2007-04-12 14:59:36

Listing documents presently open

Post by js » 2009-04-26 13:53:43

Sometimes on closing a session, I would like to keep a list of documents presently open to reopen them later. I see that you can get them all at once with „Document.openDocuments“. But what is an efficient way to get the paths on one line each and save them in a document with todays date in it‘s name? Can somebody help?

Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Listing documents presently open

Post by Kino » 2009-04-27 08:04:00

Here are macros for that. They are not particularly efficient. Or rather you don’t need worrying about the efficiency for this kind of macros, not dealing with a large amount of data. I think you don’t open a thousand of documents at once ;-)

Code: Select all

### Create Document Path List ###

$baseDir = '~/Documents/Document Path Lists/'
# Customize the path above so that it fits your need.
# Indermediate folders ("Document Path Lists" in the example above) will be created automatically.

Require Pro Version 1.2
$docs = Document.openDocuments
$LF = Cast to String "\n"  # remove from \n its attributes (in the macro file)
$documentPathsList = ''

foreach $doc in $docs
	if $doc.filePath != undefined  # if it is a saved document having a path...
		$documentPathsList &= $doc.filePath.abbreviatedFilePath & $LF
	end
end

if ! $documentPathsList
	exit 'No saved document is open, exit...'
end

$documentPathsList &= $LF  # Nisus Writer Pro does not display the last LF
$documentPathsList = Encode RTF $documentPathsList  # output as RTF to avoid possible encoding problems

$now = Date.now
$Y = $now.year
$M = Date.zeroPad $now.month
$D = Date.zeroPad $now.day
$outputPath = $baseDir & "OpenDocuments $Y-$M-$D.rtf"  # e.g. "OpenDocuments 2009-05-07.rtf"
$i = 2

while File.existsAtPath $outputPath  # append a number if there is alerady a file having the same path
	$outputPath = $baseDir & "OpenDocuments $Y-$M-$D($i).rtf"
	$i += 1
end

File.writeDataToPath $documentPathsList, $outputPath
File.revealPathInFinder $outputPath
And this one opens documents from a list created by the first macro. The find expression for getting file paths is strict enough so that comments you might have added to the document path list will be ignored unless they resemble file paths closely.

Code: Select all

### Open from Document Path List ###

$doc = Document.active
$numfound = Find All '^~?(?:/[^/]+)+$', 'E'

if ! $numfound
	exit "No file path found, exit..."
end

$paths = $doc.selectedSubtexts
$error = ''

foreach $path in $paths
	if File.canReadFromPath $path
		Open $path
	else
		$error &= "• '$path' could not be opened.\n"
	end
end

if $error  # show $error if it is not empty
	exit $error
end

Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Listing documents presently open

Post by Kino » 2009-04-27 08:05:32

What is annoying with those macros is that [1] you have to manage two macros and [2] you have to open a Document Path List file before running the second macro. Then, here is a macro which generates, instead of a list of document paths, a macro which opens them and put it in a submenu under Macro menu.

Code: Select all

### Macro Generating “Open Past Documents Macro” ###

$macroSubFolder = '/Open Past Documents/'  # give your favourite subfolder name

$docs = Document.openDocuments
$macro = ''

foreach $doc in $docs
	if $doc.filePath != undefined  # if it is a saved document having a path...
		$macro &= $doc.filePath.abbreviatedFilePath & "\n"
	end
end

if ! $macro
	exit 'No saved document is open, exit...'
end

$macro.replaceAll '(?=\'|\‘|\’)', '\x5C', 'E'  # put backslash (\x5C) before single quotes
$macro.replaceAll '^.+$', '$docPaths.appendValue \'\0\'', 'E'
$macro.findAndReplace '\A', '$docPaths = Array.new\n', 'E'  # \A: beginning of string
$macro &= "\n\$error = ''\n\n"
$macro &= "foreach \$path in \$docPaths\n"
$macro &= "\tif File.canReadFromPath \$path\n"
$macro &= "\t\tOpen \$path\n\telse\n"
$macro &= "\t\t\$error &= \"• '\$path' could not be opened.\\n\"\n"
$macro &= "\tend\nend\n\n"
$macro &= "if \$error\n\texit \$error\nend\n\n"

$macro = Cast to String $macro
$macro = Encode RTF $macro

$now = Date.now
$Y = $now.year
$M = Date.zeroPad $now.month
$D = Date.zeroPad $now.day
$baseDir = User Property 'macros folder path'
$baseDir &= $macroSubFolder
$macroPath = $baseDir & "OpenDocuments $Y-$M-$D.nwm"  # e.g. "OpenDocuments 2009-05-07.nwm"
$i = 2

while File.existsAtPath $macroPath  # append a number if there is alerady a file having the same path
	$macroPath = $baseDir & "OpenDocuments $Y-$M-$D($i).nwm"
	$i += 1
end

File.writeDataToPath $macro, $macroPath
Refresh Macro Menu
$macroPath.findAndReplace '^.+/', '', 'E'
exit "'$macroPath' macro has been added."
Edit: I corrected a typo and added two comments to the macro (2009-04-28 21:26 GMT+9:00).

js
Posts: 229
Joined: 2007-04-12 14:59:36

Re: Listing documents presently open

Post by js » 2009-04-28 13:36:09

These are great macros, very useful to track one's work and get back to past contexts. Thanks a lot, I will use these often. They are also great stuff to learn about the language itself.

In this context I have often wondered why the Nisus Macro language does not offer access to the database the system must be using to keep itself in order. The obvious advantage would be that the reference to a document would still be valid if move it around in your folder structure. And you could create hyperlinks. I don't quite understand why Nisus can create a hyperlink only to .html documents, but not to it's own .rtf documents. Would a Nisus person explain why that is?

User avatar
martin
Official Nisus Person
Posts: 4261
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Listing documents presently open

Post by martin » 2009-04-29 10:11:02

js wrote:I don't quite understand why Nisus can create a hyperlink only to .html documents, but not to it's own .rtf documents. Would a Nisus person explain why that is?
You can create hyperlinks to normal files, but there are some limitations. In the Insert Hyperlink dialog you will want to use something like "file:///Users/you/Desktop/file.rtf". The URLs you enter here are passed directly to the system, so how they are handled has the same limitations:

1. The URL must be absolute, eg: you could not use "file://~/Desktop/file.rtf".
2. What happens when you click the link depends on your system. Starting with Leopard file URLs no longer directly open in an application, instead the files are shown in the Finder. I would guess Apple made the change as a security precaution.

js
Posts: 229
Joined: 2007-04-12 14:59:36

Re: Listing documents presently open

Post by js » 2009-04-29 12:56:44

You can create hyperlinks to normal files, but there are some limitations. In the Insert Hyperlink dialog you will want to use something like "file:///Users/you/Desktop/file.rtf". The URLs you enter here are passed directly to the system, so how they are handled has the same limitations:

1. The URL must be absolute, eg: you could not use "file://~/Desktop/file.rtf".
This does not look like a very useful device then, but couldn't Nisus at least add the necessary prefix (file:// and the path to one's home)? But what I don't quite understand is this: Let's say I open a document in Nisus, then close it again, then move the document into another folder. If now I use the "Open recent" Menu, Nisus promptly finds the document in spite of it's recent displacement. From this one would say that the Open recent menu has direct acces to the Systems' database, which seems to be dynamic. Is it not possible to make the macro language provide this access? This would provide real hyperlinks.

User avatar
martin
Official Nisus Person
Posts: 4261
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Listing documents presently open

Post by martin » 2009-04-29 13:17:41

I understand your point now. The Open Recent menu is managed by Apple and internally uses aliases to track files as they move about, eg: like the "Make Alias" command does in the Finder. It would be possible for the macro language to provide commands that allows manipulation of aliases, though it currently does not.

Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Listing documents presently open

Post by Kino » 2009-07-01 06:57:02

js wrote:But what I don't quite understand is this: Let's say I open a document in Nisus, then close it again, then move the document into another folder. If now I use the "Open recent" Menu, Nisus promptly finds the document in spite of it's recent displacement. From this one would say that the Open recent menu has direct acces to the Systems' database, which seems to be dynamic. Is it not possible to make the macro language provide this access? This would provide real hyperlinks.
Document Manager has been totally renewed in Nisus Writer Pro 1.3. To manage files, you don't need putting them or their alias in Nisus Documents folder any more. And it does "find the document in spite of it's recent displacement". So I think this kind of job is done more efficiently by new Document Manager macro commands.

Code: Select all

### Take a Snapshot of Open Documents ###

# Create a new User group in Document Manager and add currently open documents to it.

# You cannot add unsaved documents to it. They will be simply ignored.

$newGroupBaseName = 'Snapshot'  # cusomize the name as you like

Require Pro Version 1.3
$docMan = DocumentManager.instance
$currentlyOpen = $docMan.groupWithName 'Currently Open'
$filePaths = $currentlyOpen.allFilePaths

if ! $filePaths.count  # i.e. if $filePaths.count is zero
	exit "No open file, exit..."
end

$unsavedFileCount = $savedFileCount = 0
foreach $i, $path in reversed $filePaths
	if $path == undefined
		$unsavedFileCount += 1
		$filePaths.removeValueAtIndex $i  # remove unsaved new documents from $filePaths
	else
		$savedFileCount += 1
	end
end

if ! $savedFileCount
	exit 'No saved document is open, exit...'
end

$now = Date.now
$Y = $now.year
$M = Date.zeroPad $now.month
$D = Date.zeroPad $now.day
$newGroupName = $newGroupBaseName &= " $Y-$M-$D"  # customize date format as you like
$newGroup = $docMan.addUserGroupWithName $newGroupName

$i = 2
while $newGroup == undefined  # while a group of the same name already exists...
	$newGroupName = $newGroupBaseName & " ($i)"  # add a number ($i) to the group name
	$newGroup = $docMan.addUserGroupWithName $newGroupName
	$i += 1
end

foreach $path in $filePaths
	$newGroup.addFilePath $path
end

$message = "\"$newGroupName\" ($savedFileCount files) has been created in Document Manager."

if $unsavedFileCount  # i.e. if $unsavedFileCount is greater than zero
	$message &= "\n\n$unsavedFileCount unsaved new file(s) could not be added."
end

exit $message

### end of macro ###

Post Reply