VS Code : variables in custom snippet - html

How do I create a custom snippet that will automatically enter a variable's value that I type into its prefix?
I want a snippet that will create a html start-end tag comment block. For example if I type /se hello I want the result to be
<!-- $var start-->
<!-- $var end-->
Where $var is replaced with "hello". Thank you for reading!

As the VSCode snippet docs says, it uses TextMate to power its snippets. TextMate uses variables of the form $name and ${name:default}, and luckily supplies $TM_CURRENT_WORD which may be sufficient for your needs. However there is no built in variable to get multiple arguments directly after the snippet name i.e. $arg1 and $arg2 as variables. Thought you could do a similar effect with interpolated shell code, but unfortunately:
The snippet syntax follows the TextMate snippet syntax with the exceptions of 'interpolated shell code' and the use of \u; both are not supported.
Emphasis mine
However for this simple example, the following indexed variable example is probably sufficient.
<!-- $1 start-->
$0
<!-- $1 end-->
$i gives you a value to fill in, you can go between each one with tabbing. The $0 is where the cursor goes at the end(the end of the snippet by default). Optionally you can do something like:
<!-- ${1: default text} start-->
$0
<!-- $1 end-->
and it'll start looking like:
<!-- default text start-->
<!-- default text end-->
with both of the defaults selected to edit.
This all put together would look like this together in the snippets.json file:
{
"se": {
"scope": "html",
"prefix": "se",
"body": [
"<!-- ${1:default text} start-->",
"\t$0",
"<!--$1 end-->"
]
}
}
As #Mark pointed out, if you want it to work for more than just HTML you can use $BLOCK_COMMENT_START and $BLOCK_COMMENT_END which will vary for each language. The snippet would then look like this:
{
"se": {
// Leaving scope off will make it a global snippet
"prefix": "se",
"body": [
"$BLOCK_COMMENT_START ${1:default text} start $BLOCK_COMMENT_END",
"\t$0",
"$BLOCK_COMMENT_START$1 end $BLOCK_COMMENT_END"
]
}
}

Related

how to wirte a python snippet in vscode to print something

I found that when you type.print at the end of the line in pycharm, it will automatically convert this line to print(line). So I want to know whether vscode can achieve such a function with snippet.
I have written a snippet after googling.
"print": {
"prefix": "print",
"body": "\nprint(${TM_CURRENT_LINE-})"
}
However, there is a problem in this snippet: the prefix will be added during conversion. Besides, it only adds an additional line instead of changing the current line.
demonstration of snippet now
you can do it like this:
".print": {
"prefix": ".print",
"body": ["\nprint(${TM_CURRENT_LINE/(^.+)(\\..+)/$1/g})"],
}

PHPStorm: JS Language Injection with custom tags inside template

In needing html templates with embedded javascript on a PHP project I was not satisfied with any solutions I found, so, with Lodash and some regex I created the following solution :
Template:
<script id="profile_greeting" type="text/template">
<h1>Hello</h1><br>
My name is <b><#=this.name#></b><br>
<# var today = "" + new Date(); #>
The date is : <#= today #>
</script>
Lodash settings :
_.templateSettings = {
interpolate: /\<\#\=([\s\S]+?)\#\>/g,
escape: /\<\#\-([\s\S]+?)\#\>/g,
evaluate: /\<\#([\s\S]+?)\#\>/g
};
Question:
How do I setup PHPStorm to treat any code inside <# #> and <#= #> as Javascript (syntax highlight, code completion, etc) while treating the outside as HTML ?
Note:
Code inside should be treated as HTML, and <# #> pieces should only be treated as javascript when inside this type of tag.
Press Alt+F7 and go to Language Injections and create a new injection that is customized to your wishes.
Maybe this can help.
Edit:
I made a RegExr with the regexp to match your wishes (/<#((?:\s|.)*?)#>/gm).
Only trouble is how it should be fed to PHPStorm...

SublimeText completion fails inside HTML attributes

SublimeText completion using .sublime-completions file fails to work on HTML attribute, inside the quotes. Typing the trigger (test in the example below) inside the alt="" attribute does not insert the completion. It does outside the image tag without problems. Any suggestions why?
Scope inside the quotes is matching the definition in the html-attr.sublime-completions file below: text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html.
<body>
<img src="/images/poster.jpg" alt="">
</body>
I am using .sublime-completions file:
// html-attr.sublime-completions
{
"scope": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html",
"completions":
[
{
"trigger": "test",
"contents": "test ok"
}
]
}
Other installed packages include Emmet, HTML5, Better Completion, HTMLAttributes and SublimeCodeIntel, but disabling them all does not help the situation.
// Preferences.sublime-settings
{
"auto_complete": true,
}
Update:
Emmet could have been a culprit, but not my case. Emmet overrides completions defined by .sublime-completions files, unless Emmet's tab_abbreviation is disabled for the corresponding scope:
// Emmet.sublime-settings
"disable_tab_abbreviations_for_scopes": "text.html.basic"
I solved the problem temporarily by using .sublime-snippet, but it didn't work on the XML files so well. Still looking for an answer to the question above.
<!-- html-attr.sublime-snippet -->
<snippet>
<content>test ok</content>
<tabTrigger>test</tabTrigger>
<scope>text.html.basic</scope>
<description>html-attr.sublime-completion does not work</description>
</snippet>

What tools are available for translating (human) languages within HTML code?

Is there a tool or task runner that can take an HTML document in one language, parse out the content in general/specific HTML tags, run that content through Google translate, then put it back into the markup in the right place in new files? Basically, digest one source file and output multiple variations in different (non-computer) languages.
What I'm hoping for is:
index.html
<!DOCTYPE html>
<html>
<body>
привет мир!
</body>
</html>
Gets compiled to:
en/index.html
<!DOCTYPE html>
<html>
<body>
Hello World!
</body>
</html>
ru/index.html
<!DOCTYPE html>
<html>
<body>
привет мир!
</body>
</html>
ch/index.html
<!DOCTYPE html>
<html>
<body>
你好世界!
</body>
</html>
I obviously don't mind setting up some sort of Gruntfile or whatever that dictates the languages, destinations, etc.
Take a look at get-translation or grunt-google-translate. Also Google Translate has simple REST API, you can write your own plugin from the scratch or use something like grunt-restful.
I was able to piece together a solution using Ruby and Grunt. This could be refactored to be more robust, but it was a working solution, so I ran with it. Keep in mind, the translating script overwrites the source files. Only the Grunt starts making duplicates in new destinations.
Using the easy_translate Rub gem I wrote this script:
#!/usr/bin/ruby
require 'easy_translate'
EasyTranslate.api_key = '' # Get from google
target_path = '' # path to translate
Dir.glob(target_path) do |item|
next if item == '.' or item == '..' or item == '.svn'
contents = ""
update = ""
File.open(item, "r") do |file|
contents += file.read
update += EasyTranslate.translate(contents, :from => :russian, :to => :en)
end
File.open(item, "w"){ }
File.open(item, "w") do |file|
file.write(update)
end
end
Walking through this, each file in the target_path is checked if it’s a worthwhile item we make variables contents and update we’ll use to place in the old and new versions of the contents of the file, respectively. Then we open the file and fill up those variable. On line 20 we empty the file, then in the last block on lines 22-24 we write the update string into the file. I used File.open(item, "w") {} instead of .truncate(0) because I was getting random Unicode characters added to the contents of the file with the latter option. Again, overwriting the files in the translation process is not ideal. It'd be better to make a copy in a new destination, but I didn't do that.
The Ruby script returned a single line of minified HTML and broke Smarty templating, so I used used grunt-prettify and grunt-text-replace to prettify the HTML for ease of use and to make the Smarty stuff work again. The Gruntfile looks like this:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
'prettify': {
options: {
indent: 4,
indent_char: ' ',
wrap_line_length: 0,
brace_style: 'expand',
"unformatted": [
"a",
"code",
"pre"
]
},
all: {
expand: true,
cwd: 'static_ugly',
ext: '.html',
src: ['*.html'],
dest: 'static_pretty'
}
},
'replace': {
fix_smarty: {
src: ['static_pretty/*.html'],
overwrite: true,
replacements: [{
from: '{/ Strip',
to: '{/strip'
},{
from: '{$ This-> setLayout ',
to: '{$this->setLayout'
},{
from: '{$ this- > setPageTitle ',
to: '{$this->setPageTitle'
},{
from: '$ this-> setPageTitle ',
to: '$this->setPageTitle'
},{
from: '{$ smarty.block.footer ',
to: '{$smarty.block.footer'
}]
}
}
});
grunt.loadNpmTasks('grunt-prettify');
grunt.loadNpmTasks('grunt-text-replace');
grunt.registerTask('default', ['prettify', 'replace']);
};
There was a lot more find/replace stuff that I left out since it's project-specific. This solution pretty much does what I wanted in the original question. I did some manual moving around of files in the name of getting it done, but I believe I'll be using a variation of this moving forward and consider it a work in progress.

What is the correct syntax for using HTML builder with mixed content in Groovy 1.7?

On the Groovy example page there is an example of how to use Groovy HTML builder with mixed content:
p [
"This is some",
b"mixed",
"text. For more see the",
ahref:'http://groovy.codehaus.org' ["Groovy"],
"project"
]
This is however not working for me, I get an error message like:
expecting ']', found 'mixed' # line 33, column 23. b"mixed", ^ 1 error
The Groovy example page states that:
[Note: the syntax in some of these
examples is slightly out-dated. See
chapter 8 of GINA in the mean-time
until these examples are updated.]
My suspicion therefore is that the syntax of the HTML builder has changed, however I don't have the book so I cannot check and I cannot seem to find any relevant example of this working online. Does anyone know how the syntax is supposed to be in Groovy 1.7 and have got this working?
I found a lot of the stuff in that example to be out dated. The syntax for mixed hrefs and the [] around the paragraph do not work for me.
For mixed content, you need to use the special keyword 'mkp.yield'. There is also an 'mkp.yieldUnescaped' if you don't want escaping. There are some other functions you can do with mkp as well.
This example does work and shows using mixed content:
def builder = new groovy.xml.MarkupBuilder()
builder.html {
head {
title"XML encoding with Groovy"
}
body {
h1"XML encoding with Groovy"
p"this format can be used as an alternative markup to XML"
a(href:'http://groovy.codehaus.org', "Groovy")
p {
mkp.yield "This is some"
b"mixed"
mkp.yield " text. For more see the"
a(href:'http://groovy.codehaus.org', "Groovy")
mkp.yield "project"
}
p "some text"
}
}​
Output:
<html>
<head>
<title>XML encoding with Groovy</title>
</head>
<body>
<h1>XML encoding with Groovy</h1>
<p>this format can be used as an alternative markup to XML</p>
<a href='http://groovy.codehaus.org'>Groovy</a>
<p>This is some
<b>mixed</b> text. For more see the
<a href='http://groovy.codehaus.org'>Groovy</a>project
</p>
<p>some text</p>
</body>
</html>
I think this works better:-
def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.html {
head {
title"Report"
}
body {
h1"XML encoding with Groovy"
p"this format can be used as an alternative markup to XML"
// an element with attributes and text content /
a(href:'http://groovy.codehaus.org', "Groovy")
// mixed content /
p() {
"This is some"
"mixed"
"text. For more see the"
a(href:'http://groovy.codehaus.org', "Groovy")
"project"
}
p "some text"
}
}
Result is:-
<html>
<head>
<title>Report</title>
</head>
<body>
<h1>XML encoding with Groovy</h1>
<p>this format can be used as an alternative markup to XML</p>
<a href='http://groovy.codehaus.org'>Groovy</a>
<p>
<a href='http://groovy.codehaus.org'>Groovy</a>
</p>
<p>some text</p>
</body>
</html>
This
p() {
"This is some"
"mixed"
"text. For more see the"
a(href:'http://groovy.codehaus.org', "Groovy")
"project"
}
Does not do what you want. The closure is executed, but the strings by themselves when executed simply get evaluated and that's it - they don't go anywhere. 'a', on the other hand, is a method call that is evaluated in the context of the newly created 'p' node.