Skip to main content
Skip table of contents

(v13) Implementing file-name mapping

This page applies to Harlequin v13.1r0 and later; both Harlequin Core and Harlequin MultiRIP.

The name mapping algorithm depends both on the operating system requirements and the variant of the RIP. Harlequin Core customers must implement their own algorithm, since this is part of the interface between the operating system and the system-independent interpreter.

The PostScript-language model of a file system is flat: there is no directory hierarchy. This is rarely true of operating systems. However, historically, a forward slash ( / ) character has been used in PostScript-language file names to delimit different components of the name, just as if there were directories and file names. The main distinction (apart from the implementation differences) is that in principle a , a/ and a/b can all exist as independent PostScript-language files. Most RIP implementations, including the command-line and GUI versions, choose to ignore this subtle distinction and interpret / as a directory separator, translating it to a colon ( : ) on Macintosh systems and to a backslash ( \ ) on MS-DOS and Windows-based systems.

In the GUI version, each component of this string is then treated individually and is used as either a directory or file name. If it is a legal name under the rules of the operating system and does not clash with file names that have already been encountered, it is used directly. Otherwise, the name is looked up in a table stored in the file FILEMAP.DAT in the SW directory. If it is found, the corresponding operating system name in the table is used. If not, a new mapping is invented and added to the table in that file.

When generating file names FILERED.PS in the SW directory is used to provide standard contractions of segments of each component. For example, FILERED.PS includes the lines:

(Helvetica) (Helve) (Oblique) (O)

which means that components including Helvetica has that contracted to Helve as part of the generation of a new name; similarly Oblique is contracted to O —so, for example, the font name HelveticaOblique end ups as HelveO. Mapped names also have any extension replaced by

.X00, unless that clashes with an existing mapping; in that case .X01 , .X02  (and so on). is used (followed by .Y00 and so on).

All mapped names generated by GUI versions of the RIP running under Windows are legal MS-DOS 8.3 file names and in upper case. On the Macintosh, mapped names may be mixed case and are limited to 27 characters, plus the suffix (for example, .X00).

On Windows RIPs, it is possible that some networked disks on which the RIP must access files may be MS-DOS FAT formatted, meaning that they are restricted to 8.3 filenames. The only effect on mapping is that some file names which would be valid on an NTFS or NT FAT volume are not valid on these disks. The Harlequin RIP automatically detects whether a disk is restricted to 8.3 names,; it uses the appropriate rules for mapping file names as appropriate.

On Macintosh and PC, where the operating system itself is case retentive (but not case sensitive), you must also map a component to a generated name if another component with the same name, but different capitalization has already been encountered; this fulfills the requirement that PostScript filenames are case sensitive. This mapping ensures that files which are only created and read from inside PostScript are always handled correctly. The listing of what case of PostScript names should be used for the original operating system file name, and which are mapped to generated names is also held in FILEMAP.DAT in the SW directory.

FILEMAP.DAT comprises a series of entries, one for each file name encountered in PostScript jobs. Entries are in two forms:

(STRING) (string) C

is used for the first instance of a PostScript language file name that is also a valid operating system file name on that platform.

The second string defines the case of the PostScript file name that is taken as referring to a file on disk by that name:

(invalid::string) (INVALIDS.X00) M

is used for all PostScript file names that are not invalid as operating system file names, and for those names that match existing names except in case. The first string is the PostScript file name; the second is the name of a file on disk that is mapped to it.

File name mapping is generally transparent to the user. For example, when a font installation job invoked from the Fonts menu is run, it makes font files in the SW/fonts directory. The PostScript-language file names must match the name of the font, which can be longer than the maximum allowed by the operating system (for example, more than 31 characters on a Macintosh), or may include illegal characters, such as a colon ( : ), illegal on both Macintosh and Windows). All of that mapping is handled automatically, and you are not normally aware that it happened.

The most common case where special attention must be given to mapping is where a file already exists in the operating system’s filing structure, and you wish to access it from PostScript. In this situation, you must disable the mapping process to ensure that you can access the file by the name you expect. In fact, only the case sensitivity part of the mapping is important here—the file on disk must already have a legal operating system name; otherwise, it could not be created.

Consider, for instance, a file named TestFile.ps . You would expect to be able to read it with (TestFile.ps)(r) file, and most of the time that would work. If, however, the RIP had encountered a file named TESTFILE.ps, the RIP recorded that the file on disk called testfile.ps (remembering that the operating system is case insensitive) equates to the PostScript file name TESTFILE.ps. The code fragment above is interpreted as a request for a file with a mapped operating system name (probably TESTFILE.X00 ); the file you created from some other application cannot be found because the RIP is looking for a file by the mapped name.

To allow the case mapping process to be turned off, you can use an empty (zero-length) component. This disables mapping for all further components (the empty component itself is discarded). A slash ( / ) at the beginning of a file name that does not include an explicit device name (or immediately after the device name if present) is interpreted as an initial empty component; elsewhere an empty component may be included as two slashes together.

Thus, the safe method of reading a file created by another application is: (/TestFile.ps)(r) file. Other examples of file names where mapping is disabled are:

(%D%/mydirectory/testfile.ps) (%Hard Disk%OPIdirectory//XYZ.JPG)

In the last example, the OPIdirectory component is mapped; the file name XYZ.JPG is not mapped, because it is after the empty component ( // ).

To access a file created outside the Harlequin RIP that includes a slash ( / ) in a component, you can override the normal treatment of the slash as a directory separator by escaping it with a backslash ( \ ).  The file mapping mechanism in the RIP uses the sequence of backslash, forward slash ( \/ ); however, remember that the backslash itself must be escaped with a second backslash when entering the string in your program so that you end up with that sequence. Thus, a file on a Macintosh system named:

HardDisk:folder:the/file

could be accessed using:

(%HardDisk%folder/the\\/file)(r)file

Operating system names under Windows cannot contain slash characters.

When using the PostScript operator filenameforall, you can request that file names returned are in either mapped or unmapped format by constructing the template string appropriately. If the template contains an empty component, the file names returned are in operating system format; if it does not, they are in the mapped, PostScript form.

(%D%somedir/*) {==} 100 string filenameforall

returns names in mapped format if possible;

(%D%/somedir/*) {==} 100 string filenameforall

returns all names in unmapped format (because all returned names must start with %D%/somedir, which contains an empty component).

filenameforall falls back to unmapped names where necessary. In the first filenameforall example above, if D:\somedir contains a file that is the same as an existing name but contains one or more characters in a different case (say helvetica, rather than the built-in Helvetica), the file is returned with just the offending component unmapped, as (%D%somedir//helvetica. The bulk of the file names returned are mapped.

The filename operator in statusdict (Device and file operator definitions) always returns the name used to create the file handle, which may have been unmapped.

PostScript filenames are always absolute (that is, relative to the root of the corresponding device; a file name always includes a full directory path after the device name, if present). If a file name does not include a device name and is being opened for writing (that is, the normal PostScript file search rules will not be followed), it is created on the %os% device, rooted at the SW directory. Any directories required by the file name are created automatically if a file is opened for writing.

The command-line and GUI RIPs on Unix do not apply any mapping beyond / because names are sufficiently representable.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.