Pushes a mark object onto the operand stack to serve as a delimiter or reference point.
1. Description
The mark operator pushes a special mark object onto the operand stack. This object has its own unique type (marktype) and serves as a stack delimiter that can be detected by operators like counttomark and cleartomark.
Marks are commonly used to delimit variable-length argument lists, allowing operators to process all stack elements down to the mark. The most familiar use is in array construction, where [ is a synonym for mark and ] creates an array from all elements up to the mark.
All mark objects are identical. The stack may contain any number of marks at once.
This is a Level 1 operator, available in all PostScript implementations.
5. Examples
5.1. Basic Usage
% Push a mark
mark % Stack: mark
type % Stack: /marktype
% Marks can be mixed with other types
1 2 mark 3 4 % Stack: 1 2 mark 3 4
5.2. Array Construction
% [ is equivalent to mark
mark 1 2 3 ] cvx % Stack: [1 2 3]
[ 1 2 3 ] % Stack: [1 2 3] (same result)
% The opening bracket [ is just mark
[ % Pushes a mark
1 2 3
] % Creates array from elements after mark
6. Advanced Examples
6.1. Safe Mark-Based Processing
% Process elements between marks safely
/processBetweenMarks { % mark elem1 ... elemn proc -> result
counttomark % Count elements to process
1 sub % Exclude the proc itself
{
% Process each element
2 copy exch exec
exch
} repeat
pop % Remove count
exch pop % Remove mark
} def
% Usage
mark 1 2 3 4 5 { 2 mul } processBetweenMarks
% Processes: 2 4 6 8 10
6.2. Dictionary Construction Pattern
% Create dictionary from mark-delimited key-value pairs
/makeDict { % mark /key1 val1 /key2 val2 ... -> dict
counttomark 2 idiv % Count pairs
dict begin
{
counttomark 0 eq { exit } if
exch def
} loop
currentdict end
exch pop % Remove mark
} def
% Usage
mark
/name (PostScript)
/version 3
/year 1999
makeDict
7. Edge Cases and Common Pitfalls
Unmatched marks (marks without corresponding cleartomark or ]) accumulate on the stack and can cause problems.
|
7.1. Unmatched Marks
% BAD: Leaving marks on stack
mark 1 2 3
% Mark never removed!
% Later operations might fail
% GOOD: Always pair mark with removal
mark 1 2 3 cleartomark
% Or: mark 1 2 3 ]
7.2. Mark vs [
% mark and [ are identical
mark % Stack: mark
[ % Stack: mark (exactly the same)
% Both create same object
mark type % /marktype
[ type % /marktype
% Difference is convention:
% Use [ with ]
% Use mark with cleartomark or counttomark
7.3. Marks in Error Conditions
% cleartomark with no mark causes error
1 2 3 cleartomark % ERROR: unmatchedmark
% Always ensure mark exists
mark
1 2 3
cleartomark % OK
% Or check first
count 0 gt {
0 index type /marktype eq {
cleartomark
} if
} if
Always ensure marks are properly matched with either cleartomark, ], or explicit removal. Unmatched marks can interfere with later operations.
|
8. Related Commands
-
cleartomark- Remove elements up to and including mark -
counttomark- Count elements to nearest mark -
[- Synonym for mark (used with]) -
]- Create array from elements after mark -
pop- Remove single element (including marks)
9. PostScript Level
Available in: PostScript Level 1 and higher
This is a fundamental operator available in all PostScript implementations.
10. Error Conditions
stackoverflow-
The operand stack is full and cannot accommodate the mark object.
% (Only if stack is at capacity)
11. Performance Considerations
Pushing a mark is a very fast O(1) operation, identical in cost to pushing any other object.
However, operations that search for marks (like counttomark) must scan the stack, which is O(n) where n is the distance to the mark.
12. Best Practices
-
Use with paired operations: Always pair
markwithcleartomarkor] -
Prefer [ ] for arrays: Use
[and]for array construction (more readable) -
Use mark for variable args: Use
markwhen implementing variable-argument procedures -
Document mark usage: Make it clear when procedures expect marks on the stack
-
Clean up marks: Never leave unmatched marks on the stack
12.1. Good Pattern: Variable Arguments
% Define procedure taking variable arguments
/myProc { % mark arg1 arg2 ... argn -> result
% Process all arguments after mark
0 {
counttomark 0 eq { exit } if
add
} loop
exch pop % Remove mark
} def
% Call with different argument counts
mark 1 2 3 myProc % Works with 3 args
mark 1 2 3 4 5 myProc % Works with 5 args
13. See Also
-
Operators Overview - Understanding PostScript operators
-
Stack Operations Guide - Stack manipulation tutorial
-
Arrays - Using marks for array construction
-
Stack Manipulation - All stack operators