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

[FEATURE] New snippet option: "quote-level-aware snippets" #229

Open
RyotaUshio opened this issue Nov 28, 2023 · 9 comments
Open

[FEATURE] New snippet option: "quote-level-aware snippets" #229

RyotaUshio opened this issue Nov 28, 2023 · 9 comments
Labels
enhancement New feature or request

Comments

@RyotaUshio
Copy link
Contributor

RyotaUshio commented Nov 28, 2023

Description of the Problem

The preset snippet dm is very useful, but it doesn't work perfectly when triggered inside a callout or a blockquote, since it doesn't take the quote level (number of ">"s) into consideration. For example:

Screen.Recording.2023-11-29.at.1.46.07.mov

Description of the Solution

In a plugin of mine, I implemented a command like a "callout-compatible dm". Here is the code:
https://github.com/RyotaUshio/obsidian-math-booster/blob/master/src/utils/plugin.ts#L80

So it would be great if Latex Suite could execute it via dm, which would be much easier than finding the command from the command palette or pressing a hotkey for it.

I'm not sure this kind of thing is compatible with the snippet system that Latex Suite employs.

Thank you!

@RyotaUshio RyotaUshio added the enhancement New feature or request label Nov 28, 2023
@RyotaUshio
Copy link
Contributor Author

RyotaUshio commented Nov 29, 2023

I think the same applies to environment snippets like align as well.

    // Environments
    { trigger: "pmat", replacement: "\\begin{pmatrix}\n$0\n\\end{pmatrix}", options: "mA" },
    { trigger: "bmat", replacement: "\\begin{bmatrix}\n$0\n\\end{bmatrix}", options: "mA" },
    { trigger: "Bmat", replacement: "\\begin{Bmatrix}\n$0\n\\end{Bmatrix}", options: "mA" },
    { trigger: "vmat", replacement: "\\begin{vmatrix}\n$0\n\\end{vmatrix}", options: "mA" },
    { trigger: "Vmat", replacement: "\\begin{Vmatrix}\n$0\n\\end{Vmatrix}", options: "mA" },
    { trigger: "case", replacement: "\\begin{cases}\n$0\n\\end{cases}", options: "mA" },
    { trigger: "align", replacement: "\\begin{align}\n$0\n\\end{align}", options: "mA" },
    { trigger: "array", replacement: "\\begin{array}\n$0\n\\end{array}", options: "mA" },
    { trigger: "matrix", replacement: "\\begin{matrix}\n$0\n\\end{matrix}", options: "mA" },

So it would be great if there were a new snippet option like >: quote-level-aware snippets.

@RyotaUshio RyotaUshio changed the title [FEATURE] Make dm compatible with callouts & blockquotes [FEATURE] New snippet option: "quote-level-aware snippets" Nov 29, 2023
@RyotaUshio
Copy link
Contributor Author

RyotaUshio commented Nov 29, 2023

So let me rephrase my proposal: introducing "quote-level-aware snippets".

A quote-level-aware snippet replaces all \ns in replacement with \n + an appropriate number of >s, depending on the quote level of the current line that the cursor is placed on.

Alternatively, it might make sense to make it the default behavior when replacement contains \ns.

@artisticat1
Copy link
Owner

I agree this would be good to have. (It should also be applied to the matrix shortcut that converts Enter to \\ \n.)

It'd probably require parsing the syntaxTree from CodeMirror to determine whether the cursor lies inside a blockquote, and setting Mode appropriately.

@JxJxxJxJ
Copy link

JxJxxJxJ commented Feb 3, 2024

Seems that using the following snippets can help getting around the most basic usecase at least:

    {trigger: "dm", replacement: "$$\n$0\n$$", options: "tAw"},
    {trigger: "> dm", replacement: "> $$\n> $0\n> $$", options: "tAw"},
  • First usecase: dm expands to
$$ 
<cursor>
$$
  • Second usecase:
> [!Callout]
> dm

expands to

> [!Callout]
> $$
> <cursor>
> $$

And afortunately, this does not break things even after doing > dm on a blank line

  • Third usecase: > dm expands to
> $$
> <cursor>
> $$

Hopefully this is enough of a solution for anybody that also encountered this problem.

@RyotaUshio
Copy link
Contributor Author

RyotaUshio commented Feb 3, 2024

@JxJxxJxJ I must say you are a legend! This works like a charm.

Just to improve your snippet a little bit, here's my version:

{trigger: /\n> (.*)dm/, replacement: "\n> [[0]]$$\n> $0\n> $$", options: "tAw"},

This way we can

  • avoid this snippet to be triggered when > appears inside a line rather than the beginning of a line
  • and also make it work when there are some other characters between > and dm.

Update: This version also handles quote levels deeper than one.

    {trigger: /\n((> )+)(.*)dm/, replacement: "\n[[0]][[2]]$$\n[[0]]$0\n[[0]]$$", options: "tAw"},

@JxJxxJxJ
Copy link

JxJxxJxJ commented Feb 3, 2024

Very happy it works for you! :) May I ask you how are you making your callouts? I've just noticed that when doing multiple levels I run into some issues... I was using something like

    {trigger: ";prob", replacement: "> [!Problem] \n> $0 ", options: "tA"},
    {trigger: ";ex", replacement: "> [!Example] \n> $0 ", options: "tA"},

for many of my snippets but it does not work very well. I wish there was an easier way to share snippets haha

@RyotaUshio
Copy link
Contributor Author

@JxJxxJxJ How about this?

{trigger: /\n((> )*);prob/, replacement: "\n[[0]]> [!Problem]\n[[0]]> $0\n[[0]]> ", options: "tAw"},

I guess it will work even for nested callouts.

@JxJxxJxJ
Copy link

Sorry for the late response, works just fine thank you very much

@makamto
Copy link

makamto commented Jan 30, 2025

@RyotaUshio any idea on how to implement the environment also?

For anyone that come to this issue, I found some basic workaround for environment based on previous smart people's work.

    { trigger: "A:", replacement: "> [!axiom|$0] $1\n> $2 \n$3", options: "tA" },
    { trigger: "CJ:", replacement: "> [!conjecture|$0] $1\n> $2 \n$3", options: "tA" },
    { trigger: "C:", replacement: "> [!corollary|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "D:", replacement: "> [!definition|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "E:", replacement: "> [!example|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "H:", replacement: "> [!hypothesis|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "L:", replacement: "> [!lemma|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "P:", replacement: "> [!proposition|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "R:", replacement: "> [!remark|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "T:", replacement: "> [!theorem|$0] $1 \n> $2 \n$3", options: "tA" },
    { trigger: "PF:", replacement: "`\\begin{proof}[Proof of $0]`\n$1\n`\\end{proof}`", options: "tA" },

    // Environment in callout
    { trigger: "> cases", replacement: "> \\begin{cases}\n> $0\n> \\end{cases}", options: "mA" },
    { trigger: "> align", replacement: "> \\begin{align}\n> $0\n> \\end{align}", options: "mA" },
    { trigger: "> array", replacement: "> \\begin{array}{l}\n> $0\n> \\end{array}", options: "mA" },
    { trigger: "> gather", replacement: "> \\begin{gathered}\n> $0\n> \\end{gathered}", options: "mA" },

    // Create n*m matrix 
    {
        trigger: /(> )?(\d)(\d)(p|b|b|v|v)\4/,
        replacement: (match) => {
            const hasarrow = match[1]; // this will capture "> " if present
            const n = match[2];
            const m = match[3];
            const bracket = match[4];

            let arr = [];
            let bracketstr; // different bracket string means different latex environment
            let output;

            for (let j = 0; j < n; j++) {
                arr[j] = [];
                for (let i = 0; i < m; i++) {
                    arr[j][i] = `\${${j * m + i}:0}`;
                }
            }

            switch (bracket) {
                case 'p': bracketstr = "pmatrix"; break;
                case 'b': bracketstr = "bmatrix"; break;
                case 'b': bracketstr = "bmatrix"; break;
                case 'v': bracketstr = "vmatrix"; break;
                case 'v': bracketstr = "vmatrix"; break;
                default: bracketstr = "matrix"; break;
            }

            output = arr.map(el => el.join("  &  ")).join("   \\\\ \n");
            output = `\\begin{${bracketstr}}\n${output}  \n\\end{${bracketstr}}`;

            // if "> " was captured, prefix each line of output with "> "
            if (hasarrow) {
                output = output.split('\n').map(line => `> ${line}`).join('\n');
            }

            return output;
        },
        options: "rmA"
    },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants