stylus string interpolation styntax for :before pseudo selector using a for loop - stylus

I'm trying to make
#others li .text1:before{
content: "text1";
}...
by doing
#others li
for label in text1 text2 text3
.{label}:before
content {label}
But syntax isn't right it seems... it gives error
expected "indent", got "outdent"
The error is for content {label} bit, because without it the class selectors (.text1:before) prints ok
And with content '{label}' it prints out {label} as is.

Stylus don't have interpolation in strings or idents for values, you could use addition to string, this would convert the ident to string:
#others li
for label in text1 text2 text3
.{label}:before
content ''+label

Related

Using React and trying to print a value exactly from {this.state.value}

I'm using React.js and in my state object of my App component, I have a value that contains \n characters and spaces.
this.state = {
value: "def foo():\n print('this is a function')\n\nfoo()"
}
However, when I try to show this value to the screen by wrapping this.state.value in a p tag like <p>{this.state.value}</p>, it simply prints out
def foo(): print('this is a function') foo()
without showing the spaces and \n characters. Is there any way I can get the value to print out exactly like how it's shown in the state object? Going into the React inspector on Chrome confirms that the value indeed matches the one in my state object.
This isn't specific to React but to how white space characters are treated in HTML. A new line can be displayed as <br> inside <p> and multiple spaces can be displayed as . While newline character and multiple spaces are displayed similarly to single space character.
It could be outputted as
<p>def foo():
print('this is a function')
foo()</p>
with same result.
In order to change that, the way how white space is displayed should be changed with white-space CSS property, e.g.:
<p style={{ 'white-space': 'pre' }}>
{this.state.value}
</p>
If the intention is to output the code with specified indentation and monospaced font, there's already <pre> tag that already has appropriate style by default, it can be used instead of <p>.
try to use string template with back-tick syntax like:
this.state = {
value: `def foo():
print('this is a function')
foo()`
}
EDIT: for better readability you can try to define constant before setState call:
const strTemplate = `def foo():
print('this is a function')
foo()`;
this.state = {
value: strTemplate
}
Let me know if it works :)
Try out this string:
this.state = {
value: "def foo():<br/> print('this is a function')<br/><br/>foo()"
}

Variable value in foreach of Red language

I am using following code to add multiple GUI elements to a view via a foreach loop:
myRange: function [n][ ; to produce a vector of [1 2 3 4... n]
vv: make vector! n
i: 1
foreach j vv [
vv/:i: i
i: i + 1
if i > n [break]]
vv ]
view collect[
foreach i myRange 10 [
print append "i in loop: " i
keep [ t: text ] keep append "message number: " i
keep [field "entry" button "Click" [t/text: "clicked"] return]
] ]
All GUI elements are being produced. But the code append "message number: " i is showing value of i to be 12345678910 in all text elements and not 1, 2, 3... 10 for different text elements.
Also, print append... statement is producing following output:
i in loop: 1
i in loop: 12
i in loop: 123
i in loop: 1234
i in loop: 12345
i in loop: 123456
i in loop: 1234567
i in loop: 12345678
i in loop: 123456789
i in loop: 12345678910
Moreover, clicking any button changes text of only the last added text element.
Where is the problem and how can it be solved? Thanks for your help.
Edit: It seems the language is converting my code from:
for i 1 10 1 [
print append "i in loop: " i ]
to:
a_variable: "i in loop"
for i 1 10 1 [
print append a_variable i ]
Which is not what I and (I think) most users want. In most languages a string "i in loop" will be taken as a constant and not converted to a variable since user has not specified it so. IMHO it will be easier for users of other languages to come here if such basic conventions are not altered.
Whenever you see something like this, it means you failed to create a new series and are reusing an existing series.
To get around that you need to create a new series with copy
Eg.
print append copy "i in loop: " i
Rebol3/ren-c no longer has this problem because source code is immutable and so you will get an error message with such code.
Rebol and Red reuses series (e.g. strings, blocks) as much as possible if you do not tell them otherwise by initializing anew with copy, make etc. So your issue should go away if you write
append copy "message number: " i
As the other answers suggest, you are only using a single string for your message and would need to be copied.
As to the other concern—you should take a wee look at the code you're generating (as I suggested elsewhere, you can pop a little PROBE to examine the output of the COLLECT function):
[
t: text "message number: 1" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 2" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 3" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 4" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 5" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 6" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 7" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 8" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 9" field "entry" button "Click" [t/text: "clicked"] return
t: text "message number: 10" field "entry" button "Click" [t/text: "clicked"] return
]
As you can see, you're constantly reassigning t so that in the end, it only refers to the last face.
A few options exist here—most prominent is to generate the name you're assigning the text face to. Within your FOREACH loop:
keep compose/deep [
(to set-word! rejoin ["t-" i])
text (rejoin ["Message Number: " i])
field "entry"
button "Click" [
set in (to word! rejoin ["t-" i]) 'text "clicked"
]
return
]
Note that in order to simplify the block creation, I used this line:
set in (to word! rejoin ["t-" i]) 'text "clicked"
This composes to (in the first instance):
set in t-1 'text "clicked"
IN returns the given word ('text) bound to the given context (the face object t-1) which is then SET to "clicked".
UPDATE
This method doesn't even use a word name, just uses a common parent to connect the button to the label:
view collect [
keep [below space 0x0]
foreach i myRange 10 [
keep compose/deep [
panel [
origin 0x0
text (rejoin ["Message Number: " i])
field "entry"
button "Click" [face/parent/pane/1/text: "clicked"]
]
]
]
]

How to split a Elements in scala into a Array of Strings

I have some troubles into slitting an Element (scraped from the web) into an Array of Strings.
Here is my code :
link = "http://www.myurl.com"
val doc: Document = Jsoup.connect(link).get()
val title2 = doc.select("li > h3 > a").toString
that give me :
1ERE COMPAGNIE D'ARC DU DAUPHINÉ
38SMS
40 BATTEURS
4L FOUR LIBERTY
A BORD PERDU
what i want is to have only the href in a Array of Strings. Only take the strings in the " ".
I've try to use JavaConverters like asScala, but i'm falling working with it :/
Thanks
simply extract href attributes from the a you get like:
doc.select("li > h3 > a").map(link -> link.attr("href")).toArray
take a look the more attribute extracting features from Jsoup

Selenium java code: How to read text from hidden element that contain many tags

1.<svg blablabla style:overflow: hidden > <aaa id=aaa>
2.+
3.<g>
4.<g>
5.<g>
6.<g>
The tags are inside the svg.
1 is the hidden tag, i want to get the 5th line text(), this is what i do.
WebElement hiddenDiv = driver.findElement(By.id("aaa"));
String n = hiddenDiv.getText();
String script = "return arguments[0].innerHTML";
n = (String) ((JavascriptExecutor) driver).executeScript(script, hiddenDiv);
System.out.println(n);
how can i get g[2], i have tried by direct xpath and it got an error because the svg is hidden.
You just need to grab an array of the g tags and pick the one you want. If you want the 5th, you would use the code below.
List<WebElement> gs = driver.findElements(By.cssSelector("#aaa g"));
System.out.println(gs.get(4).getAttribute("innerHTML"));

How to get text of element but excluding the sub-elements text

I want to get the text of the element without including the text of its elements. I have tried getText(), but it returns text that includes all the child elements text.
In the following example: When I retrieved text from the first div, it returns text that includes all its subelements.
<div class="row”>
<div class="col-lg-4 section”>
<div class="col-md-12”>
inseam 28 30 32
</div>
</div>
<div class="col-lg-5 section”>
<div class="col-md-13”>
inseam 28 34 36
</div>
</div>
</div>
Please let me know how to do this using webdriver in java.
Thanks
sean
I've been searching for the same thing for a while, here's my solution for those who can specify a WebElement or a list of WebElements:
def remove_child_text_from_webelement(webelement):
# Declaring the current text for this webelement
current_text = webelement.text
# Getting its childs elements in a list
childs_list = webelement.find_elements_by_xpath('./*')
# Manipulating text to remove child text from parents
childrens_text_list = [child.text for child in childs_list]
#return (childrens_text_list,type(childrens_text_list))
for children_text in childrens_text_list:
match_index = current_text.find(children_text)
if match_index != -1:
match_length = len(children_text)
current_text = current_text[0:match_index] + current_text[match_index+match_length:]
return current_text
Now you can do something like:
[remove_child_text_from_webelement(e) for e in browser.find_elements_by_xpath('//div[contains(#class,"person")]')]
When I retrieved text from the first div with class 'row', it returns text that includes all its subelements.
This happened because you retrieved text from the parent div and hence all the innerHTML/text of the child divs were retrieved along with them.
Below is the way to retrieve the necessary innerHTML/text only:
1- for 'inseam 28 30 32':
String text = driver.findElement(By.xpath("//div[#class='col-md-12']")).getText();
OR
String text = driver.findElement(By.className("col-md-12")).getText();
2- for 'inseam 28 34 36':
String text = driver.findElement(By.xpath("//div[#class='col-md-13']")).getText();
OR
String text = driver.findElement(By.className("col-md-13")).getText();
Not tried it specifically with Selenium, but with jQuery you can use contents() to get all elements including raw text nodes, filter by nodeType 3 (text nodes) and then take the first, in your example:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/p33gcfk2/1/
var text = $('.row').contents().filter(function () {
return this.nodeType == 3;
}).first();
alert(text.text());
This is happening because you are trying to get the text of parent tag. If you want to get tag of particular child, you have to reach all the way there. You can take use of "nth-child" or "nth-of-type". For e.g in this case, if you want to have return this text "inseam 28 34 36".
The CSS selector will be "div.row div:nth-of-type(3)" or you can directly specify the div class "div.col-md-13"
You can refer to this article on more on selectors https://saucelabs.com/resources/selenium/css-selectors

Resources