/

Listing files

The .listfiles {path} {directories?} {recursive?} {pattern?} {fullpath?} {sortby?} {order?} docs ↗ function returns an iterable of entries from a directory.

By default, the result is an unordered collection of absolute paths to the immediate children of the directory at path. The path is interpreted relative to the main source file’s location, or as an absolute path. Use a slash (/) as the path separator, regardless of the operating system.

For the following examples, assume the following directory structure:

  • assets
    • folder
      • file1.txt
      • file2.txt
      • file3.md
      • subfolder
        • nested-file1.txt
        • nested-file2.txt
        • nested-file3.md

Example 1

.listfiles {assets/folder} fullpath:{no}
  • file3.md

  • file2.txt

  • subfolder

  • file1.txt

The result is an iterable value, that can be passed to .foreach.

Example 2

.foreach {.listfiles {assets/folder} fullpath:{no}}
    name:
    **File:** .name

File: file3.md

File: file2.txt

File: subfolder

File: file1.txt

Full paths

By default, each entry is returned as its absolute path:

Example 3

.listfiles {assets/folder}
  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file3.md

  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file2.txt

  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/subfolder

  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file1.txt

This can be used in combination with file data functions to read file content:

Example 4

.foreach {.listfiles {assets/folder} directories:{no}}
    path:
    Content of .path::filename::codespan is .path::read::codespan

Content of file3.md is File 3

Content of file2.txt is File 2

Content of file1.txt is File 1

Recursive traversal

Setting recursive:{yes} walks every nested subdirectory and returns all descendants, not just the immediate children.

Example 5

.listfiles {assets/folder} recursive:{yes} fullpath:{no}
  • file3.md

  • file2.txt

  • subfolder

  • nested-file2.txt

  • nested-file3.md

  • nested-file1.txt

  • file1.txt

The root directory itself is never included in the result.

Filtering by name

Passing a pattern keeps only entries whose bare file name matches the given regular expression. The pattern always applies to the file name alone (never to a directory path), regardless of fullpath or recursive.

Example 6

.listfiles {assets/folder} pattern:{.*\.txt} recursive:{yes} fullpath:{no}
  • file2.txt

  • nested-file2.txt

  • nested-file1.txt

  • file1.txt

Excluding directories

Set directories:{no} to keep only files in the result, omitting subdirectories from the output:

Example 7

.listfiles {assets/folder} directories:{no}
  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file3.md

  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file2.txt

  • /home/runner/work/quarkdown/quarkdown/docs/./assets/folder/file1.txt

Sorting

By default, the order of the result is unspecified, and the returned iterable is unordered. Picking a sort criterion via sortby switches the result to an ordered iterable:

ValueEffect
noneNo sorting; the result is an unordered collection (default).
nameSort by file name, using a human-friendly alphanumeric comparator.
lastmodifiedSort by the file’s last-modified timestamp.

The order parameter then chooses the direction:

Example 8

.listfiles {assets/folder} sortby:{name} order:{descending} fullpath:{no}
  1. subfolder

  2. file3.md

  3. file2.txt

  4. file1.txt

Bulk inclusion of sources

Because the result is iterable, it composes naturally with .includeall:

Example 9

This loads every file under chapters/ in alphabetical order:

.listfiles {chapters} sortby:{name}::includeall

Permissions

.listfiles follows the same permission model as the other file-reading functions: