Positioning Mechanisms
An in-depth guide to absolute and relative positioning in NeuralSketch, essential for creating precise and visually coherent diagrams.
Positioning is not a detail—it is the diagram. It governs rhythm, structure, and spatial logic, shaping not only what your readers see but how they read.
Positioning is fundamental to crafting clear, accurate, and visually appealing diagrams. Neural Sketch provides robust, flexible, and intuitive positioning mechanisms designed for both straightforward and complex diagramming tasks.
Overview
Neural Sketch supports two complementary models of placement:
- Absolute positioning: Explicitly define exact coordinates.
- Relative positioning: Place elements in relation to other diagram primitives, containers, groups, or blocks.
Each method supports nuanced control through additional positioning keys, allowing you to precisely adjust or align elements with minimal boilerplate.
Positioning mechanisms are supported across all major elements — including
\nskBlock
, \nskContainer
, \nskGroup
, \nskMark
, and more. If it goes on
the canvas, it can be placed.
Absolute Positioning: Declare, Then Adjust
Absolute positioning allows you to define the exact coordinates for placing a primitive on the canvas. This method is ideal for scenarios requiring explicit spatial precision.
Basic Usage
Define absolute positions using the x
and y
keys, representing horizontal and vertical coordinates respectively:
Precision Offsets: The Role of shift-*
After establishing an absolute position, you can apply additional fine-grained adjustments using shift-x
and shift-y
keys:
This moves the block horizontally to the right by 0.5 units and vertically downward by 0.25 units, relative to the specified coordinates.
You can set absolute positioning using unit-aware values — either relative
units like 3
(default units) or explicit units like 3cm
, 10pt
, etc.
Mark shifting
shift-x
and shift-y
are particularly useful for micro-adjustments.
First, you can rougly position an element to a reference location, then apply a precise per-axis offset.
This pairs perfectly with \nskMark
:
Relative Positioning: Describe Relationships
Let layout emerge from intent.Think in terms of spatial relationships, not coordinates. Relative positioning lets you describe how one element relates to another—above, beside, offset by a margin.
It aligns primitives with reference to other primitives by ID
, significantly simplifying complex diagram layouts.
Syntax
where:
<key>
can bepos
,last-pos
, orlast-pos-s
<direction>
is aTikZ
-style compass direction such asabove
,below
,left
,right
, or combined forms likeabove right
<distance>
specifies the offset in any valid dimension (1cm
,4pt
, etc.)<target>
is theID
of a previously defined primitive (e.g., a block or container)
You can combine two directions with independent distances:
This places the current element 1cm
above and 0.5cm
to the right of baseNode
.
When combining directions, always list the vertical direction first (e.g.,
above right
, not right above
). This matches TikZ
syntax and avoids
parsing errors.
Using the pos
Keyword
The pos
key uses natural-language-inspired syntax, based on TikZ
’s positioning library. This allows expressive, readable placements without numerical guesswork:
Here, the second block (bblock
) is positioned exactly 1 cm above and 0.5 cm to the right of the first block (ablock
).
Example
Tip
When no <distance>
is provided in pos
, last-pos
, or last-pos-s
, Neural Sketch uses a default value defined by the internal variable g__nsk_style_figure_block_distance_tl
. This value is globally configurable via the block-distance
key in the package options.
This allows you to standardize spacing across your diagrams and reduce boilerplate—so even pos={right=of blockA}
or just last-pos={right=}
just works
Retrieving Diagram History
Sometimes you don’t want to assign symbolic handles (id
) to every element—or more intuitively, you want to place something relative to what you just drew. In these cases, NeuralSketch exposes a powerful diagram history system via \nskID{n}
and \nskID!{n}
.
\nskID{1}
returns the most recently drawn element.\nskID{2}
is the one before that, and so on.\nskID!{1}
accesses the first element drawn in the current figure.
This enables dynamic, ID-free layout composition:
Leveraging the diagram history through the \nskID
and \nskID!
we can easily position and connect elements and you can even chain connections dynamically:
Want to understand how IDs are generated and how far back you can go? Check out the Auto-Incremental ID page for a full breakdown of how Neural Sketch manages and exposes the internal history.
last-pos
: Chain without IDs
When building a diagram step by step, it’s often more natural to describe the layout incrementally—what comes next, not just where it goes. The last-pos
key enables this flow-driven composition by anchoring new elements to the most recently drawn primitive:
This approach keeps your code linear, expressive, and free from the overhead of assigning and referencing explicit id
s.
last-pos-s
: Safe Chaining
In dynamic scenarios—loops, branches, or conditional macros—there may be no previously drawn element. That’s where last-pos-s
(the safe variant) comes in.
It applies the offset only if a previous primitive exists, and silently skips otherwise:
No errors. No undefined references. Just graceful fallback.
Use this when the presence of a preceding element can’t be guaranteed.
Custom Errors with last-pos
Unlike last-pos-s
, the standard last-pos
assumes a previously drawn primitive must exist. If not, Neural Sketch issues a targeted error to help you diagnose and correct the issue quickly.
ERROR-BadIndex
If the reference to the previous element is invalid—such as using last-pos
with no prior primitive—Neural Sketch raises a custom ERROR-BadIndex
. This
message explicitly points out the missing or out-of-bounds index, making
debugging fast and transparent.
This is especially important when converting code from one-off diagrams to templated or loop-driven ones. Switching to last-pos-s
ensures your layout logic stays resilient.
Skip-first Positioning
Sometimes you find yourself needing to align two set of elements across two dimensions. For examples you have two containers, each with each containing block relatively placed next to each other. Then you would like to align each container below each other.
Because last-pos=right
applies to the very first block in the second container, the second container ends up side by side with the first (stricter rule applied).
You have two clear options to fix this:
- Insert a dummy marker: Add an invisible
\nskMark
to reset the positioning context:
\nskMark
like every element, is tracked--so keep that in mind when Navigating the Diagram History
- Use the “skip-first” operator (
^=
): Apply positioning only from the second element onward:
This way, the first block inside the second container uses the container’s positioning, and subsequent blocks apply last-pos=right
.
After your done, you can reset all
^
commands counters using
Available: pos^=
, last-pos^=
, last-pos-s^=
.
Currently only supported by nskBlock
primitives.
Intelligent Alignment
Neural Sketch intelligently infers alignment intentions, simplifying diagrams that rely heavily on aligned elements.
For example, horizontally aligning adjacent blocks does not require explicit anchors—Neural Sketch automatically chooses appropriate edges:
In this scenario, NeuralSketch aligns the left edge of Block B with the right edge of Block A, automatically interpreting your intent without needing explicit anchors.
Neural Sketch allows to horizontally and vertically align
Combining Positioning with Containers and Groups
Positioning mechanisms extend naturally to containers and groups, allowing cohesive positioning and transformation of composite diagram components.
Containers
Containers wrap multiple primitives, allowing global transformations alongside internal relative positioning while providing handy stylings:
This container moves as a unit, while blocks inside maintain local relative positioning.
Groups
Groups logically cluster primitives, making collective transformations (e.g., rotation or scaling) straightforward while maintaining local positional consistency:
Both blocks move cohesively, preserving their relative positions within the transformed group.
\nskGroup
is usually used internally, whenever possible you may want to use \nskContainer
.
Aligning Multiple Elements together
Sometimes, you want to align one or more elements not relative to a single item, but to a group of elements treated as a whole. Instead of aligning to an individual block, you align to the combined bounding box of several blocks.
To do this, you can wrap the elements inside an \nskContainer
. By default, \nskContainer
adds padding and styling. If you simply want pure logical grouping—without visual decoration—you can use \nskContainer![...]
(the exclamation mark disables styles).
Suppose you have a few blocks:
Now, imagine you want to place a new element above all of them, centered on the group.
At first, it might seem natural to align to one specific block:
However, none of the individual elements exactly aligns:
Grouping for Correct Alignment
Instead, wrap the blocks inside a \nskContainer![...]
.
This groups them into a single logical unit:
Now, you can simply align your new element relative to the group:
Wrapping Elements Under a Reference
Sometimes, you want to “wrap” a sequence of diagram elements beneath another—shifting the reference anchor midstream. That’s what \nskWrap
enables. It repositions the base anchor so that subsequent elements flow from a new starting point.
This is especially useful for grouped content or bifurcated flows that stem from a shared parent.
This mechanism integrates cleanly with \nskContainer
, allowing you to wrap and group new content under an existing structure.
However, sometimes you may want to wrap above an element, you can easily do so by using the over=
key instead:
By default, \nskWrap[...]
uses the global block-distance
wrap elements; sometimes you may find the need to locally modify the spacing, for this occasions you can use shift-x
and shift-y
:
Tip
You can easily chain logic, by using \nskID
or \nskID!
Edge Alignment
Sometimes you need blocks to align flush—where their edges line up exactly with a reference point or neighboring element.
In these cases, you can use the align=
key to precisely control edge alignment:
The align=
key ensures that your block’s edge (top, center, or bottom) snaps to the correct position, making layouts feel tight and intentional.
You can combine align=
with any *-pos-*=
key for fine-grained control over placement.
Best Practices
- Absolute positioning is ideal for single, fixed, or foundational elements.
- Relative positioning reduces redundancy and complexity in interconnected or iterative diagrams.
- Use
last-pos-s
within loops or uncertain contexts to avoid unnecessary errors gracefully. - Use Neural Sketch’s intelligent alignment for cleaner, simpler code.
Takeaways
Neural Sketch’s versatile positioning mechanisms—combining absolute coordinates, expressive relative references, intelligent alignment inference, and robust error handling—offer unmatched flexibility and ease-of-use, empowering you to create precise, sophisticated, and visually coherent diagrams with minimal effort.