1

It seems possible to have ultisnips produce a dynamically sized array as specified here:

https://github.com/SirVer/ultisnips/blob/master/doc/examples/tabstop-generation/README.md

The array environment created however comes prespecified with left alignment on each of the columns as indicated in the example here. The snippet code that produces this is:

post_jump "create_matrix_placeholders(snip)"
snippet 'arr(\d+),(\d+)' "LaTeX array" br
\begin{array}{`!p
orient = ""
for _ in range(0, int(match.group(1))): orient += "l"
snip.rv = orient`}
`!p
snip.rv = create_matrix(match.group(1), match.group(2), "&", "\t", "\\\\\\\\\n")
`$0
\end{array}
endsnippet

Is it possible to modify this snippet so that we only have \begin{array}{|} where | is the first placeholder stop $1 so that the user can specify whether one needs left or c enter or right alignment for each column?

1 Answer 1

1

Yes, this can be done by

  1. adding a $1 placeholder at \begin{array}{|}, and
  2. starting the placeholders within the matrix/array from 2 and up.

The first can be done by modifying lines 3-6 with

\begin{array}{${1:`!p
orient = ""
for _ in range(0, int(match.group(1))): orient += "l"
snip.rv = orient`}}

and the second can be done by modifying the code for create_matrix() to take in an additional argument controlling the starting placeholder:

global !p
def create_matrix_placeholders(snip):
    # not shown

def create_matrix(cols, rows, sep, start, end, placeholder=1):
    res = ""
    # 
    for _ in range(0, int(rows)):
        res += start + f"${placeholder} "
        placeholder += 1
        for _ in range(0, int(cols) - 1):
            res += sep + f" ${placeholder} "
            placeholder += 1
        res += end
    return res[:-1]
endglobal

and modifying line 8 of the snippet given in the question with

snip.rv = create_matrix(match.group(1), match.group(2), "&", "\t", "\\\\\\\\\n", 2)
5
  • Thank you. I tried carefully replicating your code. However, it does not seem to work. Specifically, when I type genarr3x4, there is a bunch of l's that get placed on top of the expanded snippet. Example can be seen imgur.com/a/dDag2KO
    – Tryer
    Commented Nov 23, 2022 at 17:04
  • Here is the diff of the after (lhs) vs before (rhs) imgur.com/55xnvnK imgur.com/gTKm1NG to ensure I have implemented your suggestions exactly.
    – Tryer
    Commented Nov 23, 2022 at 17:14
  • 1
    I got the same result that you did. It looks like the problem is with the implementation of the expansion of anonymous snippets.. Let me see if there is a workaround
    – husB
    Commented Nov 24, 2022 at 4:10
  • Well thank you. I certainly appreciate the time and effort.
    – Tryer
    Commented Nov 24, 2022 at 4:18
  • Unfortunately I could not find a workaround.. The details did not work, but I'll leave the main idea here: Currently the snippet is supposed to expand as genarr3x4 -> \begin{array}{${1:lll}} { ... placeholders to be anonymously expanded ... } \end{array} -> \begin{array}{${1:lll}} { $2 & $3 ... } \end{array}. This "double expansion" seems to mess up Ultisnips. Instead, empty the snippet before any anonymous expansion, ie. genarr3x4 -> (get the value of nrow, ncol, and clear that current line) -> { anonymously expand into \begin{array} ${1:lll} $2 & $3 ... } all at once
    – husB
    Commented Nov 24, 2022 at 4:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.