What's the difference between li #{variable} and li= variable in Jade? - template-engine

I was playing with Jade Template Syntax and come into this (slightly modified from the documentation):
ul
for book in books
li= book
else
li sorry, no books!
{"books": ["First"]}
I can print "First" also with:
li #{book}
So, what's the difference between using #{book} and li= book?
EDIT downvoter: instead of downvoting without giving us an explanation, what about leaving a comment?

The difference is just a difference of output in html. But you are 100% right, there is a very small difference. book is the variable and #{book} is the text contained in the variable.
#{book} : will output the text contained in the variable book, which is First only.
li= book : will output the variable content into a li statement <li>First</li>
Therefore, li= book is identical to li #{book} and will output <li>First</li>
You can even play with this a bit more:
h1= book or h1 #{book}: will output <h1>First</h1>
h2= book or h2 #{book}: will output <h2>First</h2>

Related

xpath syntax for grabbing text data after a strong tag containing header text

<li><strong>Movie Title:</strong> Training Day</li>
How do I grab the textual content in this li tag; "Training Day"?
So I need to say 'if the strong tag has 'Movie Title' in it, return 'Training Day'.
I have tried stuff using the "following-sibling", but don't seem to be able to get this right.
Another attempt was
//li/text()[preceding::strong[contains(text(),'Movie Title')]]
But this returns ALL text, not just what is inside the li class.
Actually //li/text() should return "Training Day", while //li//text()- both "Training Day" and "Movie Title:"
You can try more specific XPath
//li[starts-with(., "Movie Title:")]//text()[not(parent::strong)]
to get "Training Day" only
How do I grab the textual content in this li tag; "Training Day"?
So I need to say 'if the strong tag has 'Movie Title' in it, return 'Training Day'.
The following XPath expression selects all li-element's text-nodes following a strong-element which value contains the string 'Movie Title'.
//li[contains(strong,'Movie Title')]/strong/following-sibling::text()
In your example XML this results in 'Training Day'.
But if more text-nodes followed, you'd have to restrict the expression to the first text-node like this
//li[contains(strong,'Movie Title')]/strong/following-sibling::text()[1]

Insert html tag between word that starts with # symbol in ruby regex

link = "http://github.com/"
message = "Hi #freedom and #cake please review my commit."
expected = "Hi <a href='http://github.com/freedom'>#freedom</a> and <a href='http://github.com/cake'>#cake</a> please review my commit."
How can I achieve the expected string above using the link and message values?
So far I can extract the username without the # symbol into Array.
links = []
message.scan(/#\b[^#][a-z]*\b/).each{|x| links << x.sub('#','')}
2.1.5 :010 > links
=> ["freedom", "cake"]
But I don't have any idea on how to insert link plus links into the message string.
Here is a sample code that you can use:
puts "Hi #freedom and #cake please review my commit.".gsub(/#([a-z]+)/i, "<a href='http:\/\/github.com\/\\1'>#\\1<\/a>")
Output:
Hi <a href='http://github.com/freedom'>#freedom</a> and <a href='http://github.com/cake'>#cake</a> please review my commit.
Tested on TutorialsPoint.
You can fine-tune the regex to /(?<=^|\s)#([a-z]+)/i to only match #something after a space or at the beginning of a string.
I don't know Ruby but usually you can work with capture-groups and reference them in the substitution text like in this regex101. So I changed the regex slightly:
#\b([^#][a-z]*)\b
Debuggex Demo
I would say your regex is needlessly complicated though, I would do this to do it simpler and also accept numbers and underscore in their username (not uncommon):
#(\w+)

Tag name in CSS selector (e.g. div#id): how is it read? (Left to right or right to left?) [duplicate]

This question already has answers here:
In which direction do selector engines read, exactly?
(2 answers)
Closed 6 years ago.
So I came across a couple of articles on CSS optimization:
http://csswizardry.com/2011/09/writing-efficient-css-selectors/
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS
Apparently CSS is read from right to left. That means that div table a is read like: first all a elements on the page are retrieved, then all table elements that have an a in them (right?), then all div elements with both of those in them (right?).
My question, which I couldn't find an answer to anywhere, is: how is a CSS rule like div#div_id parsed? Do first all elements with the id "div_id" get parsed, and is a filter then applied to fetch from that bunch of #div_id elements all div elements? Or are first all div elements parsed, and is a filter then applied to fetch everything with the id "div_id"?
The first article I mentioned says that the recommended order of efficiency in CSS is: #id > > .class > tag > rest. But what about tag#id?
To clarify: I like to type div#div_id just to have it clear for myself that #div_id applies to a div element without having to look up the HTML to find out which element's styling I'm looking at, but I wouldn't want to use it that way if it costs me much of my website's performance .What would be the recommended way of writing the rule then? Should I drop the tags in my selectors? Is it really that expensive?
The answer
The answer would be, as jbutler483 says: leaving the tag name out is faster. If you want to have clarification on what element you're styling, don't use div#my_id but #div_my_id. If you don't care that much about performance, you could still go with the div#my_id, but it will be a bit slower (but you can ask yourself if it will really impact your application that much).
Ok, I think you've gotten a little confused.
In your example, you use:
div table a
So i'll use that.
Pretty much, that could look like this in your html
<div>
<table>
<a>
//styling applied here
</a>
</table>
</div>
or something else like
<div>
<div></div>
<table>
<tr>
<th>hi there</th>
<th>
<a>i'm an a tag!</a>
So, looking at that:
div table a
will be
div table a
^ ^ ^
| | |
| | a child
| |
| parent
|
grandparent
This means that you'll be styling any 'a' element that is a child/descendant of a table, which, in turn, is a descendant of a div element
so, in your other example:
div#div_id
you would be styling all id's of div_id in which have a div as a parent.
BTW looking at your example, I would like to point out that (in case you didn't know):
the id attribute should be unique
an <a> attribute shouldn't be used directly within a <table> element (instead nest it within a th or td tag)
If you wish to style multiple elements (of varying types), it would be more efficient to create a class, and use that instead
Answer after Clarification:
Your
div#div_id
In HTML, since the id is meant to be unique, it will look up 'all id's' with the specified id.
It will then check if it is a div element.
This seems to be a bad example, as obviously some (older) browsers will only look for the first id, and return it instead of checking the whole webpage for any 'duplicate' id's.
With your id's being unique, you could then drop your tag as it will be left redundant/ no use
Summary
So, an example of this extended conversation in the comments:
if I wanted to style a single div (and still know it was a div that i was adding styling to), i would use the naming convention of:
<div id="my-div-to-style">
^
|
[the word 'div' here could be anything]
in my css i would write:
_ this word must match the
/ id i used above
|
#my-div-to-style{
//styling...
}
If i wanted to add the same styling to multiple div elements (with the scope to add it to others), i would instead use a class:
<div class="myDivStyle">
and then use:
.myDivStyle{
//styling...
}
in this last example, I would not be restricted to just styling divs, so i wouldn't include this in my naming:
<div class="myStyle">
<a class="myStyle">
<table class="myStyle">
.myStyle{
//styling for any element I want
}
As you say, rules are parsed right to left, the same applies here.
Although duplicate id values are not valid, it is up to the browser to decide whether to accept and parse them, the below (in Chrome) for example, renders the first and last elements with red text.
Demo Fiddle
div#test {
color:red;
}
<div id='test'>text</div>
<span id='test'>
text
</span>
<div id='test'>text</div>
In modern browsers you may want to be less mindful of selector resolution performance and instead look to obtain valid CSS adhering to best practices, keeping selectors as short and concise as possible.
What about tag#id? The second link you mention contains the answer.
Don’t qualify ID rules with tag names or classes
If a rule has an ID selector as its key selector, don’t add the tag
name to the rule. Since IDs are unique, adding a tag name would slow
down the matching process needlessly.
Don’t qualify class rules with tag names
The previous concept also applies here. Though classes can be used
many times on the same page, they are still more unique than a tag.
You may learn more about your question here: css-tricks => efficiently rendering html
There are four kinds of key selectors: ID, class, tag, and universal. It is that same order in how efficient they are.
#main-navigation { } /* ID (Fastest) */
body.home #page-wrap { } /* ID */
.main-navigation { } /* Class */
ul li a.current { } /* Class *
ul { } /* Tag */
ul li a { } /* Tag */
* { } /* Universal (Slowest) */
#content [title='home'] /* Universal */
When we combine this right-to-left idea, and the key selector idea, we can see that this selector isn't very efficient:
#main-nav > li { } /* Slower than it might seem */
Even though that feels weirdly counter-intuitive... Since ID's are so efficient we would think the browser could just find that ID quickly and then find the li children quickly. But in reality, the relatively slow li tag selector is run first.

Replacing <a> tags that have two pairs of double quotes

I have asked a similar question before but this one is slightly different
I have content with this sort of links in:
Professor Steve Jackson
[UPDATE]
And this is how i read it:
content = doc.xpath("/wcm:root/wcm:element[#name='Body']").inner_text
The links has two pairs of double quotes after the href=.
I am trying to strip out the tag and retrieve only the text like so:
Professor Steve Jackson
To do this I'm using the same method which works for this sort of link which has only a single pair of double quotes:
World
This returns World:
content = Nokogiri::XML.fragment(content_with_link)
content.css('a[href^="ssLINK"]')
.each{|a| a.replace("<>#{a.content}</>")}
=>World
When I try To do the same for the link that has two pairs of double quotes it complains:
content = Nokogiri::XML.fragment(content_with_link)
content.css('a[href^=""ssLINK""]')
.each{|a| a.replace("<>#{a.content}</>")}
Error:
/var/lib/gems/1.9.1/gems/nokogiri-1.6.0/lib/nokogiri/css/parser_extras.rb:87:in
`on_error': unexpected 'ssLINK' after '[:prefix_match, "\"\""]' (Nokogiri::CSS::SyntaxError)
Anyone know how I can overcome this issue?
I can suggest you two ways to do it, but it depends on whether : every <a> tag has href's with two "" enclosing them or its just the one with ssLINK
Assume
output = []
input_text = 'Professor Steve Jackson'
1) If a tags has href with "" only with ssLink then just do
Nokogiri::HTML(input_text).css('a[href=""]').each do |nokogiri_obj|
output << nokogiri_obj.text
end
# => output = ["Professor Steve Jackson"]
2) If all the a tags has href with ""then you can try this
nokogiri_a_tag_obj = Nokogiri::HTML(input_text).css('a[href=""]')
nokogiri_a_tag_obj.each do |nokogiri_obj|
output << nokogiri_obj.text if nokogiri_obj.has_attribute?('sslink')
end
# => output = ["Professor Steve Jackson"]
With this second approach if
input_text = 'Professor Steve Jackson Some other TextSecond link'
then also the output will be ["Professor Steve Jackson"]
Your content is not XML, so any attempt to solve the problem using XML tools such as XSLT and XPath is doomed to failure. Use a regex approach, e.g. awk or Perl. However, it's not immediately obvious to me how to match
<a href="" sometext"">
without also matching
<a href="" sometext="">
so we need to know a bit more about this syntax that you are trying to parse.

Getting price before and after discount separately using nokogiri n Ruby on Rails

I'm trying to learn on scrap these values which i put it in 2 different task:
get the 35.00 from the entire text
get the 42.00 from the entire text
below is the html:
<p style="font-size: 30px; margin-left: -10px; padding: 15px 0pt;">
$35.00 - $42.00
</p>
the code that im using to get the entire text is as below:
node = html_doc.at_css('p')
p node.text
You can get the whole text from node.text and that's as far as you need to go with Nokogiri. From there you could use scan to find the numbers and a bit of list wrangling (flatten and map) and you're done. Something like this:
first, second = node.text.scan(/(\d+(?:\.\d+))/).flatten.map(&:to_f)
That should leave you with 35.0 in first and 42.0 in second. If you know that the numbers are prices with decimals then you can simplify the regex a bit:
first, second = node.text.scan(/(\d+\.\d+)/).flatten.map(&:to_f)
mu's answer is correct but it seems simpler to use split/splat.
first, second = *node.text.tr('$', '').split(' - ')

Resources