Make a vscode snippet that can use a variable number of arguments - regex

I am new to VSCode. Thinking about code snippets, I looked around for a way to kind of script inside the snippet. I mean to do more than just fill or transform a variable. For example...
This is a simple snippet. I am going to type rci for the class initializer. When I enter the method arguments I would like the assignment and documentation + some other things to happen.
rci<tab> and then def initialize(a, b)) to result in something like this...
attr_reader :a
attr_reader :b
# #param a [...] ...
# #param b [...] ...
def initialize(a, b)
#a = a
#b = b
end
Is it possible? How can it be achieved? There could be any number of arguments. And each argument would trigger another line of the class initializer.

"Class Initializer": {
"prefix": "rci",
"body": [
"${1/([^,]+)([,\\s]*|)/attr_reader :$1\n/g}",
"${1/([^,]+)([,\\s]*|)/# #param $1 [...]${2:+\n}/g}",
"def initialize($1)",
"${1/([^,]+)((,\\s*)|)/\t#$1 = $1${2:+\n}/g}",
"end"
],
"description": "Initialize Class"
}
The key to get it to work for any number of method arguments is to get them into the same regex capture group.
Then, with the global flag set, each capture group will trigger the replacement text. So for instance, /attr_reader :$1\n/g will get triggered 3 times if you have 3 method arguments.
You will see this ${2:+\n} in the transforms above. That means if there is a capture group 2, add a newline. The regex is designed so that there is only a capture group 2 if there is another , between arguments. So a final ) after the last argument will not trigger another newline - so the output exactly matches your desired output as to newlines (but you could easily add or remove newlines).
Your input must be in the correct form:
v1, v2, v3
Here is a demo:
So again the necessary form is just v1 v2 v3. There doesn't need to be a space between the arguments but then you would get def initialize(v1,v2,v3) without spaces either.
Hit Tab after the final argument to trigger completion.
It turns out snippets are pretty powerful!!
For a similar question about using multiple arguments, see VSCode snippet: add multiple objects to a class constructor

Related

Aspose Word Merge

I am using Aspose library for Word merge.
In the previous version of the Aspose, if we add white spaces for a field then while merging , it doesn't considers it as empty but after upgrade to latest version, it is considering the whitespaces as blank and removing those fields if setting is ON.
For my case, I want to prevent whitespaces or empty fields for few fileds but remove it for rest of the fields.
I tried to find a setting which can be applied on field level to prevent or remove empty fields but have'nt got any.
Is there any way I can acheive this?
If paragraph contains only whitespaces it is considered as empty and is removed. So for example if you use code like the following:
string[] fieldNames = new string[] { "FirstName", "MidName", "LastName" };
string[] fieldValues = new string[] { "Alexey", " ", "Noskov" };
Document doc = new Document(#"C:\Temp\in.docx");
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.Execute(fieldNames, fieldValues);
doc.Save(#"C:\Temp\out.docx");
Where MidName merge field is placed in a separate paragraph, the paragraph will be removed as empty.
However, you can work this behavior around using IFieldMergingCallback. For example, you can put hidden text at the merge field to make the paragraph to be considered as not empty. For example see the following code:
string[] fieldNames = new string[] { "FirstName", "MidName", "LastName" };
string[] fieldValues = new string[] { "Alexey", " ", "Noskov" };
Document doc = new Document(#"C:\Temp\in.docx");
doc.MailMerge.FieldMergingCallback = new MergeWhitespaceCallback("MidName");
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.Execute(fieldNames, fieldValues);
doc.Save(#"C:\Temp\out.docx");
private class MergeWhitespaceCallback : IFieldMergingCallback
{
private readonly string[] mRetainParagraphsWithFields;
public MergeWhitespaceCallback(params string[] retainParagraphsWithFields)
{
mRetainParagraphsWithFields = retainParagraphsWithFields;
}
public void FieldMerging(FieldMergingArgs args)
{
if (!string.IsNullOrEmpty(args.FieldValue.ToString().Trim()))
return;
if (!mRetainParagraphsWithFields.Contains(args.FieldName))
return;
DocumentBuilder builder = new DocumentBuilder(args.Document);
builder.MoveTo(args.Field.Start);
builder.Font.Hidden = true;
builder.Write("<empty paragraph>");
}
public void ImageFieldMerging(ImageFieldMergingArgs args)
{
// Do nothing.
}
}
Later, you can remove hidden text if required.
Assuming you're actually executing a mailmerge (not just overwriting mergefields), you should be able to control most, if not all, of that via mailmerge field coding in the mailmerge main document.
On PCs, you can use the mergefield \b and/or \f switches to suppress a space before or after an empty mergefield. For example, suppose you have:
«Title» «FirstName» «SecondName» «LastName»
but «SecondName» is sometimes empty and you don’t want that to leave two spaces in the output. To deal with that:
select the «SecondName» field and press Shift-F9 so that you get
{MERGEFIELD SecondName};
edit the field code so that you end up with-
{MERGEFIELD SecondName \b " "} or
{MERGEFIELD SecondName \f " "}
depending on whether the space to be suppressed is following or before the mergefield;
delete, as appropriate, the corresponding space following or before
the mergefield;
position the cursor anywhere in this field and press F9 to update it.
Note 1: the \b and \f switches don't work on Macs or in conjunction with other switches. In such cases you need to use and IF test instead, coded along the lines of-
{IF{MERGEFIELD SecondName}<> "" " {MERGEFIELD SecondName}"} or
{IF{MERGEFIELD SecondName}<> "" "{MERGEFIELD SecondName} "}
Even so, you can use the \b and \f switches to express other mergefields that do have switches of their own. For example, suppose you have four fields ‘Product’, ‘Supplier’, ‘Quantity’ and ‘UnitPrice’, and you don’t want to output the ‘Product’, ‘Quantity’ or ‘UnitPrice’ fields if the ‘Supplier’ field is empty. In that case, you might use a field coded along the lines of:
{MERGEFIELD "Supplier" \b "{MERGEFIELD Product}→" \f "→{MERGEFIELD Quantity \# 0}→{MERGEFIELD UnitPrice \# "$0.00"}¶
"}
Note 2: The field brace pairs (i.e. '{ }') for the above example are all created in the document itself, via Ctrl-F9 (Cmd-F9 on a Mac or, if you’re using a laptop, you might need to use Ctrl-Fn-F9); you can't simply type them or copy & paste them from this message. Nor is it practical to add them via any of the standard Word dialogues. Likewise, the chevrons (i.e. '« »') are part of the actual mergefields - which you can insert from the 'Insert Merge Field' dropdown (i.e. you can't type or copy & paste them from this message, either). The spaces represented in the field constructions are all required. Instead of the →, ↵ and ¶ symbols, you should use real tabs and line/paragraph breaks, respectively.
For more Mailmerge Tips & Tricks, see: https://www.msofficeforums.com/mail-merge/21803-mailmerge-tips-tricks.html

How can I resolve this Loop problem in kotlin?

I was watching an old programming tutorial about loops and ranges in Kotlin and I tried to copy that same code but apparently my Kotlin version did not respond well.
The original Source Code was:
val capitals= listOf("London", "Paris", "Rome", "Madrid")
for(capital in capitals){
println(capital)
}
I have 2 Questions: First, why use capital and capitals again?
Also when I introduce the source code kotlin adds these symbols <>.
Updated Kotlin code (The one code causing me concern):
val capitals = listOf<> // (this is normal the problem is <>)
When I add the listOf to the value this automatically shows up.
Also, I don't know why the for(capital in capitals) {...} fails.
The code you provided works as expected:
val capitals = listOf("London", "Paris", "Rome", "Madrid")
for(capital in capitals){
println(capital)
}
Prints:
London
Paris
Rome
Madrid
why use capital and capitals again?
Using capital variable in the for loop you store each value of capitals list by iterating through it to handle it as you want.
When you declare a list like this val capitals = listOf("London", "Paris", "Rome", "Madrid"), it implies that you want to access its elements later. You can access its elements only by its name capitals, which you do in the for loop.
As for generics, classes or interfaces in Kotlin can have type parameters, which defined in <> brackets. List is one of such classes.
If the generic parameters can be inferred, for example you can omit the type arguments and <> brackets.

ArcGIS Python Toolbox Parameter Dependencies

I'm trying to connect two parameters. In the first, the user inputs a file which contains a list (each line is one item). In the second, I'm hoping to set a parameter of type Field or GPValueTable. Here's a look at how this part of the code currently looks like:
def getParameterInfo(self):
#Define parameter definitions
# Input Features parameter
in_features = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="DETextFile",
parameterType="Required",
direction="Input")
# User selection
selection_field = arcpy.Parameter(
displayName="Selection list",
name="selection_field",
datatype="Field",
parameterType="Required",
direction="Input")
selection_field.parameterDependencies = [in_features]
# Derived Output Features parameter
out_features = arcpy.Parameter(
displayName="Output Features",
name="out_features",
datatype="GPFeatureLayer",
parameterType="Derived",
direction="Output")
out_features.parameterDependencies = [in_features.name]
parameters = [in_features, selection_field]
return parameters
The text file looks like this:
A
B
C
The toolbox dialog output is just A. I'm having a hard time understanding what ArcGIS intended to create here. Perhaps I'm using the wrong data types, but their parameter explanation doesn't make it very clear.
Any ideas?
You are confused with the arcpy terminology, I think. The second parameter's datatype="Field" does not imply data can be read/parsed from a text file where the data columns are written, in fact it is the schema/fields of a proper table and expectation is not a simple text but the field objects of a table/feature class (in the toolbox's run-time, assignment to arcpy.Parameter yields a geoprocessing value object but it is a different discussion). If you look at the "Creating value table parameters" section here, GPFeatureLayer's (param0) fields are populated in param1 automatically when the dependency is set.
The solution is setting your selection_field to GPValueTable and populating the selection_field.filters[0].list by reading the in_features's content after the parameter is altered but has not validated in def updateParameters(...). Have a look at https://gis.stackexchange.com/questions/370250/updating-valuetable-parameter-of-arcpy-python-toolbox-tool.

RDL 2016 Report Builder skip a line for an optional parameter

I have an RDL template which contains of several parameters. They are all optional and marked:
Allow Null Value
Allow Blank Value ("")
It is important that they are optional since sometimes the address does not contain AddressLine3 (or in fact AddressLine1 or AddressLine2, or even PostCode):
They are all dropped together in one textbox area, and it all works well, but the problem is if I don't pass one of the optional params (AddressLIne2 in the example below) - an empty line is preserved in the report:
Any ideas on how to make that empty line disappear?
The easiest way to do this is to replace the list of 5 parameters with a single expression. Something like this.
=
Parameters!FullName.Value & IIF(IsNothing(Parameters!FullName.Value), Nothing, vbcrlf) &
Parameters!AddressLine1.Value & IIF(IsNothing(Parameters!AddressLine1.Value), Nothing, vbcrlf) &
Parameters!AddressLine2.Value & IIF(IsNothing(Parameters!AddressLine2.Value), Nothing, vbcrlf) &
Parameters!AddressLine3.Value & IIF(IsNothing(Parameters!AddressLine3.Value), Nothing, vbcrlf) &
Parameters!PostCode.Value
This simply concatenates each parameter value with a new line added only if the parameter was not empty.
Demo data
The following shows the same principle applied to some address data from the sample AdventureWorks database
The report shows all address fields for illustration
Which gives the following output

Search for an item in a text file using UIMA Ruta

I have been trying to search for an item which is there in a text file.
The text file is like
Eg: `
>HEADING
00345
XYZ
MethodName : fdsafk
Date: 23-4-2012
More text and some part containing instances of XYZ`
So I did a dictionary search for XYZ initially and found the positions, but I want only the 1st XYZ and not the rest. There is a property of XYZ that , it will always be between the 5 digit code and the text MethondName .
I am unable to do that.
WORDLIST ZipList = 'Zipcode.txt';
DECLARE Zip;
Document
Document{-> MARKFAST(Zip, ZipList)};
DECLARE Method;
"MethodName" -> Method;
WORDLIST typelist = 'typelist.txt';
DECLARE type;
Document{-> MARKFAST(type, typelist)};
Also how do we use REGEX in UIMA RUTA?
There are many ways to specify this. Here are some examples (not tested):
// just remove the other annotations (assuming type is the one you want)
type{-> UNMARK(type)} ANY{-STARTSWITH(Method)};
// only keep the first one: remove any annotation if there is one somewhere in front of it
// you can also specify this with POSISTION or CURRENTCOUNT, but both are slow
type # #type{-> UNMARK(type)}
// just create a new annotation in between
NUM{REGEXP(".....")} #{-> type} #Method;
There are two options to use regex in UIMA Ruta:
(find) simple regex rules like "[A-Za-z]+" -> Type;
(matches) REGEXP conditions for validating the match of a rule element like
ANY{REGEXP("[A-Za-z]+")-> Type};
Let me know if something is not clear. I will extend the description then.
DISCLAIMER: I am a developer of UIMA Ruta