LaTeX fraction snippets in VSCode

After you install HyperSnips, use its command HyperSnips: Open snippets directory to open the directory where you will put your snippets.

Snippets in all.hsnips will be available in all language files. You can also put your snippets into something like latex.hsnips or Latex.hsnips in the same directory and both versions work for me.


Modifying the code from Castel’s guide put this into your chosen <language>.hsnips file:

snippet // "Fraction simple" A
\frac{$1}{$2}$0
endsnippet

snippet `((\d+)|(\d*)(\\)?([A-Za-z]+)((\^|_)(\{\d+\}|\d))*)/` "Fraction no ()" A
\frac{``rv = m[1]``}{$1}$0
endsnippet

Note that interpolated code goes into double backticks ““” and the value from that code must be assigned to rv (return value). Whatever is assigned to rv will appear in the snippet output. Note also there are additional tabstops $1, $2 and $0 in the above snippets – there values can be accessed by the interpolated code within the t array but you don’t need that here.

And then here is the final snippet that works for the harder case of embedded parentheses within your “prefix” like (1 + (2 + 3))/. I think of (1 + (2 + 3))/ just like a traditional vscode snippet prefix EXCEPT that you can use regex expressions as the prefix!! Regex prefixes/triggers must within backticks.

snippet `^.*\)/` "Fraction with ()" A
``
    let str = m[0];
    str = str.slice(0, -1);
    let lastIndex = str.length - 1;

    let depth = 0;
    let i = str.length - 1;

    while (true) {
        if (str[i] == ')') depth += 1;
        if (str[i] == '(') depth -= 1;
        if (depth == 0) break;
        i -= 1;
    }

    let results = str.slice(0, i) + "\\frac{" + str.slice(i+1, -1) + "}";
    results += "{$1}$0";
    rv = results;
    ``
endsnippet

Here ^.*\)/ is the prefix/trigger. The extension looks at all your code as you type for that pattern which is basically at least one ) before a / and then match everything before those to the previous word boundary. And then that match info is available within the matched code as m[0]. You can have capture groups with your prefix/trigger and access them in m[1], etc. but that isn’t needed here.

As you can see, the code to be interpolated must be javascript for this extension to work.

The location of that first set of backticks is important! Here

snippet `^.*\)/` "Fraction with ()" A
``
   <other code indented here>
   ``  <indented or flush left, didn't seem to matter in my testing>
endsnippet

the indented code is easier to read IMO, but the output will also be indented unless that first set of backticks is not indented (unless of course you want the output indented). I don’t that if that is a “quirk” or as planned. But the position of that first set of backticks seems to determine the location of the output.

The body of this final snippet (again code from the guide you linked to, but translated to javascript by me from his python code) just figures out how far to backtrack (character by character) to get an even number of parentheses. Any preceding part of the input prefix/trigger goes before the \frac part.

After making changes to this file, always run the command HyperSnips: Reload Snippets to ensure they are ready for testing immediately.

Demo in action:

HyperSnips latex fraction demo

Leave a Comment