From aea171631641b0b1c313c070f5fc07ec2487f84a Mon Sep 17 00:00:00 2001
From: haithium <128622475+haithium@users.noreply.github.com>
Date: Fri, 6 Mar 2026 07:49:50 +0000
Subject: [PATCH 1/4] chore(docs): auto-generate docs
---
docs/src/modules/is.md | 34 +--
docs/src/modules/keyword.md | 22 +-
docs/src/modules/list.md | 2 +-
docs/src/modules/ntpath.md | 392 +++++++++++++++++++++++++++++++++
docs/src/modules/operator.md | 2 +-
docs/src/modules/path.md | 32 +++
docs/src/modules/posixpath.md | 364 ++++++++++++++++++++++++++++++
docs/src/modules/repr.md | 2 +-
docs/src/modules/runtime.md | 11 +-
docs/src/modules/set.md | 2 +-
docs/src/modules/str.md | 5 +-
docs/src/modules/stringcase.md | 2 +-
docs/src/modules/tbl.md | 26 +--
docs/src/modules/template.md | 5 +-
docs/src/modules/utils.md | 62 ++++--
docs/src/modules/validate.md | 6 +-
16 files changed, 884 insertions(+), 85 deletions(-)
create mode 100644 docs/src/modules/ntpath.md
create mode 100644 docs/src/modules/path.md
create mode 100644 docs/src/modules/posixpath.md
diff --git a/docs/src/modules/is.md b/docs/src/modules/is.md
index 2ce5488..abcb908 100644
--- a/docs/src/modules/is.md
+++ b/docs/src/modules/is.md
@@ -1,10 +1,10 @@
---
-desc: "Type predicates for Lua values and filesystem path kinds."
+description: "Type predicates for Lua values and filesystem path types."
---
# `is`
-Type predicates for Lua values and filesystem path kinds.
+Type predicates for Lua values and filesystem path types.
## Usage
@@ -65,16 +65,16 @@ is("hello", "STRING") --> true
**Path Checks**:
-| Function | Description |
-| ------------------------- | ------------------------------------------------------- |
-| [`block(v)`](#fn-block) | Returns `true` when `v` is a block device path. |
-| [`char(v)`](#fn-char) | Returns `true` when `v` is a char device path. |
-| [`device(v)`](#fn-device) | Returns `true` when `v` is a block or char device path. |
-| [`dir(v)`](#fn-dir) | Returns `true` when `v` is a directory path. |
-| [`fifo(v)`](#fn-fifo) | Returns `true` when `v` is a FIFO path. |
-| [`file(v)`](#fn-file) | Returns `true` when `v` is a file path. |
-| [`link(v)`](#fn-link) | Returns `true` when `v` is a symlink path. |
-| [`socket(v)`](#fn-socket) | Returns `true` when `v` is a socket path. |
+| Function | Description |
+| ------------------------- | ------------------------------------------------------------ |
+| [`block(v)`](#fn-block) | Returns `true` when `v` is a block device path. |
+| [`char(v)`](#fn-char) | Returns `true` when `v` is a character device path. |
+| [`device(v)`](#fn-device) | Returns `true` when `v` is a block or character device path. |
+| [`dir(v)`](#fn-dir) | Returns `true` when `v` is a directory path. |
+| [`fifo(v)`](#fn-fifo) | Returns `true` when `v` is a FIFO path. |
+| [`file(v)`](#fn-file) | Returns `true` when `v` is a file path. |
+| [`link(v)`](#fn-link) | Returns `true` when `v` is a symlink path. |
+| [`socket(v)`](#fn-socket) | Returns `true` when `v` is a socket path. |
### Type Checks
@@ -362,13 +362,13 @@ is.truthy("non-empty")
### Path Checks
-Filesystem path kind checks.
+Filesystem path type checks.
> [!IMPORTANT]
>
> Path checks require **LuaFileSystem**
-> ([`lfs`](https://github.com/lunarmodules/luafilesystem)) and raise an error it
-> is not installed.
+> ([`lfs`](https://github.com/lunarmodules/luafilesystem)) and raise an error if
+> it is not installed.
#### `block(v)`
@@ -392,7 +392,7 @@ is.block("/dev/sda")
#### `char(v)`
-Returns `true` when `v` is a char device path.
+Returns `true` when `v` is a character device path.
**Parameters**:
@@ -412,7 +412,7 @@ is.char("/dev/null")
#### `device(v)`
-Returns `true` when `v` is a block or char device path.
+Returns `true` when `v` is a block or character device path.
**Parameters**:
diff --git a/docs/src/modules/keyword.md b/docs/src/modules/keyword.md
index 600eab1..502eee8 100644
--- a/docs/src/modules/keyword.md
+++ b/docs/src/modules/keyword.md
@@ -1,5 +1,5 @@
---
-desc: "Lua keyword helpers."
+description: "Lua keyword helpers."
---
# `keyword`
@@ -17,13 +17,13 @@ kw.isidentifier("hello_world") --> true
## Functions
-| Function | Description |
-| ----------------------------------------------------- | ----------------------------------------------------------------------------------- |
-| [`iskeyword(v)`](#fn-iskeyword) | Return `true` when `v` is a reserved Lua keyword. |
-| [`isidentifier(v)`](#fn-isidentifier) | Return `true` when `v` is a valid non-keyword Lua identifier. |
-| [`kwlist()`](#fn-kwlist) | Return Lua keywords as a [`mods.List`](https://luamod.github.io/mods/modules/list). |
-| [`kwset()`](#fn-kwset) | Return Lua keywords as a [`mods.Set`](https://luamod.github.io/mods/modules/set). |
-| [`normalize_identifier(s)`](#fn-normalize-identifier) | Normalize an input into a safe Lua identifier. |
+| Function | Description |
+| ----------------------------------------------------- | ------------------------------------------------------------- |
+| [`iskeyword(v)`](#fn-iskeyword) | Return `true` when `v` is a reserved Lua keyword. |
+| [`isidentifier(v)`](#fn-isidentifier) | Return `true` when `v` is a valid non-keyword Lua identifier. |
+| [`kwlist()`](#fn-kwlist) | Return Lua keywords as a [`mods.List`](/modules/list). |
+| [`kwset()`](#fn-kwset) | Return Lua keywords as a [`mods.Set`](/modules/set). |
+| [`normalize_identifier(s)`](#fn-normalize-identifier) | Normalize an input into a safe Lua identifier. |
@@ -71,8 +71,7 @@ kw.isidentifier("local") --> false
### `kwlist()`
-Return Lua keywords as a
-[`mods.List`](https://luamod.github.io/mods/modules/list).
+Return Lua keywords as a [`mods.List`](/modules/list).
**Return**:
@@ -88,8 +87,7 @@ kw.kwlist():contains("and") --> true
### `kwset()`
-Return Lua keywords as a
-[`mods.Set`](https://luamod.github.io/mods/modules/set).
+Return Lua keywords as a [`mods.Set`](/modules/set).
**Return**:
diff --git a/docs/src/modules/list.md b/docs/src/modules/list.md
index 0071d9c..3e0f300 100644
--- a/docs/src/modules/list.md
+++ b/docs/src/modules/list.md
@@ -1,5 +1,5 @@
---
-desc:
+description:
"A list class providing common operations to create, modify, and query
sequences of values."
---
diff --git a/docs/src/modules/ntpath.md b/docs/src/modules/ntpath.md
new file mode 100644
index 0000000..0687bf4
--- /dev/null
+++ b/docs/src/modules/ntpath.md
@@ -0,0 +1,392 @@
+---
+description: "Lexical path operations for Windows/NT-style paths."
+---
+
+# `ntpath`
+
+Lexical path operations for Windows/NT-style paths.
+
+> [!NOTE]
+>
+> Python `ntpath`-style behavior, ported to Lua.
+
+## Usage
+
+```lua
+ntpath = require "mods.ntpath"
+
+print(ntpath.join([[C:\]], "Users", "me")) --> "C:\Users\me"
+```
+
+## Functions
+
+**Normalization & Predicates**:
+
+| Function | Description |
+| ------------------------------------ | ---------------------------------------------------------- |
+| [`normcase(s)`](#fn-normcase) | Normalize case and separators for NT paths. |
+| [`isabs(path)`](#fn-isabs) | Return `true` when `path` is absolute under NT rules. |
+| [`ismount(path)`](#fn-ismount) | Return `true` when `path` points to a mount root. |
+| [`isreserved(path)`](#fn-isreserved) | Return `true` when `path` contains a reserved NT filename. |
+
+**Path Decomposition**:
+
+| Function | Description |
+| ------------------------------------ | -------------------------------------------------- |
+| [`join(path, ...)`](#fn-join) | Join one or more path components. |
+| [`split(path)`](#fn-split) | Split path into directory head and tail component. |
+| [`splitext(path)`](#fn-splitext) | Split path into a root and extension. |
+| [`splitdrive(path)`](#fn-splitdrive) | Split drive prefix from remainder. |
+| [`splitroot(path)`](#fn-splitroot) | Split path into drive, root, and tail components. |
+| [`basename(path)`](#fn-basename) | Return final path component. |
+| [`dirname(path)`](#fn-dirname) | Return directory portion of a path. |
+
+**Environment Expand**:
+
+| Function | Description |
+| ------------------------------------ | --------------------------------------- |
+| [`expanduser(path)`](#fn-expanduser) | Expand `~` home segment when available. |
+
+**Derived Paths**:
+
+| Function | Description |
+| -------------------------------------- | ------------------------------------------------ |
+| [`normpath(path)`](#fn-normpath) | Normalize separators and dot segments. |
+| [`abspath(path)`](#fn-abspath) | Return normalized absolute path. |
+| [`relpath(path, start?)`](#fn-relpath) | Return `path` relative to optional `start` path. |
+| [`commonpath(paths)`](#fn-commonpath) | Return longest common sub-path from a path list. |
+
+### Normalization & Predicates
+
+
+
+#### `normcase(s)`
+
+Normalize case and separators for NT paths.
+
+**Parameters**:
+
+- `s` (`string`): Path string to normalize.
+
+**Return**:
+
+- `value` (`string`): Normalized lowercase path with `\` separators.
+
+**Example**:
+
+```lua
+ntpath.normcase([[A/B\C]]) --> [[a\b\c]]
+```
+
+
+
+#### `isabs(path)`
+
+Return `true` when `path` is absolute under NT rules.
+
+**Parameters**:
+
+- `path` (`string`): Path to inspect.
+
+**Return**:
+
+- `value` (`boolean`): `true` if the path is absolute.
+
+**Example**:
+
+```lua
+ntpath.isabs([[C:\a]]) --> true
+```
+
+
+
+#### `ismount(path)`
+
+Return `true` when `path` points to a mount root.
+
+**Parameters**:
+
+- `path` (`string`): Path to inspect.
+
+**Return**:
+
+- `value` (`boolean`): `true` if the path resolves to a mount root.
+
+**Example**:
+
+```lua
+ntpath.ismount([[C:\]]) --> true
+```
+
+
+
+#### `isreserved(path)`
+
+Return `true` when `path` contains a reserved NT filename.
+
+**Parameters**:
+
+- `path` (`string`): Path to inspect.
+
+**Return**:
+
+- `value` (`boolean`): `true` if any component is NT-reserved.
+
+**Example**:
+
+```lua
+ntpath.isreserved([[a\CON.txt]]) --> true
+```
+
+### Path Decomposition
+
+
+
+#### `join(path, ...)`
+
+Join one or more path components.
+
+**Parameters**:
+
+- `path` (`string`): Base path component.
+- `...` (`string`): Additional path components to append.
+
+**Return**:
+
+- `value` (`string`): Joined NT path.
+
+**Example**:
+
+```lua
+ntpath.join([[C:\a]], [[b]]) --> [[C:\a\b]]
+```
+
+
+
+#### `split(path)`
+
+Split path into directory head and tail component.
+
+**Parameters**:
+
+- `path` (`string`): Path to split.
+
+**Return**:
+
+- `head` (`string`): Directory portion of the path.
+- `tail` (`string`): Final path component.
+
+**Example**:
+
+```lua
+ntpath.split([[C:\a\b.txt]]) --> [[C:\a]], "b.txt"
+```
+
+
+
+#### `splitext(path)`
+
+Split path into a root and extension.
+
+**Parameters**:
+
+- `path` (`string`): Path to split.
+
+**Return**:
+
+- `root` (`string`): Path without the final extension.
+- `ext` (`string`): Final extension, including the leading dot when present.
+
+**Example**:
+
+```lua
+ntpath.splitext("archive.tar.gz") --> "archive.tar", ".gz"
+```
+
+
+
+#### `splitdrive(path)`
+
+Split drive prefix from remainder.
+
+**Parameters**:
+
+- `path` (`string`): Path to split.
+
+**Return**:
+
+- `drive` (`string`): Drive or UNC share prefix.
+- `rest` (`string`): Remaining path after the drive prefix.
+
+**Example**:
+
+```lua
+ntpath.splitdrive([[C:\a\b]]) --> "C:", [[\a\b]]
+```
+
+
+
+#### `splitroot(path)`
+
+Split path into drive, root, and tail components.
+
+**Parameters**:
+
+- `path` (`string`): Path to split.
+
+**Return**:
+
+- `drive` (`string`): Drive or UNC share prefix.
+- `root` (`string`): Root separator portion.
+- `tail` (`string`): Remaining path after drive and root.
+
+**Example**:
+
+```lua
+ntpath.splitroot([[C:\a\b]]) --> "C:", [[\]], "a\\b"
+```
+
+
+
+#### `basename(path)`
+
+Return final path component.
+
+**Parameters**:
+
+- `path` (`string`): Path to inspect.
+
+**Return**:
+
+- `value` (`string`): Final component of the path.
+
+**Example**:
+
+```lua
+ntpath.basename([[C:\a\b.txt]]) --> "b.txt"
+```
+
+
+
+#### `dirname(path)`
+
+Return directory portion of a path.
+
+**Parameters**:
+
+- `path` (`string`): Path to inspect.
+
+**Return**:
+
+- `value` (`string`): Directory portion of the path.
+
+**Example**:
+
+```lua
+ntpath.dirname([[C:\a\b.txt]]) --> [[C:\a]]
+```
+
+### Environment Expand
+
+
+
+#### `expanduser(path)`
+
+Expand `~` home segment when available.
+
+**Parameters**:
+
+- `path` (`string`): Path that may begin with `~`.
+
+**Return**:
+
+- `value` (`string`): Path with the home segment expanded when available.
+
+**Example**:
+
+```lua
+ntpath.expanduser([[x\y]]) --> [[x\y]]
+```
+
+### Derived Paths
+
+
+
+#### `normpath(path)`
+
+Normalize separators and dot segments.
+
+**Parameters**:
+
+- `path` (`string`): Path to normalize.
+
+**Return**:
+
+- `value` (`string`): Normalized NT path with dot segments resolved lexically.
+
+**Example**:
+
+```lua
+ntpath.normpath([[A/foo/../B]]) --> [[A\B]]
+```
+
+
+
+#### `abspath(path)`
+
+Return normalized absolute path.
+
+**Parameters**:
+
+- `path` (`string`): Path to absolutize.
+
+**Return**:
+
+- `value` (`string`): Normalized absolute NT path.
+
+**Example**:
+
+```lua
+ntpath.abspath([[C:\a\..\b]]) --> [[C:\b]]
+```
+
+
+
+#### `relpath(path, start?)`
+
+Return `path` relative to optional `start` path.
+
+**Parameters**:
+
+- `path` (`string`): Target path.
+- `start?` (`string`): Optional start path used as the base.
+
+**Return**:
+
+- `value` (`string`): Relative path from `start` to `path`.
+
+**Example**:
+
+```lua
+ntpath.relpath([[C:\a\b\c]], [[C:\a]]) --> [[b\c]]
+```
+
+
+
+#### `commonpath(paths)`
+
+Return longest common sub-path from a path list.
+
+**Parameters**:
+
+- `paths` (`string[]`): Input NT paths.
+
+**Return**:
+
+- `value` (`string`): Longest common sub-path.
+
+**Example**:
+
+```lua
+ntpath.commonpath({ [[C:\a\b\c]], [[c:/a/b/d]] }) --> [[C:\a\b]]
+```
diff --git a/docs/src/modules/operator.md b/docs/src/modules/operator.md
index a836ca8..ae780ac 100644
--- a/docs/src/modules/operator.md
+++ b/docs/src/modules/operator.md
@@ -1,5 +1,5 @@
---
-desc: "Operator helpers as functions."
+description: "Operator helpers as functions."
---
# `operator`
diff --git a/docs/src/modules/path.md b/docs/src/modules/path.md
new file mode 100644
index 0000000..cbeb8ba
--- /dev/null
+++ b/docs/src/modules/path.md
@@ -0,0 +1,32 @@
+---
+description:
+ "Shared generic path helpers used by platform-specific path modules."
+---
+
+# `path`
+
+Shared generic path helpers used by platform-specific path modules.
+
+
+## `_splitext(path, sep, altsep?, extsep)`
+
+Split extension from a path. Follows Python `genericpath._splitext` semantics.
+
+**Parameters**:
+
+- `path` (`string`)
+- `sep` (`string`)
+- `altsep?` (`string`)
+- `extsep` (`string`)
+
+**Return**:
+
+- `root` (`string`)
+- `ext` (`string`)
+
+**Example**:
+
+```lua
+local root, ext = path._splitext("archive.tar.gz", "/", nil, ".")
+print(root, ext) --> "archive.tar", ".gz"
+```
diff --git a/docs/src/modules/posixpath.md b/docs/src/modules/posixpath.md
new file mode 100644
index 0000000..db132b0
--- /dev/null
+++ b/docs/src/modules/posixpath.md
@@ -0,0 +1,364 @@
+---
+description: "Lexical path operations for POSIX-style paths."
+---
+
+# `posixpath`
+
+Lexical path operations for POSIX-style paths.
+
+> [!NOTE]
+>
+> Python `posixpath`-style behavior, ported to Lua.
+
+## Usage
+
+```lua
+posixpath = require "mods.posixpath"
+
+print(posixpath.join("/usr", "bin")) --> "/usr/bin"
+```
+
+## Functions
+
+**Normalization & Predicates**:
+
+| Function | Description |
+| -------------------------------- | -------------------------------------- |
+| [`normcase(s)`](#fn-normcase) | Normalize case for POSIX paths. |
+| [`join(a, ...)`](#fn-join) | Join path components. |
+| [`normpath(path)`](#fn-normpath) | Normalize separators and dot segments. |
+| [`isabs(path)`](#fn-isabs) | Return `true` when `path` is absolute. |
+
+**Path Decomposition**:
+
+| Function | Description |
+| ------------------------------------ | -------------------------------------------------- |
+| [`split(path)`](#fn-split) | Split path into directory head and tail component. |
+| [`splitext(path)`](#fn-splitext) | Split path into a root and extension. |
+| [`splitdrive(path)`](#fn-splitdrive) | Split drive prefix from remainder. |
+| [`splitroot(path)`](#fn-splitroot) | Split path into drive, root, and tail components. |
+| [`basename(path)`](#fn-basename) | Return final path component. |
+| [`dirname(path)`](#fn-dirname) | Return directory portion of a path. |
+
+**Environment Expand**:
+
+| Function | Description |
+| ------------------------------------ | --------------------------------------- |
+| [`expanduser(path)`](#fn-expanduser) | Expand `~` home segment when available. |
+
+**Derived Paths**:
+
+| Function | Description |
+| -------------------------------------- | ------------------------------------------------ |
+| [`abspath(path)`](#fn-abspath) | Return normalized absolute path. |
+| [`relpath(path, start?)`](#fn-relpath) | Return `path` relative to optional `start` path. |
+| [`commonpath(paths)`](#fn-commonpath) | Return longest common sub-path from a path list. |
+
+### Normalization & Predicates
+
+
+
+#### `normcase(s)`
+
+Normalize case for POSIX paths.
+
+> [!NOTE]
+>
+> This is a no-op for POSIX semantics.
+
+**Parameters**:
+
+- `s` (`string`): Input path value.
+
+**Return**:
+
+- `value` (`string`): Path after POSIX case normalization.
+
+**Example**:
+
+```lua
+posixpath.normcase("/A/B") --> "/A/B"
+```
+
+
+
+#### `join(a, ...)`
+
+Join path components.
+
+> [!NOTE]
+>
+> Single input is returned as-is.
+
+**Parameters**:
+
+- `a` (`string`): First path component.
+- `...` (`string`): Additional path components.
+
+**Return**:
+
+- `value` (`string`): Joined POSIX path.
+
+**Example**:
+
+```lua
+posixpath.join("/usr", "bin") --> "/usr/bin"
+```
+
+
+
+#### `normpath(path)`
+
+Normalize separators and dot segments.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`string`): Normalized path.
+
+**Example**:
+
+```lua
+posixpath.normpath("/a//./b/..") --> "/a"
+```
+
+
+
+#### `isabs(path)`
+
+Return `true` when `path` is absolute.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`boolean`): True when `path` is absolute.
+
+**Example**:
+
+```lua
+posixpath.isabs("/a/b") --> true
+```
+
+### Path Decomposition
+
+
+
+#### `split(path)`
+
+Split path into directory head and tail component.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `head` (`string`): Directory portion.
+- `tail` (`string`): Final path component.
+
+**Example**:
+
+```lua
+posixpath.split("/a/b.txt") --> "/a", "b.txt"
+```
+
+
+
+#### `splitext(path)`
+
+Split path into a root and extension.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `root` (`string`): Path without the final extension.
+- `ext` (`string`): Final extension including leading dot.
+
+**Example**:
+
+```lua
+posixpath.splitext("archive.tar.gz") --> "archive.tar", ".gz"
+```
+
+
+
+#### `splitdrive(path)`
+
+Split drive prefix from remainder.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `drive` (`string`): Drive prefix (always empty on POSIX).
+- `rest` (`string`): Path remainder.
+
+**Example**:
+
+```lua
+posixpath.splitdrive("/a/b") --> "", "/a/b"
+```
+
+> [!NOTE]
+>
+> Split drive prefix (always empty on POSIX) from remainder.
+
+
+
+#### `splitroot(path)`
+
+Split path into drive, root, and tail components.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `drive` (`string`): Drive prefix (always empty on POSIX).
+- `root` (`string`): Root separator segment.
+- `tail` (`string`): Remaining path without leading root separator.
+
+**Example**:
+
+```lua
+posixpath.splitroot("/a/b") --> "", "/", "a/b"
+```
+
+
+
+#### `basename(path)`
+
+Return final path component.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`string`): Final path component.
+
+**Example**:
+
+```lua
+posixpath.basename("/a/b.txt") --> "b.txt"
+```
+
+
+
+#### `dirname(path)`
+
+Return directory portion of a path.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`string`): Parent directory path.
+
+**Example**:
+
+```lua
+posixpath.dirname("/a/b.txt") --> "/a"
+```
+
+### Environment Expand
+
+
+
+#### `expanduser(path)`
+
+Expand `~` home segment when available.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`string`): Path with `~` expanded when possible.
+
+**Example**:
+
+```lua
+posixpath.expanduser("~/tmp") --> "/tmp" (when HOME is set)
+```
+
+### Derived Paths
+
+
+
+#### `abspath(path)`
+
+Return normalized absolute path.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+
+**Return**:
+
+- `value` (`string`): Absolute normalized path.
+
+**Example**:
+
+```lua
+posixpath.abspath("/a/./b") --> "/a/b"
+```
+
+
+
+#### `relpath(path, start?)`
+
+Return `path` relative to optional `start` path.
+
+**Parameters**:
+
+- `path` (`string`): Input path.
+- `start?` (`string`): Optional base path.
+
+**Return**:
+
+- `value` (`string`): Path relative to `start` (or current directory when
+ omitted).
+
+**Example**:
+
+```lua
+posixpath.relpath("/a/b/c", "/a") --> "b/c"
+```
+
+
+
+#### `commonpath(paths)`
+
+Return longest common sub-path from a path list.
+
+**Parameters**:
+
+- `paths` (`string[]`): List of POSIX paths.
+
+**Return**:
+
+- `value` (`string`): Longest common sub-path, or empty string when `paths` is
+ empty.
+
+**Example**:
+
+```lua
+posixpath.commonpath({ "/a/b/c", "/a/b/d" }) --> "/a/b"
+```
diff --git a/docs/src/modules/repr.md b/docs/src/modules/repr.md
index 2590049..e0ffceb 100644
--- a/docs/src/modules/repr.md
+++ b/docs/src/modules/repr.md
@@ -1,5 +1,5 @@
---
-desc: "Render any Lua value as a readable string."
+description: "Render any Lua value as a readable string."
---
# `repr`
diff --git a/docs/src/modules/runtime.md b/docs/src/modules/runtime.md
index adfe43c..e8c2b99 100644
--- a/docs/src/modules/runtime.md
+++ b/docs/src/modules/runtime.md
@@ -1,5 +1,5 @@
---
-desc: "Exposes Lua runtime metadata and version compatibility flags."
+description: "Exposes Lua runtime metadata and version compatibility flags."
---
# `runtime`
@@ -25,6 +25,7 @@ print(runtime.is_lua54) --> true | false
| [`minor`](#minor) | Minor version number parsed from `version`. |
| [`version_num`](#version-num) | Numeric version encoded as `major * 100 + minor`. |
| [`is_luajit`](#is-luajit) | True when running under LuaJIT. |
+| [`is_windows`](#is-windows) | True when running on a Windows host. |
| [`is_lua51`](#is-lua51) | True only on Lua 5.1 runtimes. |
| [`is_lua52`](#is-lua52) | True only on Lua 5.2 runtimes. |
| [`is_lua53`](#is-lua53) | True only on Lua 5.3 runtimes. |
@@ -70,6 +71,14 @@ True when running under LuaJIT.
print(runtime.is_luajit) --> true | false
```
+### `is_windows`
+
+True when running on a Windows host.
+
+```lua
+print(runtime.is_windows) --> true | false
+```
+
### `is_lua51`
True only on Lua 5.1 runtimes.
diff --git a/docs/src/modules/set.md b/docs/src/modules/set.md
index 1c6768d..ad774bf 100644
--- a/docs/src/modules/set.md
+++ b/docs/src/modules/set.md
@@ -1,5 +1,5 @@
---
-desc:
+description:
"A set class providing common operations to create, modify, and query
collections of unique values."
---
diff --git a/docs/src/modules/str.md b/docs/src/modules/str.md
index 391a811..6ed0bc6 100644
--- a/docs/src/modules/str.md
+++ b/docs/src/modules/str.md
@@ -1,5 +1,5 @@
---
-desc: "String utility helpers modeled after Python's `str`."
+description: "String utility helpers modeled after Python's `str`."
---
# `str`
@@ -247,8 +247,7 @@ s = format_map("hi {name}", { name = "bob" }) --> "hi bob"
> [!NOTE]
>
> `format_map` is a lightweight `{key}` replacement helper. For richer
-> templating, use
-> [`mods.template`](https://luamod.github.io/mods/modules/template).
+> templating, use [`mods.template`](/modules/template).
### Predicates
diff --git a/docs/src/modules/stringcase.md b/docs/src/modules/stringcase.md
index 69c02ed..d073e0f 100644
--- a/docs/src/modules/stringcase.md
+++ b/docs/src/modules/stringcase.md
@@ -1,5 +1,5 @@
---
-desc: "String case conversion helpers."
+description: "String case conversion helpers."
---
# `stringcase`
diff --git a/docs/src/modules/tbl.md b/docs/src/modules/tbl.md
index 1e8128d..17590a0 100644
--- a/docs/src/modules/tbl.md
+++ b/docs/src/modules/tbl.md
@@ -1,5 +1,5 @@
---
-desc: "Utility functions for working with Lua tables."
+description: "Utility functions for working with Lua tables."
---
# `tbl`
@@ -39,7 +39,6 @@ print(tbl.count({ a = 1, b = 2 })) --> 2
| [`same(a, b)`](#fn-same) | Return `true` if two tables have the same keys and equal values. |
| [`find_if(t, pred)`](#fn-find-if) | Find first value and key matching predicate. |
| [`get(t, ...)`](#fn-get) | Safely get nested value by keys. |
-| [`keypath(...)`](#fn-keypath) | Format a key chain as a Lua-like table access path. |
**Transforms**:
@@ -263,29 +262,6 @@ v2 = get(t) --> { a = { b = { c = 1 } } }
>
> If no keys are provided, returns the input table.
-
-
-#### `keypath(...)`
-
-Format a key chain as a Lua-like table access path.
-
-**Parameters**:
-
-- `...` (`any`): Additional arguments.
-
-**Return**:
-
-- `path` (`string`): Rendered key path.
-
-**Example**:
-
-```lua
-p1 = keypath("t", "a", "b", "c") --> "t.a.b.c"
-p2 = keypath("ctx", "users", 1, "name") --> "ctx.users[1].name"
-p3 = keypath("ctx", "invalid-key") --> 'ctx["invalid-key"]'
-p4 = keypath() --> ""
-```
-
### Transforms
Table transformation and conversion utilities.
diff --git a/docs/src/modules/template.md b/docs/src/modules/template.md
index 407ffb3..6488c2d 100644
--- a/docs/src/modules/template.md
+++ b/docs/src/modules/template.md
@@ -1,5 +1,5 @@
---
-desc: "Interpolate string placeholders of the form {{."
+description: "Interpolate string placeholders of the form {{."
---
# `template`
@@ -85,8 +85,7 @@ template("Hi {{name_func}}", view) --> "Hi Ada"
## Table Values
-Table placeholders are rendered using
-[`mods.repr`](https://luamod.github.io/mods/modules/repr).
+Table placeholders are rendered using `mods.repr`.
```lua
view = { data = { a = 1, b = true } }
diff --git a/docs/src/modules/utils.md b/docs/src/modules/utils.md
index 4fa475d..9bdd03c 100644
--- a/docs/src/modules/utils.md
+++ b/docs/src/modules/utils.md
@@ -1,5 +1,5 @@
---
-desc: "Small shared utility helpers used by modules in this library."
+description: "Small shared utility helpers used by modules in this library."
---
# `utils`
@@ -24,11 +24,11 @@ Smart-quote a string for readable Lua-like output.
**Parameters**:
-- `v` (`string`)
+- `v` (`string`): String to quote.
**Return**:
-- `out` (`string`)
+- `out` (`string`): Quoted string.
**Example**:
@@ -37,30 +37,60 @@ print(utils.quote('He said "hi"')) -- 'He said "hi"'
print(utils.quote('say "hi" and \\'bye\\'')) -- "say \"hi\" and 'bye'"
```
-
+
-### `repr(v)`
+### `keypath(...)`
-Render any Lua value as a string.
+Format a key chain as a Lua-like table access path.
-> [!NOTE]
->
-> Uses [`inspect`](https://github.com/kikito/inspect.lua) when available,
-> otherwise falls back to
-> [`mods.repr`](https://luamod.github.io/mods/modules/repr).
+**Parameters**:
+
+- `...` (`any`): Additional arguments.
+
+**Return**:
+
+- `path` (`string`): Rendered key path.
+
+**Example**:
+
+```lua
+p1 = utils.keypath("t", "a", "b", "c") --> "t.a.b.c"
+p2 = utils.keypath("ctx", "users", 1, "name") --> "ctx.users[1].name"
+p3 = utils.keypath("ctx", "invalid-key") --> 'ctx["invalid-key"]'
+p4 = utils.keypath() --> ""
+```
+
+
+
+### `assert_arg(argn, v, tp?, level?, msg?)`
+
+Assert argument value using [`mods.validate`](/modules/validate) and raise a Lua
+error on failure.
**Parameters**:
-- `v` (`any`)
+- `argn` (`integer`): Argument index for error context.
+- `v` (`T`): Value to check.
+- `tp?` (`modsIsType`): Validator name (defaults to `"truthy"`).
+- `level?` (`integer`): Optional error level for `error(...)` (defaults to `2`).
+- `msg?` (`string`): Optional override template passed to
+ [`mods.validate`](/modules/validate).
**Return**:
-- `out` (`string`)
+- `v` (`T`): Same input value on success.
**Example**:
```lua
-print(utils.repr({ a = 1 })) --> {
--- a = 1
--- }
+utils.assert_arg(1, "ok", "string") --> "ok"
+utils.assert_arg(2, 123, "string")
+--> raises: bad argument #2 (expected string, got number)
+utils.assert_arg(3, "x", "number", 2, "need {{expected}}, got {{got}}")
+--> raises: bad argument #3 (need number, got string)
```
+
+> [!NOTE]
+>
+> When the caller function name is available, error text includes
+> `to ''` (Lua-style bad argument context).
diff --git a/docs/src/modules/validate.md b/docs/src/modules/validate.md
index d6dbf4a..53e3d36 100644
--- a/docs/src/modules/validate.md
+++ b/docs/src/modules/validate.md
@@ -1,5 +1,5 @@
---
-desc: "Validation checks for values and filesystem path types."
+description: "Validation checks for values and filesystem path types."
---
# `validate`
@@ -667,8 +667,8 @@ ok, err = validate.number("x") --> false, "need number, got string"
> validate.messages.truthy = "expected {{expected}} value, got {{value}}"
> validate.truthy(nil) --> false, "expected truthy value, got no value"
> ```
->
-> **Default Messages**:
+
+**Default Messages**:
- Type checks: expected {{expected}}, got {{got}}
- Value checks: expected {{expected}} value, got {{value}}
From 8de1716f85dee7915dd8a1af1673fe2ace6f6e75 Mon Sep 17 00:00:00 2001
From: Haitham Moahmed <128622475+haithium@users.noreply.github.com>
Date: Fri, 6 Mar 2026 09:50:49 +0200
Subject: [PATCH 2/4] Delete docs/src/modules/ntpath.md
---
docs/src/modules/ntpath.md | 392 -------------------------------------
1 file changed, 392 deletions(-)
delete mode 100644 docs/src/modules/ntpath.md
diff --git a/docs/src/modules/ntpath.md b/docs/src/modules/ntpath.md
deleted file mode 100644
index 0687bf4..0000000
--- a/docs/src/modules/ntpath.md
+++ /dev/null
@@ -1,392 +0,0 @@
----
-description: "Lexical path operations for Windows/NT-style paths."
----
-
-# `ntpath`
-
-Lexical path operations for Windows/NT-style paths.
-
-> [!NOTE]
->
-> Python `ntpath`-style behavior, ported to Lua.
-
-## Usage
-
-```lua
-ntpath = require "mods.ntpath"
-
-print(ntpath.join([[C:\]], "Users", "me")) --> "C:\Users\me"
-```
-
-## Functions
-
-**Normalization & Predicates**:
-
-| Function | Description |
-| ------------------------------------ | ---------------------------------------------------------- |
-| [`normcase(s)`](#fn-normcase) | Normalize case and separators for NT paths. |
-| [`isabs(path)`](#fn-isabs) | Return `true` when `path` is absolute under NT rules. |
-| [`ismount(path)`](#fn-ismount) | Return `true` when `path` points to a mount root. |
-| [`isreserved(path)`](#fn-isreserved) | Return `true` when `path` contains a reserved NT filename. |
-
-**Path Decomposition**:
-
-| Function | Description |
-| ------------------------------------ | -------------------------------------------------- |
-| [`join(path, ...)`](#fn-join) | Join one or more path components. |
-| [`split(path)`](#fn-split) | Split path into directory head and tail component. |
-| [`splitext(path)`](#fn-splitext) | Split path into a root and extension. |
-| [`splitdrive(path)`](#fn-splitdrive) | Split drive prefix from remainder. |
-| [`splitroot(path)`](#fn-splitroot) | Split path into drive, root, and tail components. |
-| [`basename(path)`](#fn-basename) | Return final path component. |
-| [`dirname(path)`](#fn-dirname) | Return directory portion of a path. |
-
-**Environment Expand**:
-
-| Function | Description |
-| ------------------------------------ | --------------------------------------- |
-| [`expanduser(path)`](#fn-expanduser) | Expand `~` home segment when available. |
-
-**Derived Paths**:
-
-| Function | Description |
-| -------------------------------------- | ------------------------------------------------ |
-| [`normpath(path)`](#fn-normpath) | Normalize separators and dot segments. |
-| [`abspath(path)`](#fn-abspath) | Return normalized absolute path. |
-| [`relpath(path, start?)`](#fn-relpath) | Return `path` relative to optional `start` path. |
-| [`commonpath(paths)`](#fn-commonpath) | Return longest common sub-path from a path list. |
-
-### Normalization & Predicates
-
-
-
-#### `normcase(s)`
-
-Normalize case and separators for NT paths.
-
-**Parameters**:
-
-- `s` (`string`): Path string to normalize.
-
-**Return**:
-
-- `value` (`string`): Normalized lowercase path with `\` separators.
-
-**Example**:
-
-```lua
-ntpath.normcase([[A/B\C]]) --> [[a\b\c]]
-```
-
-
-
-#### `isabs(path)`
-
-Return `true` when `path` is absolute under NT rules.
-
-**Parameters**:
-
-- `path` (`string`): Path to inspect.
-
-**Return**:
-
-- `value` (`boolean`): `true` if the path is absolute.
-
-**Example**:
-
-```lua
-ntpath.isabs([[C:\a]]) --> true
-```
-
-
-
-#### `ismount(path)`
-
-Return `true` when `path` points to a mount root.
-
-**Parameters**:
-
-- `path` (`string`): Path to inspect.
-
-**Return**:
-
-- `value` (`boolean`): `true` if the path resolves to a mount root.
-
-**Example**:
-
-```lua
-ntpath.ismount([[C:\]]) --> true
-```
-
-
-
-#### `isreserved(path)`
-
-Return `true` when `path` contains a reserved NT filename.
-
-**Parameters**:
-
-- `path` (`string`): Path to inspect.
-
-**Return**:
-
-- `value` (`boolean`): `true` if any component is NT-reserved.
-
-**Example**:
-
-```lua
-ntpath.isreserved([[a\CON.txt]]) --> true
-```
-
-### Path Decomposition
-
-
-
-#### `join(path, ...)`
-
-Join one or more path components.
-
-**Parameters**:
-
-- `path` (`string`): Base path component.
-- `...` (`string`): Additional path components to append.
-
-**Return**:
-
-- `value` (`string`): Joined NT path.
-
-**Example**:
-
-```lua
-ntpath.join([[C:\a]], [[b]]) --> [[C:\a\b]]
-```
-
-
-
-#### `split(path)`
-
-Split path into directory head and tail component.
-
-**Parameters**:
-
-- `path` (`string`): Path to split.
-
-**Return**:
-
-- `head` (`string`): Directory portion of the path.
-- `tail` (`string`): Final path component.
-
-**Example**:
-
-```lua
-ntpath.split([[C:\a\b.txt]]) --> [[C:\a]], "b.txt"
-```
-
-
-
-#### `splitext(path)`
-
-Split path into a root and extension.
-
-**Parameters**:
-
-- `path` (`string`): Path to split.
-
-**Return**:
-
-- `root` (`string`): Path without the final extension.
-- `ext` (`string`): Final extension, including the leading dot when present.
-
-**Example**:
-
-```lua
-ntpath.splitext("archive.tar.gz") --> "archive.tar", ".gz"
-```
-
-
-
-#### `splitdrive(path)`
-
-Split drive prefix from remainder.
-
-**Parameters**:
-
-- `path` (`string`): Path to split.
-
-**Return**:
-
-- `drive` (`string`): Drive or UNC share prefix.
-- `rest` (`string`): Remaining path after the drive prefix.
-
-**Example**:
-
-```lua
-ntpath.splitdrive([[C:\a\b]]) --> "C:", [[\a\b]]
-```
-
-
-
-#### `splitroot(path)`
-
-Split path into drive, root, and tail components.
-
-**Parameters**:
-
-- `path` (`string`): Path to split.
-
-**Return**:
-
-- `drive` (`string`): Drive or UNC share prefix.
-- `root` (`string`): Root separator portion.
-- `tail` (`string`): Remaining path after drive and root.
-
-**Example**:
-
-```lua
-ntpath.splitroot([[C:\a\b]]) --> "C:", [[\]], "a\\b"
-```
-
-
-
-#### `basename(path)`
-
-Return final path component.
-
-**Parameters**:
-
-- `path` (`string`): Path to inspect.
-
-**Return**:
-
-- `value` (`string`): Final component of the path.
-
-**Example**:
-
-```lua
-ntpath.basename([[C:\a\b.txt]]) --> "b.txt"
-```
-
-
-
-#### `dirname(path)`
-
-Return directory portion of a path.
-
-**Parameters**:
-
-- `path` (`string`): Path to inspect.
-
-**Return**:
-
-- `value` (`string`): Directory portion of the path.
-
-**Example**:
-
-```lua
-ntpath.dirname([[C:\a\b.txt]]) --> [[C:\a]]
-```
-
-### Environment Expand
-
-
-
-#### `expanduser(path)`
-
-Expand `~` home segment when available.
-
-**Parameters**:
-
-- `path` (`string`): Path that may begin with `~`.
-
-**Return**:
-
-- `value` (`string`): Path with the home segment expanded when available.
-
-**Example**:
-
-```lua
-ntpath.expanduser([[x\y]]) --> [[x\y]]
-```
-
-### Derived Paths
-
-
-
-#### `normpath(path)`
-
-Normalize separators and dot segments.
-
-**Parameters**:
-
-- `path` (`string`): Path to normalize.
-
-**Return**:
-
-- `value` (`string`): Normalized NT path with dot segments resolved lexically.
-
-**Example**:
-
-```lua
-ntpath.normpath([[A/foo/../B]]) --> [[A\B]]
-```
-
-
-
-#### `abspath(path)`
-
-Return normalized absolute path.
-
-**Parameters**:
-
-- `path` (`string`): Path to absolutize.
-
-**Return**:
-
-- `value` (`string`): Normalized absolute NT path.
-
-**Example**:
-
-```lua
-ntpath.abspath([[C:\a\..\b]]) --> [[C:\b]]
-```
-
-
-
-#### `relpath(path, start?)`
-
-Return `path` relative to optional `start` path.
-
-**Parameters**:
-
-- `path` (`string`): Target path.
-- `start?` (`string`): Optional start path used as the base.
-
-**Return**:
-
-- `value` (`string`): Relative path from `start` to `path`.
-
-**Example**:
-
-```lua
-ntpath.relpath([[C:\a\b\c]], [[C:\a]]) --> [[b\c]]
-```
-
-
-
-#### `commonpath(paths)`
-
-Return longest common sub-path from a path list.
-
-**Parameters**:
-
-- `paths` (`string[]`): Input NT paths.
-
-**Return**:
-
-- `value` (`string`): Longest common sub-path.
-
-**Example**:
-
-```lua
-ntpath.commonpath({ [[C:\a\b\c]], [[c:/a/b/d]] }) --> [[C:\a\b]]
-```
From d183a52123c679a6053e5ff248bac8c04108fe11 Mon Sep 17 00:00:00 2001
From: Haitham Moahmed <128622475+haithium@users.noreply.github.com>
Date: Fri, 6 Mar 2026 09:51:04 +0200
Subject: [PATCH 3/4] Delete docs/src/modules/path.md
---
docs/src/modules/path.md | 32 --------------------------------
1 file changed, 32 deletions(-)
delete mode 100644 docs/src/modules/path.md
diff --git a/docs/src/modules/path.md b/docs/src/modules/path.md
deleted file mode 100644
index cbeb8ba..0000000
--- a/docs/src/modules/path.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-description:
- "Shared generic path helpers used by platform-specific path modules."
----
-
-# `path`
-
-Shared generic path helpers used by platform-specific path modules.
-
-
-## `_splitext(path, sep, altsep?, extsep)`
-
-Split extension from a path. Follows Python `genericpath._splitext` semantics.
-
-**Parameters**:
-
-- `path` (`string`)
-- `sep` (`string`)
-- `altsep?` (`string`)
-- `extsep` (`string`)
-
-**Return**:
-
-- `root` (`string`)
-- `ext` (`string`)
-
-**Example**:
-
-```lua
-local root, ext = path._splitext("archive.tar.gz", "/", nil, ".")
-print(root, ext) --> "archive.tar", ".gz"
-```
From ecc336b8a3ff649ee26c2d25e679287ffc29eeb2 Mon Sep 17 00:00:00 2001
From: Haitham Moahmed <128622475+haithium@users.noreply.github.com>
Date: Fri, 6 Mar 2026 09:51:21 +0200
Subject: [PATCH 4/4] Delete docs/src/modules/posixpath.md
---
docs/src/modules/posixpath.md | 364 ----------------------------------
1 file changed, 364 deletions(-)
delete mode 100644 docs/src/modules/posixpath.md
diff --git a/docs/src/modules/posixpath.md b/docs/src/modules/posixpath.md
deleted file mode 100644
index db132b0..0000000
--- a/docs/src/modules/posixpath.md
+++ /dev/null
@@ -1,364 +0,0 @@
----
-description: "Lexical path operations for POSIX-style paths."
----
-
-# `posixpath`
-
-Lexical path operations for POSIX-style paths.
-
-> [!NOTE]
->
-> Python `posixpath`-style behavior, ported to Lua.
-
-## Usage
-
-```lua
-posixpath = require "mods.posixpath"
-
-print(posixpath.join("/usr", "bin")) --> "/usr/bin"
-```
-
-## Functions
-
-**Normalization & Predicates**:
-
-| Function | Description |
-| -------------------------------- | -------------------------------------- |
-| [`normcase(s)`](#fn-normcase) | Normalize case for POSIX paths. |
-| [`join(a, ...)`](#fn-join) | Join path components. |
-| [`normpath(path)`](#fn-normpath) | Normalize separators and dot segments. |
-| [`isabs(path)`](#fn-isabs) | Return `true` when `path` is absolute. |
-
-**Path Decomposition**:
-
-| Function | Description |
-| ------------------------------------ | -------------------------------------------------- |
-| [`split(path)`](#fn-split) | Split path into directory head and tail component. |
-| [`splitext(path)`](#fn-splitext) | Split path into a root and extension. |
-| [`splitdrive(path)`](#fn-splitdrive) | Split drive prefix from remainder. |
-| [`splitroot(path)`](#fn-splitroot) | Split path into drive, root, and tail components. |
-| [`basename(path)`](#fn-basename) | Return final path component. |
-| [`dirname(path)`](#fn-dirname) | Return directory portion of a path. |
-
-**Environment Expand**:
-
-| Function | Description |
-| ------------------------------------ | --------------------------------------- |
-| [`expanduser(path)`](#fn-expanduser) | Expand `~` home segment when available. |
-
-**Derived Paths**:
-
-| Function | Description |
-| -------------------------------------- | ------------------------------------------------ |
-| [`abspath(path)`](#fn-abspath) | Return normalized absolute path. |
-| [`relpath(path, start?)`](#fn-relpath) | Return `path` relative to optional `start` path. |
-| [`commonpath(paths)`](#fn-commonpath) | Return longest common sub-path from a path list. |
-
-### Normalization & Predicates
-
-
-
-#### `normcase(s)`
-
-Normalize case for POSIX paths.
-
-> [!NOTE]
->
-> This is a no-op for POSIX semantics.
-
-**Parameters**:
-
-- `s` (`string`): Input path value.
-
-**Return**:
-
-- `value` (`string`): Path after POSIX case normalization.
-
-**Example**:
-
-```lua
-posixpath.normcase("/A/B") --> "/A/B"
-```
-
-
-
-#### `join(a, ...)`
-
-Join path components.
-
-> [!NOTE]
->
-> Single input is returned as-is.
-
-**Parameters**:
-
-- `a` (`string`): First path component.
-- `...` (`string`): Additional path components.
-
-**Return**:
-
-- `value` (`string`): Joined POSIX path.
-
-**Example**:
-
-```lua
-posixpath.join("/usr", "bin") --> "/usr/bin"
-```
-
-
-
-#### `normpath(path)`
-
-Normalize separators and dot segments.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`string`): Normalized path.
-
-**Example**:
-
-```lua
-posixpath.normpath("/a//./b/..") --> "/a"
-```
-
-
-
-#### `isabs(path)`
-
-Return `true` when `path` is absolute.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`boolean`): True when `path` is absolute.
-
-**Example**:
-
-```lua
-posixpath.isabs("/a/b") --> true
-```
-
-### Path Decomposition
-
-
-
-#### `split(path)`
-
-Split path into directory head and tail component.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `head` (`string`): Directory portion.
-- `tail` (`string`): Final path component.
-
-**Example**:
-
-```lua
-posixpath.split("/a/b.txt") --> "/a", "b.txt"
-```
-
-
-
-#### `splitext(path)`
-
-Split path into a root and extension.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `root` (`string`): Path without the final extension.
-- `ext` (`string`): Final extension including leading dot.
-
-**Example**:
-
-```lua
-posixpath.splitext("archive.tar.gz") --> "archive.tar", ".gz"
-```
-
-
-
-#### `splitdrive(path)`
-
-Split drive prefix from remainder.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `drive` (`string`): Drive prefix (always empty on POSIX).
-- `rest` (`string`): Path remainder.
-
-**Example**:
-
-```lua
-posixpath.splitdrive("/a/b") --> "", "/a/b"
-```
-
-> [!NOTE]
->
-> Split drive prefix (always empty on POSIX) from remainder.
-
-
-
-#### `splitroot(path)`
-
-Split path into drive, root, and tail components.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `drive` (`string`): Drive prefix (always empty on POSIX).
-- `root` (`string`): Root separator segment.
-- `tail` (`string`): Remaining path without leading root separator.
-
-**Example**:
-
-```lua
-posixpath.splitroot("/a/b") --> "", "/", "a/b"
-```
-
-
-
-#### `basename(path)`
-
-Return final path component.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`string`): Final path component.
-
-**Example**:
-
-```lua
-posixpath.basename("/a/b.txt") --> "b.txt"
-```
-
-
-
-#### `dirname(path)`
-
-Return directory portion of a path.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`string`): Parent directory path.
-
-**Example**:
-
-```lua
-posixpath.dirname("/a/b.txt") --> "/a"
-```
-
-### Environment Expand
-
-
-
-#### `expanduser(path)`
-
-Expand `~` home segment when available.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`string`): Path with `~` expanded when possible.
-
-**Example**:
-
-```lua
-posixpath.expanduser("~/tmp") --> "/tmp" (when HOME is set)
-```
-
-### Derived Paths
-
-
-
-#### `abspath(path)`
-
-Return normalized absolute path.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-
-**Return**:
-
-- `value` (`string`): Absolute normalized path.
-
-**Example**:
-
-```lua
-posixpath.abspath("/a/./b") --> "/a/b"
-```
-
-
-
-#### `relpath(path, start?)`
-
-Return `path` relative to optional `start` path.
-
-**Parameters**:
-
-- `path` (`string`): Input path.
-- `start?` (`string`): Optional base path.
-
-**Return**:
-
-- `value` (`string`): Path relative to `start` (or current directory when
- omitted).
-
-**Example**:
-
-```lua
-posixpath.relpath("/a/b/c", "/a") --> "b/c"
-```
-
-
-
-#### `commonpath(paths)`
-
-Return longest common sub-path from a path list.
-
-**Parameters**:
-
-- `paths` (`string[]`): List of POSIX paths.
-
-**Return**:
-
-- `value` (`string`): Longest common sub-path, or empty string when `paths` is
- empty.
-
-**Example**:
-
-```lua
-posixpath.commonpath({ "/a/b/c", "/a/b/d" }) --> "/a/b"
-```