Task 573: .PS File Format
Task 573: .PS File Format
File Format Specifications for .PS (PostScript)
The .PS file format refers to PostScript, a page description language developed by Adobe for defining printable documents, including text, vector graphics, and raster images. It is primarily text-based (ASCII), with a structure consisting of comments, prolog, setup, page descriptions, and trailer. The format adheres to Document Structuring Conventions (DSC), which use special comments starting with "%%" to provide metadata and structure. The official specifications are detailed in Adobe's PostScript Language Document Structuring Conventions Specification version 3.0.
List of all properties of this file format intrinsic to its file system
These properties are the DSC comments that define metadata, structure, and requirements for PostScript files. They are intrinsic as they are embedded in the file's text structure and affect how the file is interpreted, processed, and printed. The list includes general, header, body, page, trailer, color separation, query, special, open, and deprecated comments. Each property is listed with its name (without "%%") and a brief description:
- BoundingBox: Specifies the bounding box coordinates (llx lly urx ury) enclosing all marks in the document or page.
- Copyright: Provides copyright information for the document or resource.
- Creator: Identifies the software or application that created the document.
- CreationDate: Records the date and time of document creation.
- DocumentData: Specifies data type (e.g., Clean7Bit, Binary) for transmission handling.
- Emulation: Indicates printer emulation code (e.g., diablo630).
- EndComments: Terminates the header comment section.
- Extensions: Lists required PostScript language extensions (e.g., DPS, CMYK).
- For: Identifies the intended user or recipient.
- LanguageLevel: Specifies the required PostScript language level (e.g., 1 or 2).
- Orientation: Defines page orientation (Portrait or Landscape).
- Pages: Indicates total number of pages and optional order.
- PageOrder: Specifies logical page order (Ascend, Descend, Special).
- Routing: Provides routing information for document handling.
- Title: Supplies a descriptive title for the document.
- Version: Notes the document or resource version and revision.
- +: Continues a long comment line.
- BeginBinary: Starts binary data section with byte count.
- EndBinary: Ends binary data section.
- BeginData: Starts data section (Hex, Binary, ASCII) with count.
- EndData: Ends data section.
- BeginDefaults: Starts defaults section for page-level settings.
- EndDefaults: Ends defaults section.
- BeginEmulation: Starts non-PostScript emulation code.
- EndEmulation: Ends emulation code.
- BeginPreview: Starts bitmap preview for EPSI files.
- EndPreview: Ends preview section.
- BeginProlog: Starts prolog with procedure definitions.
- EndProlog: Ends prolog.
- BeginSetup: Starts document-level setup.
- EndSetup: Ends setup.
- BeginObject: Starts a graphic object on a page.
- EndObject: Ends object.
- BeginPageSetup: Starts page-specific setup.
- EndPageSetup: Ends page setup.
- Page: Marks page start with label and ordinal.
- PageBoundingBox: Page-specific bounding box.
- PageOrientation: Page-specific orientation.
- PageTrailer: Marks end of a page with deferred comments.
- Trailer: Marks end of document script with cleanup.
- EOF: Signifies end of file.
- CMYKCustomColor: Defines custom CMYK color.
- DocumentCustomColors: Lists custom colors used.
- DocumentProcessColors: Lists process colors (Cyan, Magenta, Yellow, Black).
- RGBCustomColor: Defines custom RGB color.
- BeginCustomColor: Starts code for custom color rendering.
- EndCustomColor: Ends custom color code.
- BeginProcessColor: Starts code for process color rendering.
- EndProcessColor: Ends process color code.
- PageCustomColors: Page-specific custom colors.
- PageProcessColors: Page-specific process colors.
- ?BeginFeatureQuery: Queries printer feature availability.
- ?EndFeatureQuery: Ends feature query.
- ?BeginPrinterQuery: Queries printer details.
- ?EndPrinterQuery: Ends printer query.
- ?BeginQuery: Starts generic query.
- ?EndQuery: Ends query.
- ?BeginResourceQuery: Queries resource availability.
- ?EndResourceQuery: Ends resource query.
- ?BeginResourceListQuery: Queries list of resources by type.
- ?EndResourceListQuery: Ends resource list query.
- ?BeginVMStatus: Queries virtual memory status.
- ?EndVMStatus: Ends VM query.
- BeginExitServer: Starts code using exitserver/startjob.
- EndExitServer: Ends such code.
- DocumentPrinterRequired: Specifies required printer.
- OperatorIntervention: Blocks printing until operator action.
- OperatorMessage: Displays message to operator.
- PageMedia: Specifies media for page.
- PageRequirements: Lists page printing requirements.
- PageResources: Lists resources used on page.
- BeginDocument: Starts embedded document.
- EndDocument: Ends embedded document.
- BeginFeature: Starts printer feature code.
- EndFeature: Ends feature code.
- BeginFile: Starts file resource (deprecated).
- EndFile: Ends file (deprecated).
- BeginFont: Starts font resource (deprecated).
- EndFont: Ends font (deprecated).
- BeginProcSet: Starts procset (deprecated).
- EndProcSet: Ends procset (deprecated).
- BeginResource: Starts resource definition.
- EndResource: Ends resource.
- IncludeDocument: Requests external document inclusion.
- IncludeFeature: Requests printer feature.
- IncludeFile: Requests file inclusion (deprecated).
- IncludeFont: Requests font (deprecated).
- IncludeProcSet: Requests procset (deprecated).
- IncludeResource: Requests resource inclusion.
- DocumentFonts: Lists fonts (deprecated).
- DocumentNeededFiles: Lists needed files (deprecated).
- DocumentNeededFonts: Lists needed fonts (deprecated).
- DocumentNeededProcSets: Lists needed procsets (deprecated).
- DocumentSuppliedFiles: Lists supplied files (deprecated).
- DocumentSuppliedFonts: Lists supplied fonts (deprecated).
- DocumentSuppliedProcSets: Lists supplied procsets (deprecated).
- DocumentProcSets: Lists all procsets (deprecated).
- PageFonts: Lists page fonts (deprecated).
- PageFiles: Lists page files (deprecated).
Two direct download links for .PS files
- https://raw.githubusercontent.com/ivansostarko/postscript-examples/master/basic.ps
- https://raw.githubusercontent.com/ivansostarko/postscript-examples/master/arc.ps
Ghost blog embedded HTML JavaScript for drag-and-drop .PS file dump
This is a self-contained HTML snippet with JavaScript that can be embedded in a Ghost blog (or any HTML page). It allows dragging and dropping a .PS file, reads it as text, parses all DSC properties (comments starting with "%%"), and dumps them to the screen in a list.
Python class for .PS file handling
This class opens a .PS file, reads and decodes (parses) the DSC properties into a dictionary, prints them to console, and can write a new .PS file with modified properties (appending them to the header if the original content is provided).
import re
class PSFileHandler:
def __init__(self, filepath):
self.filepath = filepath
self.properties = {}
self.content = ''
self.read_and_decode()
def read_and_decode(self):
with open(self.filepath, 'r', encoding='utf-8', errors='ignore') as f:
self.content = f.read()
lines = self.content.splitlines()
for line in lines:
if line.startswith('%%'):
match = re.match(r'%%(\w+):\s*(.*)', line)
if match:
key, value = match.groups()
self.properties[key] = value.strip()
def print_properties(self):
for key, value in self.properties.items():
print(f"{key}: {value}")
def write(self, new_filepath, new_properties=None):
if new_properties:
self.properties.update(new_properties)
header = '%!PS-Adobe-3.0\n'
for key, value in self.properties.items():
header += f"%%{key}: {value}\n"
header += '%%EndComments\n'
with open(new_filepath, 'w', encoding='utf-8') as f:
f.write(header + self.content.split('%%EndComments')[1] if '%%EndComments' in self.content else self.content)
# Example usage:
# handler = PSFileHandler('example.ps')
# handler.print_properties()
# handler.write('new.ps', {'Title': 'Updated Title'})
Java class for .PS file handling
This class opens a .PS file, reads and decodes the DSC properties into a Map, prints them to console, and can write a new .PS file with updated properties.
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class PSFileHandler {
private String filepath;
private Map<String, String> properties = new HashMap<>();
private String content = "";
public PSFileHandler(String filepath) {
this.filepath = filepath;
readAndDecode();
}
private void readAndDecode() {
try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
if (line.startsWith("%%")) {
Pattern pattern = Pattern.compile("%%(\\w+):\\s*(.*)");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
properties.put(matcher.group(1), matcher.group(2).trim());
}
}
}
content = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
}
public void printProperties() {
for (Map.Entry<String, String> entry : properties.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public void write(String newFilepath, Map<String, String> newProperties) {
if (newProperties != null) {
properties.putAll(newProperties);
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(newFilepath))) {
writer.write("%!PS-Adobe-3.0\n");
for (Map.Entry<String, String> entry : properties.entrySet()) {
writer.write("%%" + entry.getKey() + ": " + entry.getValue() + "\n");
}
writer.write("%%EndComments\n");
String body = content.split("%%EndComments")[1];
writer.write(body != null ? body : "");
} catch (IOException e) {
e.printStackTrace();
}
}
// Example usage:
// public static void main(String[] args) {
// PSFileHandler handler = new PSFileHandler("example.ps");
// handler.printProperties();
// Map<String, String> updates = new HashMap<>();
// updates.put("Title", "Updated Title");
// handler.write("new.ps", updates);
// }
}
JavaScript class for .PS file handling
This class (for Node.js) opens a .PS file using fs, reads and decodes properties into an object, prints them to console, and can write a new .PS file with updates.
const fs = require('fs');
class PSFileHandler {
constructor(filepath) {
this.filepath = filepath;
this.properties = {};
this.content = '';
this.readAndDecode();
}
readAndDecode() {
this.content = fs.readFileSync(this.filepath, 'utf-8');
const lines = this.content.split('\n');
lines.forEach(line => {
if (line.startsWith('%%')) {
const match = line.match(/%%(\w+):\s*(.*)/);
if (match) {
this.properties[match[1]] = match[2].trim();
}
}
});
}
printProperties() {
for (const [key, value] of Object.entries(this.properties)) {
console.log(`${key}: ${value}`);
}
}
write(newFilepath, newProperties = {}) {
Object.assign(this.properties, newProperties);
let header = '%!PS-Adobe-3.0\n';
for (const [key, value] of Object.entries(this.properties)) {
header += `%%${key}: ${value}\n`;
}
header += '%%EndComments\n';
const body = this.content.split('%%EndComments')[1] || '';
fs.writeFileSync(newFilepath, header + body);
}
}
// Example usage:
// const handler = new PSFileHandler('example.ps');
// handler.printProperties();
// handler.write('new.ps', { Title: 'Updated Title' });
C++ class for .PS file handling
This class opens a .PS file, reads and decodes properties into a map, prints them to console, and can write a new .PS file with updated properties.
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <regex>
class PSFileHandler {
private:
std::string filepath;
std::map<std::string, std::string> properties;
std::string content;
public:
PSFileHandler(const std::string& fp) : filepath(fp) {
readAndDecode();
}
void readAndDecode() {
std::ifstream file(filepath);
if (!file) {
std::cerr << "Error opening file." << std::endl;
return;
}
std::string line;
std::stringstream ss;
std::regex regex(R"(%%(\w+):\s*(.*))");
while (std::getline(file, line)) {
ss << line << "\n";
std::smatch match;
if (std::regex_match(line, match, regex)) {
properties[match[1]] = match[2];
}
}
content = ss.str();
file.close();
}
void printProperties() const {
for (const auto& pair : properties) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
}
void write(const std::string& newFilepath, const std::map<std::string, std::string>& newProperties = {}) {
for (const auto& pair : newProperties) {
properties[pair.first] = pair.second;
}
std::ofstream file(newFilepath);
if (!file) {
std::cerr << "Error writing file." << std::endl;
return;
}
file << "%!PS-Adobe-3.0\n";
for (const auto& pair : properties) {
file << "%%" << pair.first << ": " << pair.second << "\n";
}
file << "%%EndComments\n";
size_t pos = content.find("%%EndComments");
if (pos != std::string::npos) {
file << content.substr(pos + std::string("%%EndComments").length() + 1);
} else {
file << content;
}
file.close();
}
};
// Example usage:
// int main() {
// PSFileHandler handler("example.ps");
// handler.printProperties();
// std::map<std::string, std::string> updates = {{"Title", "Updated Title"}};
// handler.write("new.ps", updates);
// return 0;
// }