Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Golf: Text Expressions for easy Byte Count-based Golfing #737

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

radian628
Copy link
Collaborator

Adds in a feature where you can use text expressions/notes to specify the LaTeX of other expressions, enabling easy golfing based on byte count.
image

@radian628
Copy link
Collaborator Author

I probably should add a page to the site (and a corresponding "Learn More" link) for this.

@radian628 radian628 added the enhancement Enhancement to existing features label Sep 30, 2023
@radian628
Copy link
Collaborator Author

Current status: All the functionality has essentially been implemented. Whenever you start a note expression with @codegolf, it will (ignoring leading whitespace) treat the remainder of its text as a LaTeX math expression, and will create an expression below which is auto-synced to it, updating whenever the plaintext LaTeX in the note expression changes. This autosyncing also extends to dragging (the expr drags with the note to keep the two together and the expr itself can't be dragged). There's also measures in place to prevent other expressions from appearing between a note-expr pair (if they do, the expr moves back to right below the note).

Another important note about auto-syncing is that it does not always occur--- if the expression below a note doesn't match its latex (and this isn't just because it's responding to an update), it will treat the expression below as a separate entity and create a new one to sync up. This is done to prevent cases where someone creates a graph with the plugin, hands it off to someone without the plugin who messes with the expressions directly, and then hands it off to a person with the plugin. I don't want their work getting overwritten by the plugin.

@radian628
Copy link
Collaborator Author

Future plans: All I can really see myself doing now to get this feature production-ready is:

  1. Polishing up the CSS so note-expr pairs more resemble single, continuous "units."
  2. Potentially finding a better way of handling dragging (at least, a way that's better than my current strategy of "lol just fix the issue right after they're done dragging")

@radian628
Copy link
Collaborator Author

Bug: I should probably switch from direct state-setting to simulating the paste operation because these both produce different results. E.g. this doesn't work for state-setting but pasting does work
image

@jared-hughes
Copy link
Member

Bugs:

  • Dragging an @codegolf note into a folder doesn't update folderId.
  • Writing a @codegolf in the middle of a folder doesn't keep folderId on the generated expression.
  • Dragging the expression after the @codegolf cancels the drag instead; I'm assuming you're aware of this. It's not a big issue (no need to fix) since users can just drag the @codegolf instead.
  • Pressing the "enter" key while inside an @codegolf note places a new expression between the note and its expression. Same for adding a new expression by hotkey (Ctrl+Alt+X, Ctrl+Alt+O, etc) and by the "+" Add Item menu in the top-left.

Also, an underlying issue of the pasting not working for stuff like floor(x) -- see "Two Pasting Approaches"

Ideas for later PRs:

  • It would be nice to put multiple lines in one @codegolf note. A full hole solution. Split by lines, and paste each line to a separate expression.
  • @textmode notes.

Two Pasting Approaches

There's two ways to paste in expressions that give different results. Seems this plugin is always doing the first one:

  1. with a leading newline, e.g. pasting in (newline then) \{x>3\}. Note that pasting in (newline then) floor(x) doesn't work. (you have to write \floor) . My sum of two squares solution and Aiden's Fill In solution requires this pasting approach.
  2. without a leading newline, e.g. floor(x). Note that pasting \{x>3\} without a leading newline doesn't work. I think this is because it uses MathQuill's paste handler. My Bernard solution and Aiden's Decompose solution both require this pasting approach.

If you paste in several lines, it's treated like there's a leading newline for all of them. People use both paste-approaches, and sometimes mix both paste approaches in the same hole. Aiden's skin solution, which uses leading newline for all the expressions except the first. In my Biohazard solution, I made an ad-hoc temporary meta where I added a byte for a newline whenever it needed approach 1.

From a cursory scan of CGSE, the second approach tends to be more common since it removes the need for backslashes. As far as I know, the first approach is only needed for piecewises \{\}. So different choices of resolution here:

  1. stick with the first approach
  2. use the second approach always
  3. use the second approach unless there's a literal substring \{ (but don't count a \left\{ since Mathquill handles that properly.
  4. add some syntax to differentiate between the two approaches.

Resolution 3 would be best if it seems to work reliably. I prefer Resolution 2 over resolution 1, especially if there's a Mathquill PR to make Mathquill handle \{\} instead of just \left\{\right\}.

@jared-hughes
Copy link
Member

Auto-syncing also stops if an action changes the value of the expression below.

Expressions can be prevented from accidentally being Mathquill-edited by marking them as readonly: true. But sliders and actions can still change their values.

@radian628
Copy link
Collaborator Author

Bugs:

* Dragging an `@codegolf` note into a folder doesn't update folderId.

* Writing a `@codegolf` in the middle of a folder doesn't keep folderId on the generated expression.

Yep, those are bugs, thx for catching them!

* Dragging the expression after the `@codegolf` cancels the drag instead; I'm assuming you're aware of this. It's not a big issue (no need to fix) since users can just drag the `@codegolf` instead.

This was an intentional choice to avoid the two from accidentally being separated. Ideally I'd disable dragging from the very beginning, but I'm not totally sure how to do that yet.

* Pressing the "enter" key while inside an `@codegolf` note places a new expression between the note and its expression. Same for adding a new expression by hotkey (Ctrl+Alt+X, Ctrl+Alt+O, etc) and by the "+" Add Item menu in the top-left.

Also, an underlying issue of the pasting not working for stuff like floor(x) -- see "Two Pasting Approaches"

Ideas for later PRs:

* It would be nice to put multiple lines in one `@codegolf` note. A full hole solution. Split by lines, and paste each line to a separate expression.

Good idea. Given that I need to completely overhaul pasting anyway, I might just implement that in this PR.

* `@textmode` notes.

I'll probably defer this for a later PR but agreed this'd be a good feature.

Two Pasting Approaches

There's two ways to paste in expressions that give different results. Seems this plugin is always doing the first one:

1. with a leading newline, e.g. pasting in (newline then) `\{x>3\}`. Note that pasting in (newline then) `floor(x)` doesn't work. (you have to write `\floor`) . My [sum of two squares solution](https://codegolf.stackexchange.com/a/246833/68261) and Aiden's [Fill In solution](https://codegolf.stackexchange.com/a/243831/68261) requires this pasting approach.

2. without a leading newline, e.g. `floor(x)`. Note that pasting `\{x>3\}` without a leading newline doesn't work. I think this is because it uses MathQuill's paste handler. My [Bernard solution](https://codegolf.stackexchange.com/a/248827/682610) and Aiden's [Decompose solution](https://codegolf.stackexchange.com/a/245413/68261) both require this pasting approach.

If you paste in several lines, it's treated like there's a leading newline for all of them. People use both paste-approaches, and sometimes mix both paste approaches in the same hole. Aiden's skin solution, which uses leading newline for all the expressions except the first. In my Biohazard solution, I made an ad-hoc temporary meta where I added a byte for a newline whenever it needed approach 1.

From a cursory scan of CGSE, the second approach tends to be more common since it removes the need for backslashes. As far as I know, the first approach is only needed for piecewises \{\}. So different choices of resolution here:

1. stick with the first approach

2. use the second approach always

3. use the second approach unless there's a literal substring `\{` (but don't count a `\left\{` since Mathquill handles that properly.

4. add some syntax to differentiate between the two approaches.

Resolution 3 would be best if it seems to work reliably. I prefer Resolution 2 over resolution 1, especially if there's a Mathquill PR to make Mathquill handle \{\} instead of just \left\{\right\}.

Best option imo is to stick with Resolution 4 unless I can find a way to make Resolution 3 reliable. I'll default to second approach and I'll add a @leading-newline "at-code" (for lack of a better term) which switches the line immediately following it to the first approach.

@radian628
Copy link
Collaborator Author

Hmmm, to make it more concise I could probably instead switch to first-approach if there's more than one leading newline.

@radian628
Copy link
Collaborator Author

Honestly, just to keep things simple, what I might do is delete all the golfed expressions and generate them from the ground up immediately afterwards, rather than changing the content in the expressions themselves. This will remove the custom colors and formatting and whatnot, but honestly I think that's an acceptable sacrifice considering how infrequently that's relevant to codegolfing. If I find I need that, I'll probably add it as some kind of syntax extension later.

@jared-hughes
Copy link
Member

You've convinced me to prefer resolution 4, considering the idea for other @sync types. Brackets idea here is to make the separation clear (it can even fuzzy-match inside the brackets, at least to provide suggestions when typo'd).

  • @sync[paste] y=sin(x)\left\{x>3\right\}
  • @sync[paste-with-newline] y=\sin(x)\{x>3\}
  • @sync[latex] y=\operatorname{sin}(x)\left\{x>3\right\}
  • @sync[text-mode] y=sin(x)*{x>3}

Then plain @sync (without brackets) could auto-detect between the four. Auto-detect approaches:

  1. Use text-mode if it parses as text mode. Otherwise, try paste unless there's a \{ (that's not part of a \left\{), when you use paste-with-newline.
  2. Use text-mode if it parses as text mode. Otherwise, use latex.

Backslashes are unused in text mode. Maybe I should make it so latex, paste, and paste-with-newline are all parseable with text mode.

@radian628
Copy link
Collaborator Author

I like your sync syntax proposal! I think I'll go with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement to existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants