exprv4:how-to:how_relative_paths_work

How Relative Paths Work

Expr path resolution is designed so machine configuration, scripts, libraries, and assets can be kept together and moved as one profile folder.

The most important rule is to know whether a path is resolved from the profile path or from the source path.


Profile Path

The profile path is the main machine configuration folder. It is the folder where the settings file is stored.

A good profile folder contains everything that belongs to one machine setup:

  • settings
  • scripts
  • include libraries
  • custom dialogs
  • images and icons
  • job-specific helper files
  • machine-specific configuration data

Copying or moving the profile folder should copy the complete machine configuration.

Use profile-relative paths for shared files that belong to the machine setup.

include "./lib/probing/probe_job.expr" as Probe
icon = path("./assets/icons/probe.png");

Source Path

The source path is the folder of the current source script used as the source context by the host.

For a script file, this is normally the folder that contains the script being evaluated. For host-entered code, such as MDI or code evaluated from a string, the host decides the source path and there may be no source file.

Use source-relative paths for files that live next to the script being run.

local_data = path("job_data.csv");
include "probe_steps.expr" as Steps

The path() Function

`path()` returns resolved absolute paths using the same host path rules used by internal Expr path resolution.

Use it when you want to inspect or store the absolute path that Expr will use.

print(path());
print(path("./lib/probing/probe_job.expr"));
print(path("job_data.csv"));

Resolution Rules

Assume this example context:

profile path: C:/PlanetCNC/Profile
source file:  C:/PlanetCNC/Profile/jobs/probe_plate.expr
source path:  C:/PlanetCNC/Profile/jobs
Expr Result Meaning
`path()` `C:/PlanetCNC/Profile` Profile path.
`path(“”)` `C:/PlanetCNC/Profile/jobs` Source path.
`path(“.”)` `C:/PlanetCNC/Profile` Profile path.
`path(“~”)` `C:/PlanetCNC/Profile/jobs/probe_plate.expr` Source file.
`path(“~/MyFile.txt”)` `C:/PlanetCNC/Profile/jobs/MyFile.txt` Explicit source-relative file. Same as `path(“MyFile.txt”)`.
`path(“~/../MyFile.txt”)` `C:/PlanetCNC/Profile/MyFile.txt` Parent of source path.
`path(“MyFile.txt”)` `C:/PlanetCNC/Profile/jobs/MyFile.txt` Source-relative file.
`path(“./MyFile.txt”)` `C:/PlanetCNC/Profile/MyFile.txt` Profile-relative file.
`path(“../MyFile.txt”)` `C:/PlanetCNC/MyFile.txt` Parent of profile path.

The rule is:

  • no argument returns the profile path
  • an empty string returns the source path
  • `~` returns the source file
  • a path that starts with `~/` is resolved from the source path
  • a path that starts with `.` is resolved from the profile path
  • a path that does not start with `.` is resolved from the source path

This means `./` is profile-relative, not source-relative. Use `~/` when you want to make source-relative intent explicit.

If code is evaluated from a string and no source file is available, `path(“~”)` returns an empty string. Source-relative paths such as `path(“”)`, `path(“MyFile.txt”)`, and `path(“~/MyFile.txt”)` use the source-path fallback, normally the profile path.


Profile-Relative Paths

Use `./` for files that belong to the profile folder.

include "./lib/probing/probe_job.expr" as Probe
include "./lib/dialogs/tool_dialog.expr" as ToolDlg
 
icon_file = path("./assets/icons/tool.png");
config_file = path("./config/tool_table.txt");

This is usually the best style for shared libraries and machine configuration files.

If the profile folder is copied to another computer, these paths still point inside the copied profile.


Source-Relative Paths

Use paths without a leading dot for files that live next to the current source script.

include "probe_steps.expr" as Steps
 
points_file = path("probe_points.csv");
report_file = path("probe_report.txt");
explicit_file = path("~/probe_points.csv");

If the current source script is:

C:/PlanetCNC/Profile/jobs/probe_plate.expr

then both `path(“probe_points.csv”)` and `path(“~/probe_points.csv”)` resolve to:

C:/PlanetCNC/Profile/jobs/probe_points.csv

Be Careful With ../

A path that starts with `..` also starts with `.`. It is resolved from the profile path.

file = path("../shared.txt");

If the profile path is:

C:/PlanetCNC/Profile

then the result is:

C:/PlanetCNC/shared.txt

It is not resolved relative to the current script folder.

Prefer keeping shared files inside the profile folder and using `./` paths.


For shared libraries stored in the profile folder:

include "./lib/probing/probe_job.expr" as Probe
include "./lib/atc/tool_change.expr" as ATC

For small helper files stored beside the current script:

include "probe_steps.expr" as Steps
include "local_report.expr" as Report

Avoid using `../lib/…` for shared profile libraries. It goes to the parent of the profile folder, not to a sibling of the current source script.


For machine/profile assets:

logo = path("./assets/images/logo.png");
icon = path("./assets/icons/probe.png");

For files next to the current script:

input = path("input.csv");
output = path("output.txt");
explicit_input = path("~/input.csv");

For the current source file, when the script comes from a file:

current_file = path("~");

When there is no source file, `path(“~”)` returns an empty string.


Checklist

When writing a path, ask:

  • Is this file part of the machine profile?
  • Should this file move when the profile folder is copied?
  • Is this file beside the current script?
  • Did I use `./` only when I really want the profile path?
  • Did I avoid `../` unless I really want to leave the profile folder?
  • Should I use `path(…)` to inspect the resolved absolute path?

See Also

exprv4/how-to/how_relative_paths_work.txt · Last modified: by 127.0.0.1

Page Tools