Documents

How Jotura stores PDFs, Word files and spreadsheets, mirrors them into searchable markdown, and keeps that mirror current as the originals change.

Documents

A Jotura vault is a folder of files, and not all of them are markdown notes. You can keep PDFs, Word documents, spreadsheets, presentations, images, code, and configuration files alongside your notes. Jotura treats each kind differently, and the difference matters when you want to search them.

For a document that Jotura can read text out of, such as a PDF or a Word file, the app writes a second file next to it. That second file is an ordinary markdown note holding the extracted text, and this page calls it the mirror. The original file stays untouched and opens in whatever application you normally use. The mirror is what full text search reads, so a phrase buried on page 40 of a contract turns up in the same search box as your notes.

What counts as a document

Only file types on the converter’s allowlist are sent for conversion. Everything else is stored as it is, because converting it would produce metadata noise rather than content. The old binary Office formats doc and ppt are stored and synced but never converted, because the bundled converter has no reader for them.

File type Extensions What Jotura does
Convertible document pdf, docx, pptx, xls, xlsx, epub, msg, odt, ods, odp, rtf Stores the file and generates a markdown mirror beside it. OpenDocument files keep their headings, lists and tables, a spreadsheet becomes one table per sheet, and a presentation becomes one section per slide with its speaker notes. An rtf mirror holds the plain text without formatting. See the note on msg below
Legacy Office binary doc, ppt Shown in the file tree and synced. Never converted, because the bundled converter has no reader for these formats. The next sweep deletes the failure notes earlier versions wrote for them, unless you edited one
Markdown note md, markdown Opens in the editor. Already searchable, so no mirror
Plain text and code txt, rst, org, tex, json, yaml, yml, toml, xml, csv, tsv, css, scss, sass, js, mjs, ts, tsx, jsx, py, rb, rs, go, java, kt, swift, c, cpp, h, hpp, sh, bash, zsh, fish, ini, conf, env, sql, log, ps1, bat Opens in a text editor tab. Indexed directly, so no mirror
Obsidian canvas and Bases canvas, base Opens as plain JSON text. There is no canvas editor and no Bases view
HTML page html, htm Opens in a sandboxed preview tab with a source toggle. Indexed directly, so no mirror
Image png, jpg, jpeg, gif, webp, svg, bmp, ico, heic, heif, avif, tiff, tif Stored and displayed in notes. Clicking one in the file tree opens it in a media tab. Never converted
Audio and video mp3, m4a, wav, ogg, flac, mp4, mov, webm, mkv Shown in the file tree and synced, subject to the 16 MB upload cap. A video opens in a media tab that plays it. Never converted, and there is no audio player
Comic book archive cbz, cbr Shown in the file tree and synced as a book, up to 95 MB. Never converted. The Android app opens cbz in its book reader
Anything else for example zip, exe, files with no extension Left alone on disk. Jotura does not show these files in the file tree, does not index them, and does not upload them

The extension test is case insensitive, so REPORT.PDF is treated exactly like report.pdf.

Two exclusions apply before the extension is even checked. Microsoft Office owner files, the transient ~$name.docx files Word leaves beside an open document, are ignored rather than converted. So is anything under a folder or file name that starts with a dot. The file tree, the search index and the conversion sweep all skip dot-prefixed entries, so a PDF stored in .archive/ or in Obsidian’s .trash/ is invisible to Jotura and never gets a mirror.

Automatic conversion is a per-vault setting

Whether documents are converted without you asking is decided per vault by Convert documents automatically, in the Document conversion group in Settings and stored in <vault>/Jotura/settings.json, so it applies on every device. It is on by default for an ordinary vault, so a sweep runs on vault open and every import and watched change queues a conversion.

A vault that contains an .obsidian/ folder is treated differently, because writing a .md sibling next to every PDF in a vault you also use elsewhere is not a reasonable first move. The first time Jotura opens a vault it has never opened before, the setting is switched off and no notes are written. The decline is kept on that device in .jotura/vault-settings.json, and reaches Jotura/settings.json with the first vault setting you change. A vault Jotura has already opened is left as it is, so an upgrade never changes how a vault you are already using behaves. A vault the jotura CLI has already written to counts as opened, because the CLI’s write lock creates the .jotura folder. If the vault holds convertible documents, a notice appears. It reads This vault has <n> documents Jotura can convert into searchable notes. Nothing has been written. Converting adds a markdown copy beside each document; you can change this later in Settings > Advanced > Document conversion. and offers two buttons. Convert now turns the setting on and runs the sweep once. Not now dismisses the notice and leaves the setting off, and you can flip it later under Settings, Advanced, Document conversion.

With the setting off, the manual actions still work: Convert pending, Reconvert stale, Reconvert all, and clicking a document row all convert on request. jotura import converts as part of the command regardless of this setting, unless you pass --no-convert.

Outlook messages are a special case. The msg extension is convertible, but it is not one of the file types Jotura enumerates in the vault. A .msg file is missing from the file tree, from sweeps and from jotura ls-documents, and sync never uploads it. It is converted only when you import it explicitly through the app or through jotura import, and after that its mirror behaves like any other note while the .msg file itself stays hidden from the app.

HTML, CSV and TSV files were convertible in older builds and are not any more. They are first class text now, indexed from their own contents. A leftover machine generated mirror for one of them is deleted during a sweep, but only when the original file is still on disk and the mirror still carries its generated provenance. A mirror you have edited, or one whose original is gone, survives and needs deleting by hand.

Importing a document

Every route below copies the file into the vault, so the original on your desktop or in your downloads folder is untouched. If the destination already holds a file with that name, the import adds a numeric suffix before the extension, so a second report.pdf lands as report-1.pdf.

Route Where the file lands Extra effect
Drag files from the operating system onto a folder row in the file tree That folder Conversion starts immediately while automatic conversion is on
Drag files onto the file tree background Your default document folder Conversion starts immediately while automatic conversion is on
Drag files into the editor Your default document folder Inserts a markdown link, [name](path), at the drop point
Paste files into the editor Your default document folder Inserts a markdown link at the cursor
Copy the file into the vault folder with Finder, Explorer or a terminal Wherever you put it The file watcher notices it and queues conversion while automatic conversion is on
jotura import attachments by default, or the folder you name Conversion runs as part of the command, whatever the vault setting

Documents dropped or pasted into the editor keep their original file name. On a multiple file drop into the editor, each link goes on its own line. Links are written relative to the note, and images are handled differently from documents. See The editor.

You cannot import into a share someone else has given you view-only access to. The app refuses the write, and jotura import exits with code 15, ReadOnlyShare. See Sync and sharing and Exit codes and JSON output.

The default document folder is attachments. Change it under Settings, Advanced, Files and folders. A value that is blank or that contains .. falls back to attachments.

Setting Effect Default
Default document folder Where dropped or pasted documents are stored, relative to the vault root attachments

The full list of settings is on the Settings reference page.

The searchable markdown mirror

The mirror takes the document’s full file name and appends .md. That keeps report.pdf and report.docx from colliding.

Original Mirror
attachments/report.pdf attachments/report.pdf.md
attachments/report.docx attachments/report.docx.md
Projects/2026/budget.xlsx Projects/2026/budget.xlsx.md

The mirror is an ordinary note. It sits in the same folder as the document, it is indexed, it can be linked to, it appears in search results, and it syncs like any other note. The file tree hides the mirror’s own row so you do not see the same name twice, and clicking the document row opens the mirror. If the mirror does not exist yet, clicking the document row converts it first and announces the progress, then opens the result.

Jotura has no built in PDF, Word or spreadsheet viewer. Clicking a document opens its text mirror. To see the file with its original layout, use Open original externally, described below.

What is in the mirror

Every generated mirror starts with a YAML frontmatter block recording where it came from. The editor hides frontmatter in the visual view, so you see only the converted text. Toggle to source mode to see the whole file, including the block. The shortcut is Cmd/Ctrl+Shift+E, which only fires while the editor has focus, and the same toggle sits in the editor header and the command palette. See Keyboard shortcuts.

Field Meaning
jotura_converted_doc Marks the note as machine generated. Older mirrors use jotura_md_store
source_path The vault relative path of the document this came from
source_content_hash Hash of the document’s bytes at conversion time, used to detect a changed source
converted_body_hash Hash of the generated body, used to detect that you have since edited the note. Mirrors old enough to lack this field are always treated as unedited
markitdown_version The converter version that produced this text, or null
converted_at The conversion timestamp in UTC
conversion_ok Whether the conversion succeeded

Finding documents by content

Because the mirror is a normal note, every search surface already covers it. Search for a phrase from a contract and the hit comes back as contract.pdf.md, with the surrounding text as the snippet. Opening the hit opens the mirror.

Surface Covers documents Notes
Sidebar search pane Yes, through the mirror Keyword mode always; Semantic and Smart once semantic search is enabled
Search page, Keyword mode Yes, through the mirror Cmd/Ctrl+Shift+F opens it
Search page, Semantic and Smart modes Yes, through the mirror Requires semantic search to be enabled first
Quick open (Cmd/Ctrl+P) Matches file names, not contents Matches the document and the mirror by name
jotura search-documents Yes Returns the original document paths

Full details of the three search modes are on the Search page. Files above 25 MB are skipped by the full text indexer, so a very large converted document may not be searchable even though its mirror exists.

Editing originals in their native applications

Jotura never edits a PDF or a spreadsheet itself. Right click the document in the file tree and choose Open original externally, and the operating system opens it in whatever application owns that file type. For HTML files the same menu item reads Open in browser instead.

Context menu item Shown for Effect
Open original externally Documents and plain text files Opens the file with the operating system default application
Open in browser html and htm files Opens the file with the operating system default application
Reveal in File Explorer, Reveal in Finder, or Show in folder Every row Shows the file in the operating system file manager. The wording follows your platform
Copy path Every row except the vault root Copies the vault relative path

When you save the document in that other application, the file watcher sees the change and queues a fresh conversion for that one file. The queue waits for one second of quiet before it runs, so a burst of saves collapses into a single conversion. This watcher route does not check whether the mirror is stale. It reconverts the file unconditionally, though it still skips a mirror you have edited.

The watcher only reacts to files being created or modified. A document renamed outside the app produces a rename event, which is not queued, so the renamed file gets its mirror from the next vault open or from a manual action in Settings.

While conversions run, the status bar at the bottom of the sidebar shows the single highest priority background job, formatted Converting {done}/{total} · {eta} left. Converting outranks embedding, indexing and syncing, and any other active jobs collapse into a +{n} badge with a tooltip.

Documents that arrive while Jotura is closed are handled on the next vault open. The app looks for documents whose mirror is missing or out of date and converts them in the background. Both the watcher route and the vault-open sweep are gated on Convert documents automatically, described above. With it off, a changed document waits for a manual action.

Editing the generated note

You can edit a mirror like any other note, and Jotura will not overwrite your edits. The protection comes from a check Jotura makes on every read: it compares a hash of the current body against the converted_body_hash recorded in the frontmatter. A mirror whose body no longer matches is skipped by every sweep and by Reconvert all, for as long as your edits are on disk.

The same protection applies when a note you wrote happens to already occupy the mirror’s path, because that note carries no conversion marker at all.

To get the machine generated text back, delete or rename your version and run a conversion again, which writes a fresh mirror. Restoring the body to exactly the generated text would also lift the protection, but in practice deleting the file is the reliable route.

Two consequences are worth knowing. Clicking a document whose mirror is protected announces that it was not converted because its note is user owned. And Settings cannot tell you a document is protected: the conversion status row counts only converted, failed and pending documents, and a protected one falls into none of the three. jotura doctor prints a total alongside those counts, so a total larger than the three added together is the only visible hint.

Regeneration and staleness

A sweep looks at every eligible document in the vault, decides whether its mirror is out of date, and converts the ones that are. Never converted documents are always handled before retries, so a backlog of failures cannot starve a document that has never been read at all.

Reason What it means Order
Missing The document has no mirror yet Converted first
SourceChanged The document’s bytes no longer match the hash in the mirror Second
ConverterUpgraded The local converter is a newer version than the one recorded in the mirror Third
PreviousFailure The last conversion failed and is eligible for a retry Last

Two rules keep sweeps from spinning. A failed mirror is only retried when the converter is present, conversion is currently permitted, and either the mirror records no converter version or the local converter is strictly newer than the recorded one. A conversion blocked by a missing sandbox is never retried automatically, because it would fail identically every time.

The converter version recorded in a mirror also names the version of Jotura’s own reader layer, as in markitdown-sidecar 2 (markitdown 0.1.8). When that layer gains a reader for a format, mirrors of that format made by an older layer count as ConverterUpgraded or PreviousFailure once and are converted again. This is how odt, ods, odp and rtf files that earlier versions left as failure notes or raw markup get a real mirror. A device running the older layer leaves the newer mirrors alone.

Sweeps run automatically on vault open while Convert documents automatically is on for the vault. You can also run one by hand from Settings, Advanced, Document conversion, and the manual actions work whatever the setting says.

Action What it does
Converter Status row reading Checking…, Converter ready (markitdown <version>), or Converter not available. The version here is the one stamped into markitdown_version
Conversion status Reads N converted · N failed · N pending
Reconvert stale Runs a sweep over every out of date document, including ones that have never been converted, with a progress bar
Reconvert all Re-runs conversion for every document, protected mirrors excepted. Confirms first, because it is heavy for large vaults
Convert pending Runs the same sweep as Reconvert stale, reporting a count rather than a progress bar
Show N failed Lists the failing document paths. Appears only when at least one document has failed
Retry failed conversions Sits inside that list. Re-runs the failed documents now, bypassing the automatic backoff

Reconvert stale and Convert pending are worth reading twice, because their labels suggest different scopes. They compute an identical target list and differ only in how progress is reported.

Everything from Conversion status downwards is hidden when the converter binary is missing, and replaced by a row explaining that documents still import but stay unsearchable. A vault with no documents at all shows a single row saying so.

Vaults created by older versions kept their mirrors in a hidden .md_store folder. At the start of a sweep, Jotura moves those into the sibling layout on its own and deletes orphans whose document is gone.

The converter and its sandbox

Conversion is done by a converter binary that ships inside the Jotura installer. It runs as a separate short lived process, isolated by the operating system’s sandbox, and its output is written into the mirror.

Platform Sandbox used Network denied
macOS sandbox-exec Yes
Linux bwrap (bubblewrap), when it is on your PATH Yes
Windows A restricted token at Low integrity plus a Job Object, falling back to Medium integrity when the converter cannot run at Low No

The Windows sandbox blocks the converter from reading anything protected by your own user or group permissions, which covers your profile, your registry hive and the vault itself. It does not block network access, and it does not block locations readable by every account on the machine. jotura doctor says as much in its own output, reporting network NOT denied on Windows.

Sandboxing is on by default and conversion fails closed. Jotura treats the sandbox as unusable in two cases: when no sandbox is available on the system at all, and when a sandbox is present but fails a health check. The health check runs the real converter under the profile once per converter path, which catches a profile that lets the converter start and then breaks it mid run. In either case Jotura skips the conversion rather than parsing an untrusted file with your full account privileges, and writes a mirror explaining why.

Setting Effect Default
Allow unsandboxed conversion Convert documents without operating system sandboxing when no sandbox is available. Only enable it if you trust every document you import Off

Each conversion is bounded on every axis. Any run that trips a bound is terminated together with every process it started.

Bound Value
Wall clock timeout 180 seconds
Converted output kept Up to 32 MB
Diagnostic output kept Up to 1 MB
Processor time and file size Limited by the operating system, through resource limits on Unix and a Job Object on Windows

When a conversion does not succeed

Jotura still writes the mirror, with conversion_ok: false and a short quoted explanation in place of the text, so the document is visible in the vault rather than silently missing. There are three wordings.

Situation What the mirror says
The converter is not installed The document could not be indexed yet and will be converted automatically once the converter is installed
The sandbox is unusable and unsandboxed conversion is off The document was not converted because no sandbox is available to isolate the converter. No automatic retry is promised, because there would not be one. The Reason line says whether no sandbox was found or the health check failed
Any other failure, such as a corrupt or password protected file Conversion failed and will be retried automatically, with the reason quoted

Settings shows an Unavailable badge on the Document conversion group when the converter binary is missing, and the group explains that documents still import but stay unsearchable until it is present. Reinstalling Jotura restores it. Failures are usually corrupt or password protected files, so Retry failed conversions is the right first move only after you have checked the file opens elsewhere.

Advanced environment variables

These are escape hatches for unusual setups.

Variable Effect
JOTURA_MARKITDOWN_SIDECAR Use the converter at this path instead of the bundled one. An empty value, or a path that does not exist, silently forces the no converter path rather than raising an error
JOTURA_ALLOW_UNSANDBOXED_CONVERSION Consent to unsandboxed conversion, the same as the Settings switch
JOTURA_DISABLE_SANDBOX Turn the sandbox off entirely and convert anyway. Setting it also grants unsandboxed consent, so conversion proceeds with no isolation at all. jotura doctor reports it as a warning

Plain text and code files

Jotura stores, opens, edits, indexes and syncs a .py file, a .csv export or a .yaml config with the same machinery it uses for your notes. None of them needs a mirror, because their contents are already text.

  • Clicking one opens a CodeMirror tab with syntax highlighting picked from the file name, line numbers, bracket matching, and undo and redo. There is no find bar inside the pane.
  • Edits autosave one second after you stop typing, exactly like the markdown editor. There is no save shortcut.
  • Changes made outside the app merge in silently rather than prompting.
  • HTML files open in their own tab, rendered inside a fully sandboxed frame with no scripts, with a toggle to read the source.
  • Every row in the file tree carries a small type badge, for example PDF, W for Word, X for spreadsheets, P for presentations, TS, PY, RS, {} for JSON and TXT.

One inconsistency is worth naming. The search index and sync both treat .mdc as a text file, but the app’s file tree does not recognize that extension. Clicking such a row opens it in an external application instead of a tab.

Storage, sync and size limits

Documents live in the vault as ordinary files, so every other tool on your machine can see them, with no hidden store or proprietary container in the way. When cloud sync is switched on, documents and their mirrors are encrypted on your device before upload like everything else, and sync is the one paid part of Jotura, priced on the pricing page.

Limit Value Effect
Sync upload cap 95 MB for pdf, epub, cbz and cbr files, 16 MB for every other file Larger files stay local. The pending upload is dropped rather than retried forever
Full text index cap 25 MB per file Larger files are skipped by the indexer and will not appear in content search
Synced file types Text and document extensions, images, comic archives, and audio and video Archives, executables, .msg files and files with no extension are stored locally but never uploaded. Audio and video sync, but most recordings exceed the 16 MB cap and stay local

More detail on what is encrypted and when is on the Sync and sharing page and the security page.

Documents from the command line

The jotura command line tool shipped with the app covers the same pipeline, which is what lets scripts import and read documents without the app being open. Full reference: Documents from the CLI.

Import a file into the default attachments folder and convert it:

jotura import ~/Downloads/contract.pdf

Import to an exact path, replacing anything already there:

jotura import ~/Downloads/contract.pdf --as Legal/2026/contract.pdf --force

Store a file without generating a mirror:

jotura import ~/Downloads/scan.pdf --no-convert

Read the bytes from standard input, which requires an explicit target path:

cat ~/Downloads/scan.pdf | jotura import - --as attachments/scan.pdf

Regenerate only the mirrors that are out of date:

jotura regenerate-md-store --stale-only

Regenerate one named document:

jotura regenerate-md-store attachments/report.pdf

Search documents and get their original paths back:

jotura search-documents "termination clause" --limit 10 --json

List every document with its conversion state:

jotura ls-documents --folder attachments --json
Command Flags and rules
jotura import <FILE> --folder, --as, --no-convert, --force. --folder is ignored when --as is set. --force only means anything with --as, because the folder route already de-duplicates by suffixing. With --as and no --force, an existing target exits 9. Use - for the file to read bytes from standard input, which then requires --as
jotura regenerate-md-store [PATHS]... --all, --stale-only. One of paths, --all or --stale-only is required, and passing none of them exits 9. Positional paths are silently ignored, with no warning, whenever --all or --stale-only is also given
jotura search-documents <QUERY> --limit, default 20
jotura ls-documents --folder

The --json flag is not uniform across these four commands. import and regenerate-md-store always emit JSON, so the flag does nothing on them and the examples above print JSON with or without it. search-documents and ls-documents print tab separated text unless you pass --json. See Exit codes and JSON output.

jotura doctor reports the converter version, the sandbox in use, and the converted, failed, pending and total counts, and points at jotura regenerate-md-store --stale-only when anything is failing. See Watching and diagnostics.

Limitations worth knowing

  • Renaming or moving a document in the app or with the CLI carries its mirror along. Deleting a document does not delete its mirror: the mirror is an ordinary note, so it stays behind and becomes visible in the tree. Delete it yourself.
  • Renaming a document outside the app does not trigger a conversion. The new name waits for the next vault open or a manual sweep.
  • There is no in-app viewer for PDFs, Word files, spreadsheets or presentations. You get the extracted text in a note, and the real file opens in another application.
  • doc and ppt files get no mirror. Save them as docx or pptx to make them searchable.
  • OpenDocument and rtf mirrors carry text and structure only. Bold, italics, colours and images are dropped, and a spreadsheet mirror holds cell values rather than formulas.
  • A password protected OpenDocument file converts to a failure note that says so.
  • Conversion quality is whatever the converter can extract. Complex layouts, scanned pages and password protected files may produce little or nothing.
  • A mirror you have edited never updates again, even when the document changes, until you remove your edited version.
  • Nothing under a dot-prefixed folder is converted, indexed or synced.
  • Very large documents can be stored locally but excluded from both sync and search by the caps above.

If a document is not turning up in search, open Settings, Advanced, Document conversion and check whether it is pending or failed. A document that is missing from all three counts has a protected mirror. Troubleshooting covers what to do next.