unexpected snippets behavior in vscode+latex workshop - visual-studio-code

I'm using vscode with the latex workshop extension, and I put the following in my latex.json file.
"newcommand": {
"prefix": "nc",
"body": [
"\\newcommand{\\$1}{$2}",
],
},
I expected nc to expand to \newcommand{\}{}, with placeholders after the backslash and in the second pair of braces. However, I'm getting \newcommand{$1}{} with only one placeholder in the second pair of braces. Why is that? How can I get the desired behavior?

From the snippet doc
With \ (backslash), you can escape $, }, and \. Within choice elements, the backslash also escapes comma and pipe characters.
The following string is passed to the snippet engine: \newcommand{\$1}{$2}
\$ is interpreted as a literal $
We want the following string to be passed : \newcommand{\\$1}{$2}
Escaping this string for json gives
"\\newcommand{\\\\$1}{$2}"

Related

Pass a JSON string without using backslashes

Using backslashes to pass a JSON string as a parameter in PowerShell is cumbersome.
executable --json-input '{ \"name\": \"Bob\" }' output.txt
Is there a way to avoid using these backslashes? I tried using single quotes, and doubles quotes in and out without any success. In Python I use triple quotes print(""" here is an example "" """) to avoid character escaping.
Is there a similar solution in PowerShell? One where we never need to worry about reformating a JSON string?
PowerShell has here-strings, similar to the multiline literals from Perl (<<<) or Python (""").
The starting quote must be preceded by # and immediately followed by a line break, whereas the closing quote must follow a newline and be followed by another # sign:
command --json-input #"
{ "name": "Bob" }
"# output.txt
The unfortunate need for manual \-escaping of " chars. embedded in string arguments passed to external programs is due to a long-standing PowerShell bug that may finally get fixed in PowerShell 7.3, though possibly on an opt-in basis - see this answer for details.
That is to say, you should be able to just pass '{ "name": "Bob" }' - no \-escaping, but the bug prevents that.
To automate this escaping for now, without having to modify a given JSON string, you can apply a regex-based -replace operation, namely $json -replace '([\\]*)"', '$1$1\"'
# Note: only needed for *external executables*, up to at least PowerShell 7.2.x
executable --json-input ('{ "name": "Bob" }' -replace '([\\]*)"', '$1$1\"') output.txt
Note:
The above replacement operation also handles escaped embedded " characters correctly.
E.g., { "name": "Nat \"King\" Cole" } becomes { \"name\": \"Nat \\\"King\\\" Cole\" }, with the \ before " properly escaped as \\
See this regex101.com page for an explanation of the regex and replacement operation (for technical reasons, the linked page uses C#'s string format, which requires escaping \ and " in the regex and substitution expression too, but the solution is equivalent to what is shown here).
If you know your JSON input not to contain them, you can simplify to -replace '"', '\"'

Output is not generating while running the bash script [duplicate]

In Bash, what are the differences between single quotes ('') and double quotes ("")?
Single quotes won't interpolate anything, but double quotes will. For example: variables, backticks, certain \ escapes, etc.
Example:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
The Bash manual has this to say:
3.1.2.2 Single Quotes
Enclosing characters in single quotes (') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
3.1.2.3 Double Quotes
Enclosing characters in double quotes (") preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.
The special parameters * and # have special meaning when in double quotes (see Shell Parameter Expansion).
The accepted answer is great. I am making a table that helps in quick comprehension of the topic. The explanation involves a simple variable a as well as an indexed array arr.
If we set
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
and then echo the expression in the second column, we would get the result / behavior shown in the third column. The fourth column explains the behavior.
#
Expression
Result
Comments
1
"$a"
apple
variables are expanded inside ""
2
'$a'
$a
variables are not expanded inside ''
3
"'$a'"
'apple'
'' has no special meaning inside ""
4
'"$a"'
"$a"
"" is treated literally inside ''
5
'\''
invalid
can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6
"red$arocks"
red
$arocks does not expand $a; use ${a}rocks to preserve $a
7
"redapple$"
redapple$
$ followed by no variable name evaluates to $
8
'\"'
\"
\ has no special meaning inside ''
9
"\'"
\'
\' is interpreted inside "" but has no significance for '
10
"\""
"
\" is interpreted inside ""
11
"*"
*
glob does not work inside "" or ''
12
"\t\n"
\t\n
\t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13
"`echo hi`"
hi
`` and $() are evaluated inside "" (backquotes are retained in actual output)
14
'`echo hi`'
`echo hi`
`` and $() are not evaluated inside '' (backquotes are retained in actual output)
15
'${arr[0]}'
${arr[0]}
array access not possible inside ''
16
"${arr[0]}"
apple
array access works inside ""
17
$'$a\''
$a'
single quotes can be escaped inside ANSI-C quoting
18
"$'\t'"
$'\t'
ANSI-C quoting is not interpreted inside ""
19
'!cmd'
!cmd
history expansion character '!' is ignored inside ''
20
"!cmd"
cmd args
expands to the most recent command matching "cmd"
21
$'!cmd'
!cmd
history expansion character '!' is ignored inside ANSI-C quotes
See also:
ANSI-C quoting with $'' - GNU Bash Manual
Locale translation with $"" - GNU Bash Manual
A three-point formula for quotes
If you're referring to what happens when you echo something, the single quotes will literally echo what you have between them, while the double quotes will evaluate variables between them and output the value of the variable.
For example, this
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
will give this:
double quotes gives you sometext
single quotes gives you $MYVAR
Others explained it very well, and I just want to give something with simple examples.
Single quotes can be used around text to prevent the shell from interpreting any special characters. Dollar signs, spaces, ampersands, asterisks and other special characters are all ignored when enclosed within single quotes.
echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
It will give this:
All sorts of things are ignored in single quotes, like $ & * ; |.
The only thing that cannot be put within single quotes is a single quote.
Double quotes act similarly to single quotes, except double quotes still allow the shell to interpret dollar signs, back quotes and backslashes. It is already known that backslashes prevent a single special character from being interpreted. This can be useful within double quotes if a dollar sign needs to be used as text instead of for a variable. It also allows double quotes to be escaped so they are not interpreted as the end of a quoted string.
echo "Here's how we can use single ' and double \" quotes within double quotes"
It will give this:
Here's how we can use single ' and double " quotes within double quotes
It may also be noticed that the apostrophe, which would otherwise be interpreted as the beginning of a quoted string, is ignored within double quotes. Variables, however, are interpreted and substituted with their values within double quotes.
echo "The current Oracle SID is $ORACLE_SID"
It will give this:
The current Oracle SID is test
Back quotes are wholly unlike single or double quotes. Instead of being used to prevent the interpretation of special characters, back quotes actually force the execution of the commands they enclose. After the enclosed commands are executed, their output is substituted in place of the back quotes in the original line. This will be clearer with an example.
today=`date '+%A, %B %d, %Y'`
echo $today
It will give this:
Monday, September 28, 2015
Since this is the de facto answer when dealing with quotes in Bash, I'll add upon one more point missed in the answers above, when dealing with the arithmetic operators in the shell.
The Bash shell supports two ways to do arithmetic operation, one defined by the built-in let command and the other the $((..)) operator. The former evaluates an arithmetic expression while the latter is more of a compound statement.
It is important to understand that the arithmetic expression used with let undergoes word-splitting, pathname expansion just like any other shell commands. So proper quoting and escaping need to be done.
See this example when using let:
let 'foo = 2 + 1'
echo $foo
3
Using single quotes here is absolutely fine here, as there isn't any need for variable expansions here. Consider a case of
bar=1
let 'foo = $bar + 1'
It would fail miserably, as the $bar under single quotes would not expand and needs to be double-quoted as
let 'foo = '"$bar"' + 1'
This should be one of the reasons, the $((..)) should always be considered over using let. Because inside it, the contents aren't subject to word-splitting. The previous example using let can be simply written as
(( bar=1, foo = bar + 1 ))
Always remember to use $((..)) without single quotes
Though the $((..)) can be used with double quotes, there isn't any purpose to it as the result of it cannot contain content that would need the double quote. Just ensure it is not single quoted.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Maybe in some special cases of using the $((..)) operator inside a single quoted string, you need to interpolate quotes in a way that the operator either is left unquoted or under double quotes. E.g., consider a case, when you are tying to use the operator inside a curl statement to pass a counter every time a request is made, do
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Notice the use of nested double quotes inside, without which the literal string $((reqcnt++)) is passed to the requestCounter field.
There is a clear distinction between the usage of ' ' and " ".
When ' ' is used around anything, there is no "transformation or translation" done. It is printed as it is.
With " ", whatever it surrounds, is "translated or transformed" into its value.
By translation/ transformation I mean the following:
Anything within the single quotes will not be "translated" to their values. They will be taken as they are inside quotes. Example: a=23, then echo '$a' will produce $a on standard output. Whereas echo "$a" will produce 23 on standard output.
A minimal answer is needed for people to get going without spending a lot of time as I had to.
The following is, surprisingly (to those looking for an answer), a complete command:
$ echo '\'
whose output is:
\
Backslashes, surprisingly to even long-time users of bash, do not have any meaning inside single quotes. Nor does anything else.

How to pass space to Cobra CLI string slice flag?

I am using a StringSliceP from the Pflag libraray accept a list of strings as CLI arguments.
I am calling the Go application from the Windows Command Prompt.
I would like some of the strings of the list to contain a (") double quote character, but I have not been able to do this.
Escaping the quotes does not work:
goapp.exe --string-slice-list "a\"b",c,d,e
Expected result: []string{"a\"b", "c", "d", "e"}
Actual result: Error: invalid argument "a\"\\b,c,d,e" for "--string-slice-list" flag: parse error on line 1, column 1: bare " in non-quoted-field
Doubling up the quotes does not work:
goapp.exe --string-slice-list "a""b",c,d,e
Expected result: []string{"a\"b", "c", "d", "e"}
Actual result: Error: invalid argument "a\"b,c,d,e" for "--string-slice-list" flag: parse error on line 1, column 1: bare " in non-quoted-field
Here is how to do it from a Windows command prompt:
goapp.exe --string-slice-list \"a\"\"b\",c,d,e
yields [a"b c d e] and
goapp.exe --string-slice-list \"a\\\"\"b\",c,d,e
does [a\"b c d e] (I’m not sure which one you actually want).
The reason for this is, as has been pointed out, that the Pflag library makes use of the Go standard library encoding/csv supporting the format described in RFC 4180. If we refer to section 2 from paragraphs 5, 6 and 7:
If fields are not enclosed with double quotes, then
double quotes may not appear inside the fields.
Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes.
If double-quotes are used to enclose fields, then a double-quote
appearing inside a field must be escaped by preceding it with
another double quote.

confused about what must be escaped for sed

I want to replace specific strings in php files automatically using sed. Some work, and some do not. I already investigated this is not an issue with the replacement string but with the string that is to be replaced. I already tried to escape [ and ] with no success. It seems to be the whitespace within the () - not whitespaces in general. The first whitespaces (around the = ) do not have any problems. Please can someone point me to the problem:
sed -e "1,\$s/$adm = substr($path . rawurlencode($upload['name']) , 16);/$adm = rawurlencode($upload['name']); # fix 23/g" -i administration/identify.php
I already tried to shorten the string which should be replaced and the result was if I cut it directly behind $path it works, with the following whitespace it does not. Escaping whitespace has no effect...
what must be escaped for sed
The following characters have special meaning in sed and have to be escaped with \ for the regex to be taken literally:
\
[
the character used in separating s command parts, ie. / here
.
*
& only replacement string
Newline character is handled specially as the end of the string, but can be replaced for \n.
So first escape all special characters in input and then pass it to sed:
rgx="$adm = substr($path . rawurlencode($upload['name']) , 16);"
rgx_escaped=$(sed 's/[\\\[\.\*\/&]/\\&/g' <<<"$rgx")
sed "s/$rgx_escaped/ etc."
See Escape a string for a sed replace pattern for a generic escaping solution.
You may use
sed -i 's/\$adm = substr(\$path \. rawurlencode(\$upload\['"'"'name'"'"']) , 16);/$adm = rawurlencode($upload['"'"'name'"'"']); # fix 23/g' administration/identify.php
Note:
the sed command is basically wrapped in single quotes, the variable expansion won't occur inside single quotes
In the POSIX BRE syntax, ( matches a literal (, you do not need to escape ) either, but you need to escape [ and . that must match themselves
The single quotes require additional quoting with concatenation.

How to escape ] char in character class in sed

echo "eh]" | sed -r 's/[\]a]/lol/g' returns eh] instead of ehlol. no errors are raised so I assume \] is some kind of sed magic. Im tired of constant sed problems, but I have to use it. so how to escape ] in sed substition expression?
You can simply use echo "eh]" | sed -r 's/[]a]/lol/g':
without the backslash
and ] as first character inside the brackets.
] and \ have some specialties when used inside brackets.
Let me cite from the documentation:
A leading ^ reverses the meaning of list, so that it matches any single character not in list. To include ] in the list, make it the first character (after the ^ if needed), to include - in the list, make it the first or last; to include ^ put it after the first character.
The characters $, *, ., [, and \ are normally not special within list. For example, [\*] matches either ‘\’ or ‘*’, because the \ is not special here. However, strings like [.ch.], [=a=], and [:space:] are special within list and represent collating symbols, equivalence classes, and character classes, respectively, and [ is therefore special within list when it is followed by ., =, or :. Also, when not in POSIXLY_CORRECT mode, special escapes like \n and \t are recognized within list. See Escapes.