Not able to run lambdasoup example - web-scraping

I can't seem to run run one snippet of code given as example in lambdasoup. Whenever I run the code it gives error: This expression has type string but an expression was expected of type string list pointing to the "" argument of String.concat. But trimmed_texts li will give it the string list it expects, so why is it complaining?
example html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<ul class="odd">
<li>1. One</li>
<li>3. Three</li>
<li>5. Five</li>
<li>7. Seven </li>
<li>9. Nine</li>
</ul>
<ul class="even">
<li>2. Two</li>
<li>4. Four</li>
<li>6. Six</li>
<li>8. Eight</li>
<li>10. Ten</li>
</ul>
</body>
</html>
ocaml snippet:
(* Find the first unordered list. *)
let ul = soup $ "ul" in
(* Print the contents of all its items. *)
ul $$ "li"
|> iter (fun li ->
trimmed_texts li |> String.concat "" |> print_endline)
Note: I'm using the library Core.

Figured out the problem as I was writing the question. The code works if we are explicit with the String.concat labeled argument sep:
(* Find the first unordered list. *)
let ul = soup $ "ul" in
(* Print the contents of all its items. *)
ul $$ "li"
|> iter (fun li ->
trimmed_texts li |> String.concat ~sep: "" |> print_endline)

Related

OOCSS - only use class to do styling

I am practicing OOCSS now but I meet a problem.
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
If I want to style these 3 <li> items separately I will do:
li:nth-of-type(1) {}
li:nth-of-type(2) {}
li:nth-of-type(3) {}
But according to OOCSS we should use class to style the elements, like:
<ul>
<li class="li-1">a</li>
<li class="li-2">b</li>
<li class="li-3">c</li>
</ul>
.li-1 {}
.li-2 {}
.li-3 {}
Now seems OK but what if I have 10 <li> I have to add 10 classes which looks dumb to me.
Which style should I use? Can I use those that other than classes to style the elements, based on OOCSS?
Well, technically I think what they are referring to is that you should use classes instead of html element identifiers.
So perhaps doing something like:
<ul>
<li class="li">a</li>
<li class="li">b</li>
<li class="li">b</li>
</ul>
And then just use your original styles like:
.li:nth-of-type(1) {}
.li:nth-of-type(2) {}
.li:nth-of-type(3) {}
In your case you're basically using classes as you would use an id. Classes are supposed to identify multiple elements.

data type (model) was displayed as (data type (model when using "direction:rtl"

I encounter a problem failing to format the parenthesis when using style="direction: rtl;
<ul style="direction: rtl; ">
<li>data type (model)</li>
<li>try another data type (model)</li>
</ul>
It displayed as:
I add css white-space:nowrap,which not the solution.
Use should use the left-to-right mark: ‎ after the parentheses so that the text is read left to right. https://www.w3.org/TR/WCAG20-TECHS/H34.html
<ul style="direction: rtl; ">
<li>data type (model)‎</li>
<li>try another data type (model)‎ </li>
</ul>

Display an unordered list of phone numbers

I made a block to loop though the database and grab all the numbers and display them on an unordered list but they are all coming back on the same line like they are all one item. I feel that the block should automatically separate them?
`<h1>Listing Numbers</h1>
<div class='from-group'>
<ul>
<li class="numbers">
<% #people.each do |person| %>
<%= person.phone_number %>
<% end %>
</li>
</ul>
</div>
`
What I think is happening is that all the numbers are on ONE li rather than individual li...
See the difference:
<h1>Listing Numbers</h1>
<div class='from-group'>
<ul>
<li class="numbers">
Item 1 Item 2 Item 3 (we're all in the same li)
</li>
</ul>
</div>
<h1>Listing Numbers</h1>
<div class='from-group'>
<ul>
<li class="numbers">Item 1 Separate li</li>
<li class="numbers">Item 2 Separate li</li>
<li class="numbers">Item 3 Separate li</li>
</ul>
</div>
Looks like there's one iteration only and person.phone_number prints all three numbers at once. Check the person. I think it holds all three numbers in one attribute phone_number. In this case you could split the numbers and join them together with a html line break.
<%= person.phone_number.split(" ").join("<br />") %>
But with this solution you keep the numbers in one li element only.
The other way would be to think about a database migration to store the numbers within different attributes (phone, mobil, fax, ...).

Indentation of li items in ng-repeat

I am using ng-repeat to show list items with some text. And I want every single item to be indented 10-20px to the right from the previous one. I don't have much experience with css.
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}">
{{todo.toDoText}}
</li>
Here is a jsFiddle with my code.
Thanks in advance!
you may use ng-style to solve your problem:
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}"
ng-style="{'margin-left': 10*$index+'px'}">
{{todo.toDoText}}
</li>
$index is a varibale that will be set by ng-repeat. You may use this to calculate your style.
Change your template with following::
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}" style="text-indent: {{$index * 10}}px">
{{todo.toDoText}}
</li>
</ul>
</div>

Prototype: How do I find the first element with a certain class?

I have 2 ul elements in my document. How can I find the first of the 2 using PrototypeJS? I tried this code:
first = $$('ul[class="level0"]')[0];
second = $$('ul[class="level0"]')[1];
Only first is filled, the second is empty. Any ideas? This is my html:
<ul id="nav">
<li class="level0 nav-1 first level-top parent">
<ul class="level0">...</ul>
</li>
<li class="level0 nav-2 last level-top parent">
<ul class="level0">...</ul>
</li>
</ul>
Thanks :)
Instead of using the attribute CSS selector use the class CSS selector
first = $$('ul.level0')[0];
second = $$('ul.level0')[1];
but otherwise that should work
there are other methods as well $$() returns an array of elements (even if is one) and you can refer to the .first()
first = $$('ul.level0').first()
Please let us know if fixing the HTML worked or if you are getting any errors in your javascript console - that could lead you to a different problem
Use
first
$('nav').down('.level0');
second
$('nav').down('.level0', 1);
Cheers

Resources