Skip to content

Convert a typed character reference when its semicolon completes it #299

Description

@Azganoth

Summary

Text typed as a character reference stays literal text. An author who types © gets six characters that save as \©, while the same six characters loaded from a file render as © and save as ©. This completes the gesture in the writing direction: typing the semicolon that finishes a valid reference converts the run to the reference it spells, under the projection #298 already opens.

Without it the gesture only runs one way. A reference can be broken but not made, so an author who removes one cannot put it back except by editing the file outside Leafdown.

The two input paths also disagree. Plain-text paste parses through leafdownCharacterReference with the pasted text as its source, so a pasted © is expected to arrive already preserved while a typed one does not, which is the divergence #238 was opened over reappearing for a different construct. Confirm the paste path before relying on it; it decides whether this issue changes one path or two.

Expected behavior

  • Typing the closing ; of a valid reference converts the run: the document holds the character the reference names, carrying the typed source, and Project a character reference as its source when the caret reaches it #298's projection is open over it. The visible characters do not change and the caret stays where the author left it, as for any commit under an open projection. The run restyling to marker colour is the signal that the conversion happened.
  • The conversion is provisional while the caret stays. Continuing to type follows Project a character reference as its source when the caret reaches it #298's rules, so source that no longer spells one whole reference commits as the literal text it spells: typing x after the converted run returns ©x to literal text and the marker styling drops with it.
  • Editing the projected source to \© commits literal text, which is how an author keeps the six characters after converting them without reaching for Undo.
  • An incomplete or invalid reference stays literal text. &copy, &MadeUpEntity;, and &#; are unchanged by typing, and save with an escape only where a valid reference would otherwise form.
  • A preserved reference is inert to the trigger, on the rule A character reference is decoded and saved as the literal character #262 states for escaping. Typing & and then copy; leaves the file holding ©, which reopens as the literal text the author wrote. Converting there would write © and reopen as ©.
  • The trigger does not fire where a reference cannot form or is not the run's owner: inside inline code, inside an open link or marked-fragment projection, or across a mark boundary, so &co**py;** stays as written.
  • Undo returns the typed source in one step, stepping past the semicolon rather than landing on the literal run the semicolon completed. One Undo onto a state that differs only by marker colour is the silent gesture How a Markdown escape should be represented in the editor #245 blocked Project an escape as its two characters so deleting the backslash converts the run #255 on.
  • Typing and plain-text paste of the same characters reach the same document.

Related context

Done when

  • Typing the closing ; of a valid reference converts the run and leaves Project a character reference as its source when the caret reaches it #298's projection open with the caret unmoved.
  • Continuing to type past a converted reference returns the run to literal text, and editing the projected source to \© commits literal text.
  • An invalid or incomplete reference is unchanged by typing and stays literal text through a save and reopen.
  • Typing copy; after a preserved & leaves the file holding ©.
  • The trigger does not fire inside inline code, inside another open projection, or across a mark boundary.
  • One Undo returns the typed source.
  • Regression coverage asserts the typed path and the pasted path reach the same document.

Notes

Implementation direction

The commit point is the semicolon rather than the caret leaving the run, because no caret-leave trigger can be sound here. A file holding \© opens as literal text © with nothing durable recording the escape, so it is the same document as a freshly typed ©, node for node. Caret-leave would convert the run the file deliberately escaped, which is the hole the session-scoped record closes for links and which references neither have nor should grow. A trigger keyed to the keystroke is provenance by construction.

#255 is the precedent, not #270. #270 closed Not proceeding: the caret-leave commit and its record both stayed, because the narrowed rule cost the Link and Image commands their only conversion path. What carries here is #255's shape, a conversion that completes on the keystroke that causes it and reads as a restyle rather than as moved text.

Every valid reference ends in ;, named, decimal, and hex alike, so one trigger character covers all three forms with no per-form rule.

The conversion adds no second commit clock. The semicolon converts the run and hands it to #298's session, whose exit rule then governs, which is what lets continuing to type revert it with nothing new to keep in step with the serializer.

Out of scope

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

FeatureNew feature or request

Projects

  • Status
    Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions