Reply to topic  [ 9 posts ] 
Paper size macro? 
Author Message

Joined: 2007-11-09 15:27:25
Posts: 86
I have a few hundred rtf files with the paper size (in File -> Page Setup) set to something ridiculously small. I'd like to change all of these to US Letter.

Is it possible to put together a macro or applescript to do this so that I can avoid opening each one individually and making the changes manually?


2009-07-27 06:25:35
Profile

Joined: 2008-05-17 04:02:32
Posts: 400
Hello again,

This macro seems to work. Gather those files in a folder, run the macro which will ask you to choose a folder. It will produce new files whose paper size set to US Letter.

To achieve it, the macro changes values of rtf directives. That is feasible because rtf is a kind of markup language like html. Not very readable, though.
Code:
### Change Paper Size ###

# From rtf files in a folder, this macro generates new files with page size set to $width and $height.

# This macro does not change margins. So resulting files may not look good.

# Only files having "rtf" as file extension are processed.

# Generated files will be saved in the same folder as that of the source file, that of the original if it is a symlink or alias.

# Files for which converted file already exists will be ignored.

# If "Keep prior copy of each files using the file name suffixv is enabled in "Preferences - Saving", backup files will be ignored.

Require Pro Version 1.3

$suffix = ' (US Letter)'  # settings for US Letter
$width = 12240
$height = 15840

#$suffix = ' (A4)'  # settings for A4
#$width = 11900
#$height = 16840

#$suffix = ' (JB5)'  # settings for JB5
#$width = 10320
#$height = 14580


$defaultFolderPath = '~/Documents'
$openButtonCaption = 'Choose a Folder'
$folderPath = Choose Folder $defaultFolderPath, $openButtonCaption
if $folderPath == undefined
   exit  # cancelled by the user
end

$fileNames = File.namesInFolderAtPath $folderPath
$keepLastCopy = Read User Default 'com.nisus.backup.keepLastCopy'

if $keepLastCopy == true
   $lastCopySuffix = Read User Default 'com.nisus.backup.lastCopySuffix'
   $lastCopySuffix = '\Q' & $lastCopySuffix
   $lastCopySuffix &= '.\E[^.]+$'
   foreach $i, $fileName in reversed $fileNames
      if $fileName.find $lastCopySuffix, 'E-i'
         $fileNames.removeValueAtIndex $i
      end
   end
end

$errors = ''
foreach $fileName in $fileNames
   if $fileName.filePathExtension == 'rtf'
      $filePath = $folderPath.filePathByAppendingComponent $fileName
      $filePath = $newPath = File.resolveLinkAtPath $filePath
      $newPath.findAndReplace '(?=\.rtf)', $suffix, 'E'
      if File.existsAtPath $newPath
         $errors &= "File converted from $fileName already exists.\n"
      else
         $data = File.readDataFromPath $filePath
         $data = Cast to String $data
         $data.replaceAll '(?<=\x5Cpaperw|\x5Cpgwsxn)[0-9]+', $width, 'E-i'
         $data.replaceAll '(?<=\x5Cpaperh|\x5Cpghsxn)[0-9]+', $height, 'E-i'
         File.writeDataToPath $data, $newPath
      end
   end
end

File.revealPathInFinder $folderPath

if $errors
   exit $errors
end

### end of macro ###


2009-07-27 09:18:36
Profile

Joined: 2007-11-09 15:27:25
Posts: 86
Thank you, Kino. This is fabulous.
I don't know how you manage to perform such minor miracles, and so quickly.

All I can say is Nisus don't pay you enough.

I've made just a small change so that the newly created file has a different 'suffix' added. Just personal taste. (For me this is serious programming :)

Thanks many times.


2009-07-27 09:45:13
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Yes, Kino's macros and help are fantastic- we are very lucky to have such a dedicated user! :)

Interpreting RTF is tricky business, and there is one danger with the way Kino's macro is written. Although RTF may appear to be "plain text" codes, like HTML, it actually must be handled as a binary stream, as it is legal to embed arbitrary binary data inside (eg: an image). When Kino's macro converts the RTF to text and then resaves it, there is the possibility that binary data could be corrupted, depending. I would say the chances of this are quite slim, because most of the time the binary data feature of RTF is not used, but I wanted to mention it.


2009-07-27 10:52:48
Profile WWW

Joined: 2007-11-09 15:27:25
Posts: 86
Thanks for the tip, Martin.

I'm dealing with pure text files which have minimal formatting. So I take it the danger you mention is moot for me at the moment.

But are there examples of such "arbitrary binary data" other than images that one ought to watch out for?

Thanks


2009-07-27 12:21:23
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
In thinking about this a little more, there may not be any problem after all. Since the macro only modifies the "plain text" part of the RTF code, the binary data should remain intact.

While loading up the data directly via "readDataFromPath" and casting it to a string will interpret the data as UTF-8 or similar, saving it out should produce the same original data. I can't guarantee this, because we use Apple's text encoding services, but it should be a safe bet.


2009-07-27 15:12:51
Profile WWW

Joined: 2008-05-17 04:02:32
Posts: 400
Thank you, Martin, very much for the explanation. Unfortunately, the macro does not work with rtf files containing binary data. I tested it with an unzipped zrtf file (Release Notes.zrtf), for which Cast to String seems to return nothing. I'd like to have something like Cast to String $data, bytes (feature request ;-)

With ordinary rtf files, the macro does not have a problem, though. Images are stored in them as ASCII strings.

But I have not checked all kinds of objects and this may change in a future version of Nisus Writer Pro, for example, when it supports audio or movie (?). Thus, I modified the macro so that it uses Perl to change the values of the rtf directives.

Also, now you can define $folderNameSuffix and $fileNameSuffix. If you set $folderNameSuffix to something, converted files will be saved in a new folder (folder name + $folderNameSuffix) under the same parent directory. In that case, you can set $fileNameSuffix to nothing ($fileNameSuffix = '') so that the converted files have the same file names.

With $folderNameSuffix set to nothing ($folderNameSuffix = '') and $fileNameSuffix set to something (e.g. $fileNameSuffix = ' (US Letter)'), the macro works almost in the same way as the first version.

Code:
### Change Paper Size ###

# From rtf files in a folder, this macro generates new files with page size set to $width and $height.

# The macro does not change margins. So resulting files may not look good.

# Only files in RTF format (rtf, nwm and non-binary doc) are processed.

# Converted files (file name + $fileNameSuffix) will be saved in a new folder (folder name + $folderNameSuffix) under the same parent directory. However, if you set $folderNameSuffix to nothing ($folderNameSuffix = ''), converted files will be saved in the source folder.

# If you set $fileNameSuffix to nothing ($fileNameSuffix = ''), the same file names will be used. In that case, you cannot set $folderNameSuffix to nothing.

# Files for which a converted file already exists will be skipped.

# If "Keep prior copy of each files using the file name suffixv is enabled in "Preferences - Saving", backup files will be ignored.

Require Pro Version 1.3

$folderNameSuffix = ' (US Letter)'  # settings for US Letter
$fileNameSuffix = ''
$width = 12240
$height = 15840

#$folderNameSuffix = ' (A4)'  # settings for A4
#$fileNameSuffix = '_A4'
#$width = 11900
#$height = 16840

#$folderNameSuffix = ' (JB5)'  # settings for JB5
#$fileNameSuffix = '_JB5'
#$width = 10320
#$height = 14580

if $folderNameSuffix == undefined
   if $fileNameSuffix == undefined
      exit 'You have to define $fileNameSuffix and $folderNameSuffix, one of them at least.'
   end
end


$defaultFolderPath = '~/Documents'
$openButtonCaption = 'Choose a Folder'
$folderPath = Choose Folder $defaultFolderPath, $openButtonCaption
if $folderPath == undefined
   exit  # cancelled by the user
end

$fileNames = File.namesInFolderAtPath $folderPath
$keepLastCopy = Read User Default 'com.nisus.backup.keepLastCopy'

if $keepLastCopy == true
   $lastCopySuffix = Read User Default 'com.nisus.backup.lastCopySuffix'
   $lastCopySuffix = '\Q' & $lastCopySuffix
   $lastCopySuffix &= '.\E[^.]+$'
end

$newPaths = Hash.new
$newFolder = $folderPath & $folderNameSuffix

foreach $fileName in $fileNames
   $notLastCopy = true
   if $keepLastCopy == true
      if $fileName.find $lastCopySuffix, 'E-i'
         $notLastCopy = false
      end
   end
   if $notLastCopy == true
      $filePath = $folderPath.filePathByAppendingComponent $fileName
      $filePath = File.resolveLinkAtPath $filePath
      $newPath = $newFolder.filePathByAppendingComponent $fileName
      $newPath.findAndReplace '(?=\.[^.]+$)', $fileNameSuffix, 'E'
      $newPaths{$filePath} = $newPath
   end
end

$errors = ''
Set Exported Perl Variables 'newPaths', 'newFolder', 'width', 'height', 'errors'
Set Include Perl UTF Preamble false

begin Perl
   foreach my $path (keys (%newPaths)) {
      my $newPath = $newPaths{$path};
      if ( -e $newPath ) {
         $errors .= "'$newPath' already exists.\n";
      } else {
         my $fileType = `/usr/bin/file -b --mime "$path"`;
         $fileType =~ s/[\n\r]+$//;
         if ( $fileType eq 'text/rtf' ) {
            if ( ! -f $newFolder ) {
               `mkdir -p "$newFolder"`;
            };
            open (IN, "<:bytes", $path);
            open (OUT, ">:bytes", $newPath);
            local undef $/;
            my $data = <IN>;
            $data =~ s/(?<=\x5Cpaperw|\x5Cpgwsxn)[0-9]+/$width/g;
            $data =~ s/(?<=\x5Cpaperh|\x5Cpghsxn)[0-9]+/$height/g;
            print OUT $data;
            close IN;
            close OUT;
         } else {
            $errors .= "'$path' is not an RTF file.\n";
         }
      }
   };
end

File.revealPathInFinder $newFolder

if $errors
   exit $errors
end

### end of macro ###


2009-07-28 02:30:18
Profile

Joined: 2007-11-09 15:27:25
Posts: 86
Kino, you've anticipated my every wish.
If I thought it appropriate, i would have asked for this versatility. Fortunately, you got there first.

This is just the thing.

Thanks again.


2009-07-28 10:10:09
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
Kino wrote:
Thank you, Martin, very much for the explanation. Unfortunately, the macro does not work with rtf files containing binary data. I tested it with an unzipped zrtf file (Release Notes.zrtf), for which Cast to String seems to return nothing.

Offhand I would guess that the data in the file somehow produces an invalid Unicode string. For example, unmatched surrogate pairs may cause the whole conversion to fail.

Quote:
But I have not checked all kinds of objects and this may change in a future version of Nisus Writer Pro, for example, when it supports audio or movie (?). Thus, I modified the macro so that it uses Perl to change the values of the rtf directives.

This would be the safest. Even things that one does not normally think of as binary data can be saved in odd ways in RTF. For example, list style formats often use low ASCII characters (like 0x01 and 0x02) as placeholders. This wouldn't be an issue for the UTF-8 conversion, but the point stands that RTF files must be treated as binary.


2009-07-28 10:30:02
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 9 posts ] 

Who is online

Users browsing this forum: No registered users and 4 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:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software