expected substitution value for custom inline macro to be of type Inline; got String - asciidoctor

I am trying to update my macro to use AsciidoctorJ 2.0.0. I have a macro extending InlineMacroProcessor that creates a link or a text depending on the configuration.
To create a link, I can do:
String linkUrl, linkText;
//TODO init the variables
// Define options for an 'anchor' element:
Map<String, Object> options = new HashMap<String, Object>();
options.put("type", ":link");
options.put("target", linkUrl);
// Create the 'anchor' node:
PhraseNode inline = createPhraseNode(parent, "anchor", linkText, attributes, options);
return inline;
I would like to just insert some text to the document.
Option 1. return just a String (as with the previous version of AsciidoctorJ):
String linkText;
//TODO init the linkText variable.
return linkText;
It works but I get this log entry:
INFO: expected substitution value for custom inline macro to be of type Inline; got String
Which is implying that I am doing something wrong with the new API.
Option 2: I have tried to create a PhraseNode of type "text" (I invented this)
String linkText;
//TODO init the linkText variable.
PhraseNode inline = createPhraseNode(parent, "text", linkText, attributes, options);
return inline;
But then I get:
org.asciidoctor.jruby.internal.AsciidoctorCoreException: org.jruby.exceptions.NoMethodError: (NoMethodError) undefined method `convert_inline_text' for #<Asciidoctor::Converter::Html5Converter:0x10b4e7f8>
Did you mean? convert_inline_button
convert_inline_quoted
convert_inline_menu
convert_inline_image
convert_inline_break
convert_inline_kbd
So what is the correct way to create an Inline that contains just a string?

If you want to return a String, you can use:
PhraseNode inline = createPhraseNode(parent, "quoted", linkText, attributes, options);
return inline;

Related

Is there a simple way to convert lambda into a full expression in Kotlin with Android Studio 3.5.1?

The code in popup.setOnMenuItemClickListener is lambda expression, the function of the code is to show a popup menu.
It's hard to understand lambda expression sometimes.
Is there a simple way to convert a lambda into a full expression ? Is there some utilities to do that?
Code
private fun showPopup(v: View, mContext: Context) {
val popup = PopupMenu(mContext, v)
popup.inflate(R.menu.menu_popup_more)
popup.setOnMenuItemClickListener {
when (it.itemId) {
R.id.MenuMoreAbout->{
requireActivity().openActivity<UIAbout>()
}
}
true // Why do I need add 'true'
}
popup.show()
}
Is there a simple way to convert a lambda into a full expression ?
Yes there is! First position the cursor on the first curly brace
Position your cursor at this character
|
v
popup.setOnMenuItemClickListener {
when (it.itemId) {
R.id.MenuMoreAbout->{
requireActivity().openActivity<UIAbout>()
}
}
true // Why do I need add 'true'
}
then type Alt+Enter (Option+Enter for Mac) to bring up the Quick Fix menu. Select Convert to anonymous function. That will turn the code into the following:
popup.setOnMenuItemClickListener(fun(it: MenuItem): Boolean {
when (it.itemId) {
R.id.MenuMoreAbout -> {
requireActivity().openActivity<UIAbout>()
}
}
return true
})
which is clearer for someone that is new to Kotlin syntax.
As can be seen, your true expression was the return value of the lambda. In Kotlin, the return value of a lambda is the value of the last expression in the lambda. If you prefer, you can make this explicit by replacing
true // Why do I need add 'true'
with
return#setOnMenuItemClickListener true
in your original code. See official docs for Return at Labels for more information.
The reason a Boolean has to be returned is because the lambda is for the following Java interface which is the type of the argument to setOnMenuItemClickListener(OnMenuItemClickListener)
public interface OnMenuItemClickListener {
boolean onMenuItemClick(MenuItem item);
}
As you can see, onMenuItemClick(MenuItem) returns a boolean (which is converted to Boolean in Kotlin). So the lambda must also return a Boolean.

Spotify API-Net ResumePlayback - Error With Code Example From Documentation

The documentation at Spotiy API_NET for ResumePlayback
gives the following example:
ErrorResponse error = _spotify.ResumePlayback(uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" });
When I try that code in C#, I get the following code error which prevents me building:
Error CS0121 The call is ambiguous between the following methods or properties: 'SpotifyWebAPI.ResumePlayback(string, string, List, int?)' and 'SpotifyWebAPI.ResumePlayback(string, string, List, string)'
Can anyone tell me what is wrong with this?
Also, what is the simplest way to simply resume the existing player at the point where it was paused?
Edit
#rene answered the first part of my question.
In regard to the second part, how to resume the existing player at the point where it was paused, I got the answer through the library's Github site, it's simply:
_spotify.ResumePlayback(offset: "")
The ResumePlayback method has two overloads that take these parameters:
ErrorResponse ResumePlayback(string deviceId = "",
string contextUri = "",
List<string> uris = null,
int? offset = null)
and
ErrorResponse ResumePlayback(string deviceId = "",
string contextUri = "",
List<string> uris = null,
string offset = "")
When the compiler comes across this line
ErrorResponse error = _spotify.ResumePlayback(
uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" });
it has to decide which ResumePlayback it is going to call and it doesn't want to take a guess or roll a dice.
It looks at which parameters are going to be provided and you only give it uris (that is the third parameter). It will assume the defaults for the other parameters. For both methods these defaults (null for strings or for the Nullable<int> (int?)) apply so the compiler can't decide which method it should bind to. It shows you an error.
Provide more parameters so the compiler can pick an unique overload.
ErrorResponse error = _spotify.ResumePlayback(
uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" }
,
offset: 0
);
Adding that named parameter offset and setting it to the int value of 0 is enough for the compiler to pick this overload to bind to:
ResumePlayback(string deviceId, string contextUri, List<string> uris, int? offset)

BeginForm overload that accepts RouteValueDictionary and Dictionary<string,object> as htmlParameters

I came across this old question from 2009 that is asking the exact same question as I am now, but the solution no longer appears to work. I am currently using MVC 5.
I am calling BeginForm like this:
helper.BeginForm("Edit", controllerName, new { id }, FormMethod.Post, htmlAttributes.Attributes);
htmlAttributes.Attributes is Dictionary<string, object>. The form ends up generating this markup:
<form
comparer="System.OrdinalComparer"
count="2"
keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]"
values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]"
action="/CustomerDocumentTypeAdmin/Edit/1"
method="post">
You can clearly see that it's reflecting over the dictionary class itself and using its properties as the HTML attributes.
Previously, I was declaring my attributes like this:
new { id = "formId" }
I changed it to a dictionary because I need to be able to modify the value collection at any stage in the call stack.
The HtmlHelper extension overload that my call resolves to is this:
MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes);
The signature of my call certainly matches it, and the question I linked to seems to as well. Not sure why it's not working for me now.
So I found an overload that I can use which means I need to change the type of one of my parameters. This is the overload:
MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes);
This means I need to pass new { id } into a RouteValueDictionary like so:
helper.BeginForm("Edit", controllerName, new RouteValueDictionary(new { id }), FormMethod.Post, htmlAttributes.Attributes)
I could also pass a dictionary into the RouteValueDictionary, but not sure how marginal the performance difference would be. At any rate, this now works.

Groovy: Unexpected token ":"

I have this auto generated lines of codes:
EPRole validator: { EPRole r, EPUserEPRole ur ->
if (ur.EPUser == null) return
boolean existing = false
EPUserEPRole.withNewSession {
existing = EPUserEPRole.exists(ur.EPUser.id, r.id)
}
if (existing) {
return 'userRole.exists'
}
}
When I try to compile the code I get 82: unexpected token: validator # line 82, column 10.
I am new in groovy so any help is appreciated.
You should add your properties with the proper type and name to the class. First letter uppercase is for classes (or types in general). So there should be in your EPUserEPRole a property like this:
EPRole epRole
Then add the validator for epRole. Pay attention to the case.
Above code would confuse the groovy parser into defining a property validator of type EPRole followed by a :, hence the error (or else it would try to call the method EPRole with the map, depending on context).

Passing parameter between XAML pages

I have following requirement, I have 4 pages. First 3 pages prompt user to enter some information and finally on fourth page I do some processing and display the result.
I came up with this approach. I have created a class with all the field user enter in various pages
ref class CameraWiFiInfo sealed
{
public:
property String^ sCameraName;
property String^ sWiFIName;
property String^ sWifiPassword;
CameraWiFiInfo()
{
sCameraName = ref new String;
sWiFIName = ref new String;
sWifiPassword = ref new String;
}
};
I am trying to pass this object as follows
PAGE #1
CameraWiFiInfo^ cameraInfo = ref new CameraWiFiInfo();
cameraInfo->sCameraName = txtCameraName->Text;
this->Frame->Navigate(TypeName(WifiCheck::typeid),cameraInfo);
PAGE#2
void Page2::OnNavigatedTo(NavigationEventArgs^ e)
{
(void) e; // Unused parameter
CameraWiFiInfo^ cameraInfo= e->Parameter ;
}
I am getting error here error C2440: 'initializing': cannot convert from 'Platform::Object ^' to 'CameraWiFiInfo ^'.
I goggled in the net I didn't get any suitable C++/Win Rt XAML example to pass the data from one XAML page to another.If any one tried data passing in C++/Win Rt Please suggest on this.
You need an explicit cast:
CameraWiFiInfo^ cameraInfo= (CameraWiFiInfo^)e->Parameter;
But be careful when doing this, according to the documentation:
To enable serialization of the frame's state using GetNavigationState, you must pass only basic types to this method, such as string, char, numeric, and GUID types. […] In general, we discourage passing a non-basic type as a parameter to Navigate because it can’t be serialized when the application is suspended, and can consume more memory […]

Resources