feat(editor): ${filename} in the image directory, so a folder can belong to one document (#714) - #716
Merged
Merged
Conversation
added 2 commits
August 25, 2026 04:41
…ong to one document (#714) `imageDirectory` was taken literally, so every document in a folder shared one `img/` and a directory of notes accumulated one flat pile of screenshots with no way to tell which document any of them belonged to. `${filename}` in that setting now expands to the document's name without its extension: `${filename}.assets` next to `notes/trip.md` writes to `notes/trip.assets`. The token is spelled the way Typora and SoloMD spell it, because a user arriving from either types what already worked there. The expansion is a path *component*, so Rust is unchanged: `trip.assets` still goes through `safe_path_component`, which refuses separators, `.`, `..` and absolute paths and keeps the folder inside the document's directory. That guard is also the answer for the stems this does not special-case -- a file named `..md` expands to `.` and Rust says no. A nested template (`./images/${filename}/`) would need that constraint relaxed and is deliberately not part of this. The three call sites that read the setting -- paste, drop, and the path completion that lists the image folder -- go through one function now, and a source assertion keeps the fourth from being written by hand: expanding at two of them and not the completion would offer suggestions out of a folder named after the literal token, which exists nowhere. Substitution is `split`/`join`, not `String.replace`: the replacement is a filename the user chose, and `replace` reads `$&` and `$'` in a replacement as backreferences, so a document named `$&.md` would have put `${filename}.assets` on disk verbatim. Not changed: renaming a document still leaves its assets folder behind under the old name (Typora moves it and rewrites the links), and a failed image write still only reaches the console. Both are their own change. The setting's hint is English-only; the other 25 locales fall back to it, which i18nCoverage.test.ts allows by design. Tests: 982 node, svelte-check clean.
imageUndoKeepsFile.spec.ts evaluates the component's own paste and drop statements over a scope it builds by hand, so a name those statements newly reference has to be added to the scope or it is simply undefined at call time. `resolveImageDirectory` was not, and both handlers threw where they read the image directory — inside the try/catch that exists for a failed disk write, so the throw surfaced as "the drop did not insert an embed" rather than as a ReferenceError. It replaces `DEFAULT_IMAGE_DIRECTORY` in the parameter list rather than joining it: the lifted code no longer names that constant, and a parameter nothing reads is the next person's puzzle.
PathGao
added a commit
that referenced
this pull request
Aug 25, 2026
Four things shipped since 2.7.4 that the file which documents what Markpad can do never heard about. It carries the editing behaviour around each construct, not only the spellings, so each one belongs to a section that already exists. - Lists: `Tab` moved a line by tabSize and left the marker alone. #713 makes it a level change -- the parent's content column, and both numbered lists renumbered -- which is what the file already claimed and now describes accurately. - Quotes: `Enter` continues a block quote (#705), so the section gets the paragraph Lists has had. Including that one keystroke clears an empty quoted line at any depth, which is the way out. - Images: where a pasted or dropped image lands, and `${filename}` in that setting (#716). It expands to a folder name, not a path, and the note says so -- `./images/${filename}/` is not a thing you can write here. - Not-syntax: copying from the preview keeps its formatting (#680), and the split panes can trade sides (#693). Tests: 984 pass.
alecdotdev
pushed a commit
that referenced
this pull request
Aug 25, 2026
…own again (#719) * chore: bump version to 2.7.5 * docs(syntax): bring the reference up to 2.7.5, in both languages Four things shipped since 2.7.4 that the file which documents what Markpad can do never heard about. It carries the editing behaviour around each construct, not only the spellings, so each one belongs to a section that already exists. - Lists: `Tab` moved a line by tabSize and left the marker alone. #713 makes it a level change -- the parent's content column, and both numbered lists renumbered -- which is what the file already claimed and now describes accurately. - Quotes: `Enter` continues a block quote (#705), so the section gets the paragraph Lists has had. Including that one keystroke clears an empty quoted line at any depth, which is the way out. - Images: where a pasted or dropped image lands, and `${filename}` in that setting (#716). It expands to a folder name, not a path, and the note says so -- `./images/${filename}/` is not a thing you can write here. - Not-syntax: copying from the preview keeps its formatting (#680), and the split panes can trade sides (#693). Tests: 984 pass. * docs(release): the download table's two warnings describe 2.7.5, not 2.7.4 The table is composed in `build.yml` and printed on every release page, so both notes ship with whatever master holds when the workflow is dispatched. Both are about to be wrong. macOS: the last paragraph told users the app grants file access per prompt and that self-signing in Keychain Access is the way out, redone after every update. #707 is what that paragraph asks for, so it would print the workaround on the first release that no longer needs it. Replaced with what is now true, worded so it stays true for 2.7.6: the grant survives an update, and only a user coming from a release older than 2.7.5 is asked once more, because the signature changes the identity the old grants belonged to. The Gatekeeper paragraph above it is untouched -- signing is not notarization, and the first-launch dialog is unaffected. Windows: the "false positive Trojan" half is the stale one -- VirusTotal no longer flags the portable `.exe`, which is what #334 and #466 were. The SmartScreen half is not: it fires on an unsigned binary regardless of what any scanner says, and stays true until an Authenticode certificate exists (#562). Dropping the whole note would leave the release page silent about a dialog every Windows user still meets. So the antivirus claim goes and the unrecognized-app one stays, in one shorter sentence. Tests: 984 pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second half of #714. The session-persistence half is a separate conversation and is not touched here.
imageDirectoryis read literally, so every document in a folder shares oneimg/. A directory of notes accumulates one flat pile of screenshots with nothing saying which document any of them belongs to, and renaming or moving a document takes none of its images with it.What changed
${filename}in that setting now expands to the document's name without its extension.${filename}.assetsnext tonotes/trip.mdwrites tonotes/trip.assets; each document gets its own folder. A setting without the token is still the literal folder name it has always been, and an empty setting still meansimg, so nothing changes for anyone who does not type the token.Three call sites read the setting — paste (
save_image), drop (copy_file_to_img), and the path completion that lists the image folder for and one source assertion that no call site resolves the setting inline.