passageway-connector-markdown
A passageway connector that turns a folder of markdown files into searchable items: a docs folder, an Obsidian vault, a Jekyll or Hugo site, or the articles of the frozen Wikipedia corpus.
What it does
- Each markdown file is one item. Its id is the path relative to the folder (or an
idin its front matter) and its version is a hash of the file, so an edit re-indexes just that note. - Front matter gives the metadata: title, address, date, tags, id and weight (see the table below).
- Headings become sections. Every heading level starts a section whose heading is the trail of its parents, such as
Setup › Linux, so a hit says where in the note it is. - Folders become the breadcrumb, and links between notes become related items:
[text](other.md)and[[Other]]. - Files that cannot be indexed are skipped, not fatal. A file that is not UTF-8 text, holds binary data or is too big is skipped with a warning on stderr, and the rest of the folder is indexed.
Install
Add the connector to the environment that runs passageway (see Install):
uv tool install \
--with 'passageway-connector-markdown @ git+https://github.com/getpassageway/passageway#subdirectory=connectors/markdown' \
git+https://github.com/getpassageway/passageway
An example
A note ops/rotating-certificates.md:
---
title: Rotating certificates
tags: [ops, security]
url: https://wiki.example.org/ops/certs
---
# Rotating certificates
Rotate the signing certificate every year.
## Steps
1. Create the new certificate.
2. Follow [the deploy guide](deploy.md).
becomes this item (shortened):
{
"id": "ops/rotating-certificates.md",
"title": "Rotating certificates",
"url": "https://wiki.example.org/ops/certs",
"path": ["ops"],
"labels": ["ops", "security"],
"links": ["ops/deploy.md"],
"sections": [
{
"heading": null,
"text": "Rotate the signing certificate every year."
},
{
"heading": "Steps",
"text": "1. Create the new certificate.\n2. Follow [the deploy guide](deploy.md)."
}
]
}
Configure
In passageway.toml (use the interpreter that has passageway installed, see Install):
[[connector]]
name = "notes"
command = ["/path/to/python", "-m", "passageway_connector_markdown"]
env = { FOLDER = "/Users/you/notes", EXCLUDE = "drafts/**|*.draft.md" }
| Setting | Default | Meaning |
|---|---|---|
FOLDER |
required | The folder to index, including its subfolders |
INCLUDE |
*.md|*.markdown |
Glob patterns for the files to index, separated by |. * stays within a folder, ** crosses folders, and a pattern without / matches the file name at any depth. Replaces the default |
EXCLUDE |
Glob patterns for files to leave out, the same syntax | |
MAX_FILE_BYTES |
1048576 |
Files larger than this are skipped with a warning. The core accepts at most 4 MiB per item line and the output escapes non-ASCII text, which can triple its size, so keep this at or below 1 MiB unless your notes are plain ASCII |
Always skipped: hidden files and folders (names starting with ., such as .git and .obsidian) and node_modules. Symlinked folders are not followed, and a symlinked file counts only if it points inside FOLDER.
Front matter
A file may start with a YAML block between --- lines. These keys are read; everything else is ignored.
| Key | Used for |
|---|---|
title |
The title. Without it: the first # heading, then the file name |
url |
The address shown with a hit. Without it: the file:// address of the file |
updated |
The date shown with a hit. Without it: the file's modification time |
tags |
Labels. A list, or a comma-separated string |
id |
A stable id that survives renames and moves. Without it: the relative path. Two files with the same id fail the call and the message names both |
weight |
A multiplier for ranking, from 0 to 2 (default 1) |
All values are read as text, so no stays no and 2026-10-28 stays a date string. Front matter that is not valid YAML is reported on stderr and the file is indexed without it.
Behavior
- Sections: every heading level (
#to######) starts a section whose heading is the trail of its parents. Text before the first heading is its own section. The first# headingis the title (when the front matter has no title, or the same one) and is not repeated; a different# headingstays a section heading. A#inside a fenced code block is not a heading. - Links:
[text](other.md#part)and[[Other]]or[[Other|text]]become related items when they point at a note in the folder. Wiki links match the file name without case; a name shared by two files links to neither. Links in code are ignored, and the text itself is not changed. - Version: a hash of the whole file and of the notes it links to, so any change to the file, front matter included, and a link that starts to resolve (its target was created) re-indexes the note.
- Bad files: a file that is not UTF-8 text (a BOM is removed), contains binary data or is over
MAX_FILE_BYTESis skipped with a warning on stderr, not an error. changed: notes modified or moved in since the given time, from the later of each file's modification and change time, so edits appear within a minute, also for files copied in with their old dates.- Cost: every call reads the whole folder, because ids and links need all the notes. A skipped file is reported on every call.
Not supported
- Headings underlined with
===or---(setext); only#headings split. A#line inside an HTML comment still counts as a heading. - Glob character classes (
[ab]) and braces ({a,b});*.mdis case sensitive, soNOTE.MDis not found withoutINCLUDE=*.MD. A pattern with a/is anchored atFOLDER, sodrafts/**matches only the top-leveldrafts; use**/drafts/**for any depth. - Reference-style links (
[text][ref]) and brackets inside link text. - File names in a different Unicode form than the link (
Cafétyped with a combining accent).
Test
uv sync # installs this connector too
uv run pytest connectors/markdown # offline, on temporary folders
Metadata
Release files for passageway-connector-markdown 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| passageway_connector_markdown-0.3.0.tar.gz | 12.8 kB | Without provenance | Details for passageway_connector_markdown-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| passageway_connector_markdown-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for passageway_connector_markdown-0.3.0-py3-none-any.whl |
Total release size: 21.0 kB
Release files / passageway_connector_markdown-0.3.0.tar.gz
| Download URL | passageway_connector_markdown-0.3.0.tar.gz |
|---|---|
| Size | 12.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c8d0bbcb6779e6802515553ee79b3268339ec5fef2efc33bd5d7eabe6998d43
|
|
BLAKE2b-256 checksum How to use checksums |
aeb31129e411524e679b8554f56efbfc536fc5ab3b371d60279cc40e5c51a552
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / passageway_connector_markdown-0.3.0-py3-none-any.whl
| Download URL | passageway_connector_markdown-0.3.0-py3-none-any.whl |
|---|---|
| Size | 8.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ad38002fcf28649467b17123d158f47a074b1e902810cd59a379b5c22eaa94c
|
|
BLAKE2b-256 checksum How to use checksums |
dd688cf385fb0d3f0b7377807b739d4eb4456714d7610c2665ff247f74006084
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for passageway-connector-markdown 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.