Set default value in stylus mixin - mixins

Using stylus I want to create a mixin that uses the right image based on a locale option.
mixin
locale-image(name, locale)
if locale is not defined
locale = 'en-US'
background-image url('../images/'locale'/'name'.jpg')
Example Usage:
.us-image
locale-image('my-us-image')
.ge-image
locale-image('my-german-image', 'de-DE')
Basically is there a way to leave off a parameter like in the US example? How can I modify my mixin to support this?

Yep, you can use argument defaults:
locale-image(name, locale = 'en-US')
background-image url('../images/' + locale + '/' + name + '.jpg')
.us-image
locale-image('my-us-image')
.ge-image
locale-image('my-german-image', 'de-DE')

Related

How to select and set a covering/covered annotation as a feature in RUTA

I have a Ruta rule that looks something like this, where dep is a DKPro imported Dependency type.
dep{}->{MyItem{->
SETFEATURE("Display", "displayedValue"),
SETFEATURE("Lemma", dep.Dependent.lemma.value),
SETFEATURE("Parent", dep.Governor)};};
The first two actions work. The problem I have is in the third action SETFEATURE("Parent", dep.Governor). dep.Governor returns a Token type but my feature requires another type that happens to share the same location as the Governor. In other words I want my own type, not dep.Governor, that has already annotated that governing word.
I am unsure how to recover an annotation (my annotation) that occupies the same space as the dep.Governor. Ideally I would like to recover it as a variable so that I can reuse it for other features to do something like this.
a:MyItem [that overlaps dep.Governor]
dep{}->{MyItem{->SETFEATURE("Parent", a)};};
Here is a more precise example
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = d,
};
The line MyItem.LanguageParent = d produces this Ruta error
Trying to access value of feature "type.MyItem:LanguageParent" as "type.MyItem", but range of feature is "de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency"
I am sure there is a cleaner way than this, but for now, I am converting the type using a block function and saving it into an annotation variable.
BLOCK(ConvertTokenToMyItem) Token{IS(MyItem)} {
varMyItem:MyItem;
}
Then I use it
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = varMyItem,
};

AG-GRID value formatter not working for dynamically generated currency

I am trying to use a value-formatter in my AG-GRID table for displaying currency information.
This works perfectly when I have a hardcoded value in the formatter, in this case the unicode for 'Euros'
currencyFormatter(params) {
return '\u20ac' + params.value;
}
However, I dont know in advance what currency I will need to format the data in, as it is dynamically generated. If I try an use a value that is available in my component (like below) it doesn't like it!
currencyFormatter(params) {
return this.currencyUnicode + params.value;
}
There it throws in the console is:
TypeError: Cannot read property 'defaultCurrency' of undefined
It seems like all 'this' component variables are not available inside the currencyFormatter. Is there a way to make this work?
In order to access your component variables, you will have to bind your component context - this to the valueFormatter
...
name : 'Currency',
field : 'currency',
valueFormatter: this.currencyFormatter.bind(this) //bind your component's context here
...
currencyFormatter(params) {
return this.currencyUnicode + params.value;
}
This is a common javascript problem. Here is a good read
Also, this answer describes the 2 ways you can reference this.

Cannot parse date using JodaTime

I've been trying to parse a simple date using JodaTime since yesterday and so far I keep on failing.....
Here's a (random) date I'm trying to parse:
2017-Sept-14 (Even with S in upper case doesn't change anything...)
Here's my code
DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd");
// The variable 'parsed' is a dynamic string. For now I set it to 2017-sept-14
DateTime dateTime = dateTimeFormat.parseDateTime(parsed);
Log.d(TAG, "Parsed date = "+ dateTime.toString());
And here's the exception I have:
java.lang.IllegalArgumentException: Invalid format: "2017-sept-14" is malformed at "sept-14" at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945)
What am I missing here ??
UPDATE:
Actually what I get from my textfield is in the form above i.e date-month-day (the month is 3 or 4 characters long depending on the month....)
So what I want to get as output when I have 2017-sept-14 is simply 2017-09-14
Joda-Time accepts the month name in a short format (in most languages, it's usually with 3 letters) or long format (with the full name). Your input seems to be in English and with 4 letters, which is not supported.
If it's possible to manipulate the input, you can remove the extra characters and make sure the month name contains just 3 letters.
I also use a java.util.Locale to specify that the month name is in English. If you don't specify a locale, it uses the system default, and it's not guaranteed to always be English, so it's better to specify one.
I also parse it to a LocalDate, because its toString() method already produces the output you want:
String input = "2017-Sept-14";
input = input.replace("Sept", "Sep");
DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MMM-dd").withLocale(Locale.ENGLISH);
LocalDate dateTime = dateTimeFormat.parseLocalDate(input);
System.out.println(dateTime);
The output is:
2017-09-14
I was assuming that the locale was English, but in Estonia locale the short month name for September is "sept", so you could also do:
String input = "2017-Sept-14";
input = input.toLowerCase(); // et_EE locale accepts only "sept"
DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MMM-dd")
.withLocale(new Locale("et", "EE"));
LocalDate dateTime = dateTimeFormat.parseLocalDate(input);
System.out.println(dateTime);
Or you can try with your system's default (based on your comments that SimpleDateFormat works with French locale, so there's a chance of the code above to also work).
Java new Date/Time API
Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
If you can't (or don't want to) migrate from Joda-Time to the new API, you can ignore this section.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).
You can create a formatter, set the locale and parse it to a LocalDate:
import org.threeten.bp.LocalDate;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeFormatterBuilder;
DateTimeFormatter f = new DateTimeFormatterBuilder()
// case insensitive (so it accepts Sept, sept, and so on)
.parseCaseInsensitive()
// pattern
.appendPattern("yyyy-MMM-dd")
// set locale
.toFormatter(new Locale("et", "EE"));
System.out.println(LocalDate.parse("2017-Sept-14", f));
The output is:
2017-09-14
Or just try with your system's default locale (just call toFormatter() without arguments and it'll use the system default).
Optionally, you can create a map of custom month names and use it in the formatter. The only detail is that you have to fill it with values for all months. I put Sept in September, and you can fill the other months accordingly:
// map of custom names for month
Map<Long, String> monthNames = new HashMap<>();
// put the names used in your input
monthNames.put(1L, "Jan");
monthNames.put(2L, "Feb");
monthNames.put(3L, "Mar");
monthNames.put(4L, "Apr");
monthNames.put(5L, "May");
monthNames.put(6L, "Jun");
monthNames.put(7L, "Jul");
monthNames.put(8L, "Aug");
monthNames.put(9L, "Sept");
monthNames.put(10L, "Oct");
monthNames.put(11L, "Nov");
monthNames.put(12L, "Dec");
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// case insensitive (so it accepts Sept, sept, and so on)
.parseCaseInsensitive()
// year
.appendPattern("yyyy-")
// month, using custom names
.appendText(ChronoField.MONTH_OF_YEAR, monthNames)
// day
.appendPattern("-dd")
// create formatter
.toFormatter();
String input = "2017-Sept-14";
System.out.println(LocalDate.parse(input, fmt));
Joda-Time does not offer a simple way. The only (complex) way would be to define your own implementation of DateTimeParser. You might find some inspiration how to implement it in another old SO-post from me and then do:
DateTimeParser monthParser = ...; // left as exercise to you
DateTimeFormatter joda =
new DateTimeFormatterBuilder()
.appendPattern("yyyy-")
.append(monthParser)
.append("-dd")
.toFormatter();
LocalDate ld = joda.parseLocalDate("2017-sept-14");
I am not sure why the answer of Hugo suggesting a map-based lookup of customized names does not work for you. Maybe the month names are variable and not fixed (for the same month). Maybe you just want to check if the month names start with the same prefix. If so then my lib Time4J might help you because it manages much more formatting/parsing attributes to control parsing, see following short example (it also manages additional trailing dots if present):
String s = "2017-sept.-14";
ChronoFormatter<PlainDate> f =
ChronoFormatter
.setUp(PlainDate.class, new java.util.Locale("fr", "FR"))
.addPattern("uuuu-MMM", PatternType.CLDR)
.skipUnknown(c -> c == '.', 1)
.addPattern("-dd", PatternType.CLDR)
.build()
.with(net.time4j.format.Attributes.PARSE_CASE_INSENSITIVE, true)
.with(net.time4j.format.Attributes.PARSE_PARTIAL_COMPARE, true);
System.out.println(f.parse(s)); // 2017-09-14
For Android, you would replace Time4J by Time4A and also replace the given lambda-expression by an anonymous class implementing the ChronoCondition-interface.
By the way, a lookup-table for fixed month names is possible with every library. For Joda, see my older SO-post mentioned above as link. For Java-8 or the threeten-backport see the answer of Hugo. For SimpleDateFormat see how to set a suitable instance of DateFormatSymbols. For Time4J, see the builder-API (similar to Java-8).
A final word about SimpleDateFormat. Even if it seems to work for you now (just because of lenient parsing which works for old Java and Time4J but interestingly not for java.time-API), I would still not trust it in every situation, and this old parser class is not thread-safe, too.
You need a two digits number for the month (09) if you want to keep the pattern yyyy-MM-dd. Otherwise change your pattern to yyyy-MMMM-dd.
So I don't know know if it's the right way but this worked for me (I ended up using SimpleDateFormat...) :
SimpleDateFormat sdfSource = new SimpleDateFormat("yyyy-MMM-dd");
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdfSource.parse(parsed);
String strOutput = sdfDestination.format(date);
Log.d(TAG, "Parsed date = "+ strOutput);
} catch (ParseException e) {
e.printStackTrace();
}

The concept of an object variable in typoscript

In my typoscript 20.special.value and 10.value.typolink.parameter have the same value, which is a page id. I use this value to build a heading and a menu of its subpages within the same COA object. I would like to be able to re-use this value.
How can I call a object property in typoscript?
Here's what I have tried:
10 = HTML
10 {
value.typolink {
parameter = {$temp.LANDINGPAGEMENU.20.special.value}
}
}
UPDATE:
I am re-utilizing my COA object in different parts of the site, and changing only the special.value, so to display a menu I have:
temp.LANDINGPAGEMENU.10.value.typolink.parameter = 2427
temp.LANDINGPAGEMENU.20.special.value = 2427
temp.COLUMN_NOTSURE < temp.LANDINGPAGEMENU
I am after a cleaner way of handling the
temp.LANDINGPAGEMENU.10.value.typolink.parameter = 2427
temp.LANDINGPAGEMENU.20.special.value = 2427
Full LANDINGPAGEMENU typoscript code is http://pastebin.com/p9kPuZEe
Use the constants but not in a way you tried. You have to define the constant first.
Constants: my_constant = 2427
Setup: parameter = {$my_constant}
...OR...
Assign one of the values by reference using the =< operator. However, this would work only when using the whole object. Example:
temp.something = TEXT
temp.something.value = 2427
...parameter.cObject =< temp.something
I suggest you go with the option 1 using the constants as the 2nd option is somewhat cumbersome.
You can copy the property but not by reference it.

Dynamic property names in VBA

I have a custom class module in VBA (Access) that is supposed to handle a large amount of external data. Currently I have two functions Read(name) and Write(name, value) that allows to read and set dynamic properties.
Is there a way to define a more syntactic way to read and write those data? I know that some objects in VBA have a special way of accessing data, for example the RecordSet, which allows to read and set data using myRS!property_name. Is there a way to do exactly the same for custom class modules?
The exclamation mark syntax is used to access members of a Scripting.Dictionary instance(you'll need to add a reference to Microsoft Scripting Runtime through Tools > References first). To use this syntaxyou'll need to be storing the information internally in a dictionary.
The quickest way to use it in a class is to give your class an object variable of type Scripting.Dictionary and set it up as follows:
Option Explicit
Dim d As Scripting.Dictionary
Private Sub Class_Initialize()
Set d = New Scripting.Dictionary
End Sub
Private Sub Class_Terminate()
Set d = Nothing
End Sub
Public Property Get IntData() As Scripting.Dictionary
Set IntData = d
End Property
Now you can access properties using myinstance.IntData!MyProperty = 1... but to get to where you want to be you need to use Charlie Pearson's technique for making IntData the default member for your class.
Once that's done, you can use the following syntax:
Dim m As MyClass
Set m = New MyClass
Debug.Print "Age = " & m!Age ' prints: Age =
m!Age = 27
Debug.Print "Age = " & m!Age ' prints: Age = 27
Set m = Nothing
Okay, thanks to Alain and KyleNZ I have now found a working way to do this, without having a collection or enumerable object below.
Basically, thanks to the name of the ! operator, I found out, that access via the bang/pling operator is equivalent to accessing the default member of an object. If the property Value is the default member of my class module, then there are three equivalent statements to access that property:
obj.Value("param")
obj("param")
obj!param
So to make a short syntax working for a custom class module, all one has to do is to define a default member. For example, I now used the following Value property:
Property Get Value(name As String) As String
Value = SomeLookupInMyXMLDocument(name)
End Property
Property Let Value(name As String, val As String) As String
SetSomeNodeValueInMyXMLDocument(name, val)
End Property
Normally, you could now access that like this:
obj.Value("foo") = "New value"
MsgBox obj.Value("foo")
Now to make that property the default member, you have to add a line to the Property definition:
Attribute Value.VB_UserMemId = 0
So, I end up with this:
Property Get Value(name As String) As String
Attribute Value.VB_UserMemId = 0
Value = SomeLookupInMyXMLDocument(name)
End Property
Property Let Value(name As String, val As String) As String
Attribute Value.VB_UserMemId = 0
SetSomeNodeValueInMyXMLDocument(name, val)
End Property
And after that, this works and equivalent to the code shown above:
obj("foo") = "New value"
MsgBox obj("foo")
' As well as
obj!foo = "New value"
MsgBox obj!foo
' Or for more complex `name` entries (i.e. with invalid identifier symbols)
obj![foo] = "New value"
MsgBox obj![foo]
Note that you have to add the Attribute Value.VB_UserMemId = 0 in some other editor than the VBA editor that ships with Microsoft Office, as that one hides Attribute directives for some reason.. You can easily export the module, open it in notepad, add the directives, and import it back in the VBA editor. As long as you don't change too much with the default member, the directive should not be removed (just make sure you check from time to time in an external editor).
See this other question: Bang Notation and Dot Notation in VBA and MS-Access
The bang operator (!) is shorthand for
accessing members of a Collection or
other enumerable object
If you make your class extend the Collection class in VBA then you should be able to take advantage of those operators. In the following question is an example of a user who extended the collection class:
Extend Collections Class VBA