Conditions and loops#
Purpose and concepts#
for follows list order or dictionary insertion order. Pair and nested unpacking are supported; enumerate adds indices and zip stops at the shortest input. Iteration snapshots are fixed at loop entry.
Minimal complete example#
Run this file directly with laymesh validate or laymesh render; it contains its own canvas and required definitions.
# Minimal complete example: rangepage=canvas(size=(100mm,75mm),background="#ffffff")for i in range(4) { page.add(rect(size=(10mm,10mm),fill="#087f8c"),offset=(10mm+i*16mm,20mm)) }# Minimal complete example: rangepage=canvas(size=(100mm,75mm),background="#ffffff")for i in range(4) { page.add(rect(size=(10mm,10mm),fill="#087f8c"),offset=(10mm+i*16mm,20mm)) }Preview
Dependencies
examples/manual/range.lay
Parameters and default behavior#
Unitless geometry uses the canvas unit; unitless type and stroke sizes use pt. Explicit call parameters override inherited/theme defaults. The linked interface reference lists accepted types, choices and defaults per parameter.
Composition#
Store dimensions, colors or offsets in lists and place them using range(len(items)). while, break and continue control iteration, with explicit reproducible exit conditions.
function doubled(value, factor=2) { return value * factor }count = 0for index in range(3) { count = count + index }while count < 5 { count = count + 1 }status = "pending"if count == 5 { status = "ready" } else { status = "error" }label = text(content="count=" + str(count) + " gap=" + str(doubled(3 mm)) + " " + status, font_family=font, font_size=11 pt, color="#087f8c")page.add(label, target=page.top_left, offset=(10 mm, 34 mm))# Gallery: scripting / control-flowpage = canvas(name="Functions and loops", size=(120 mm, 80 mm), background="#f7f9fc")font = "DejaVu Sans"heading = text(content="Functions and loops", font_family=font, font_size=14 pt, color="#203864")page.add(heading, target=page.top_left, offset=(7 mm, 5 mm))# BEGIN DEMOfunction doubled(value, factor=2) { return value * factor }count = 0for index in range(3) { count = count + index }while count < 5 { count = count + 1 }status = "pending"if count == 5 { status = "ready" } else { status = "error" }label = text(content="count=" + str(count) + " gap=" + str(doubled(3 mm)) + " " + status, font_family=font, font_size=11 pt, color="#087f8c")page.add(label, target=page.top_left, offset=(10 mm, 34 mm))# END DEMOPreview
Dependencies
examples/gallery/scripting/control-flow.lay
Common errors and limits#
Loops allow at most 10,000 iterations, function depth is at most 64 and statement execution is bounded. New local bindings do not automatically leak outward; reassigning existing outer bindings follows scope rules.
Individual functions#
enumerate#
Return index/value pairs for loop unpacking; start defaults to zero and input is limited to 10,000 items.
Returns: list
Required inputs: seq.
Minimal complete source · Composition source · All parameters
zip#
Combine positional iterable inputs into tuples, stopping at the shortest input; no arguments return an empty list.
Returns: list
Minimal complete source · Composition source · All parameters
Detailed behavior and further examples#
Parameters#
| Parameter | Purpose | Default or requirement |
|---|---|---|
if / else |
Conditional branches | Restricted DSL |
for |
Iterate sequences | Bounded by evaluation limits |
Common usage#
Use conditions to select layouts and finite loops to repeat placements. Evaluation and iteration are limited; prefer native batch layers for large datasets.
Limits and related topics#
Variables and expressions · Functions and modules
workflow#
Complete sources and executable verification fixtures for this workflow are listed in the feature coverage map. Follow this page’s input conditions and limits when composing features.
Pair unpacking and snapshots#
for key in d iterates keys; for key,value in d.items() iterates pairs. Nested patterns such as for i,(name,ys) in enumerate(d.items()) bind in the loop scope; _ discards a value. Shapes must match exactly and repeated variable names are rejected.
enumerate(seq,start=0) returns index/value pairs. zip(a,b,...) stops at the shortest input, and zero arguments return an empty list. Lists, dictionaries and geometry collections are iterable. Iteration snapshots are fixed at loop entry, so updating the original dictionary does not add work to the current loop. Existing break, continue, scope and evaluation limits remain in force. Dictionary membership uses key in d or key not in d.

