How to use html lists in Nitrogen - erlang

I would like to create an html list in Nitrogen but can't figure out how to do it. Basically I want to output:
<ul>
<li>One</li>
<li>Two</li>
</ul>
I found some source for lists under apps/nitrogen/src/elements/html in my Nitrogen distribution so it seems like there is an element that can do this but none of my attempts to use the element compile. Can someone please provide a snippet which will produce the above html?

Here's a version that uses the #list and #listitem nitrogen elements rather than raw HTML.
body() ->
List = ["Apple","Orange","Banana"],
#list{
body=[#listitem{body=Fruit} || Fruit <- ListOfFruit]
}.
For any expressions more complicated than that, I'll usually switch from a list comprehension to lists:map/2

Just use your erlang string and list manips like this:
body()->
Items = ["Joe Armstrong","Robert Virding","Mike Williams"],
UL = "<ul>" ++ lists:flatten(["<li>" ++ X ++ "</li>" || X <- Items]) ++"</ul>",
[
#panel{body=[
UL,
#br{},
#button {text="Continue", postback=continue}
]}
].
You have a list of items, the list can be from a database or anything. The list items should be strings for tis to work well, if a different type then you need to convert first. Then a list comprehension and latter you flatten the whole list to be one thing. Hope it helps !

Related

How to output text from lists of variable sizes using printf?

I'm trying to automate some output using printf but I'm struggling to find a way to pass to it the list of arguments expr_1, ..., expr_n in
printf (dest, string, expr_1, ..., expr_n)
I thought of using something like Javascript's spread operator but I'm not even sure I should need it.
For instace, say I have a list of strings to be output
a:["foo","bar","foobar"];
a string of appropriate format descriptors, say
s: "~a ~a ~a ~%";
and an output stream, say os. How can I invoke printf using these things in such a way that the result will be the same as writing
printf(os,s,a[1],a[2],a[3]);
Then I could generalize it to output lists of variable size.
Any suggestions?
Thanks.
EDIT:
I just learned about apply and, using the conditions I posed in my OP, the following seems to work wonderfully:
apply(printf,append([os,s],a));
Maxima printf implements most or maybe all of the formatting operators from Common Lisp FORMAT, which are quite extensive; see: http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm See also ? printf in Maxima to get an abbreviated list of formatting operators.
In particular for a list you can do something like:
printf (os, "my list: ~{~a~^, ~}~%", a);
to get the elements of a separated by ,. Here "~{...~}" tells printf to expect a list, and ~a is how to format each element, ~^ means omit the inter-element stuff after the last element, and , means put that between elements. Of course , could be anything.
There are many variations on that; if that's not what you're looking for, maybe I can help you find it.

Whet does it means to append a integer to a list in erlang?

The normal way to do a list appending is via:
10> [1,2,3] ++ [4].
[1,2,3,4]
But after I convert it to the following way, I actually don't get the point what does the result means here:
11> [1,2, 3] ++ 4.
[1,2,3|4]
Could anyone give me a explanation? Many thanks.
The Erlang lists are described in Getting Started with Erlang User's Guide in chapter Sequential Programming and subchapter Lists. The operator | separates a head of the list from a tail. The proper list ends with the empty list. The syntax with , is just syntactic sugar.
1> [1|[2|[3|[]]]].
[1,2,3]
It is like CONS function in Lisp. The list is called improper list if doesn't end with the empty list.
2> [1|[2|[3|4]]].
[1,2,3|4]
You made the improper list by appending number instead of a proper list. ([4] is proper list [4|[]].) See my answer to how is a list constructured by the erlang vm? for more details how it works internally in BEAM VM.

Remove contents within a specific tag

Using Rails 3.2. I want to remove all text in <b> and the tags, but I manage to find ways to strip the tags only.:
string = "
<p>
<b>Section 1</b>
Everything is good.<br>
<b>Section 2</b>
All is well.
</p>"
string.strip_tags
# => "Section 1 Everthing is good. Section 2 All is well."
I want to achieve this:
"Everthing is good. All is well."
Should I add regex matching too?
The "right" way would be to use an html parser like Nokogiri.
However for this simple task, you may use a regex. It's quite simple:
Search for : (?m)<b\s*>.*?<\/b\s*> and replace it with empty string. After that, use strip_tags.
Regex explanation:
(?m) # set the m modifier to match newlines with dots .
<b # match <b
\s* # match a whitespace zero or more times
> # match >
.*? # match anything ungreedy until </b found
<\/b # match </b
\s* # match a whitespace zero or more times
> # match >
Online demo
It would be much better to use an HTML/XML parser for this task. Ruby does not have a native one, but Nokogiri is good and wraps libxml/xslt
doc = Nokogiri::XML string
doc.xpath("//b").remove
result = doc.text # or .inner_html to include `<p>`
You can do string.gsub(/<b>.*<\/b>/, '')
http://rubular.com/r/hhmpY6Q6fX
if you want to remove tags you can try this :
ActionController::Base.helpers.sanitize("test<br>test<br>test<br> test")
if you want to remove all the tags you need to use this :
ActionView::Base.full_sanitizer.sanitize("test<br>test<br>test<br> test")
these two differ slightly.the first one is good for script tags to prevent Xss attacks but it doesn't remove tages. the second one removes any html tags in the text.

extracting runs of text with Mechanize/Nokogiri

Is there a sensible way to extract each run of text in a Mechanize-parsed HTML document, so that (for example):
<p>Here is <b>some</b> text<p>
is broken into three elements:
Here is
some
text
? My hunch is that there's a simple technique using recursive CSS search and/or #flatten, but I've not figured it out yet.
Borrowing from an answer in "Nokogiri recursively get all children":
result = []
doc.traverse { |node| result << node.text if node.text? }
That should give you the array ["Here is ", "some", " text"].
"Getting Mugged by Nokogiri" discusses traverse.
Since you want the contents of each text node, you can do this:
doc.search('//text()').map(&:text)
The only downside to this (and to the other answer) is that you get all the whitespace between elements as well. If you want to suppress this, you can do this:
doc.search('//text()').map(&:text).delete_if{|x| x !~ /\w/}
This removes all elements that don't contain a word character.

Input in Prolog

I'm currently working on a recursive Prolog program to link routes together to create a basic GPS of the Birmingham area. At the moment I can get output as so:
Input
routeplan(selly_oak, aston, P).
Output
P = [selly_oak, edgbaston, ... , aston]
What I would like to do is have my program provide some sort of interface, so if I were to type in something along the lines of:
Route from selly_oak to aston
It would provide me with:
Go from selly_oak to edgbaston
Go from edgbaston to ...
Finally, Go from ... to aston.
Prolog is a powerful language so I assume this is easily possible, however many of the books I've taken out seem to skip over this part. As far as I am aware I have to use something along the lines of write() and read() although the details are unknown to me.
Could anyone here a Prolog novice out with some basic examples or links to further information?
EDIT: A lot of these answers seem very complicated, where the solution should only be around 5-10 lines of code. Reading in a value isn't a problem as I can do something along the lines of:
find:-
write('Where are you? '),
read(X),
nl, write('Where do you want to go? '),
read(Y),
loopForRoute(X,Y).
I'd prefer it if the output could be written out using write() so a new line (nl) can be used, so that it displays like the output above.
If this were my input, how would I then arrange the top routeplan() to work with these inputs? Also, if I were to add the Lines for these stations as an extra parameter how would this then be implemented? All links are defined at the beginning of the file like so:
rlinks(selly_oak, edgbaston, uob_line).
rlinks(edgbaston, bham_new_street, main_line).
Therefore, with this information, it'd be good to be able to read the line as so.
Go from selly_oak to edgbaston using the uob_line
Go from edgbaston to ... using the ...
Finally, go from ... to aston using the astuni_line
A book which discusses such things in detail is Natural Language Processing for Prolog Programmers
by Michael A. Covington.
In general, what you need to do is
Tokenize the input
Parse the tokens (e.g. with DCG) to get the input for routeplan/3
Call routeplan/3
Generate some English on the basis of the output of routeplan/3
Something like this (works in SWI-Prolog):
% Usage example:
%
% ?- query_to_response('Route from selly_oak to aston', Response).
%
% Response = 'go from selly_oak to edgbaston then go from edgbaston
% to aston then stop .'
%
query_to_response(Query, Response) :-
concat_atom(QueryTokens, ' ', Query), % simple tokenizer
query(path(From, To), QueryTokens, []),
routeplan(From, To, Plan),
response(Plan, EnglishTokens, []),
concat_atom(EnglishTokens, ' ', Response).
% Query parser
query(path(From, To)) --> ['Route'], from(From), to(To).
from(From) --> [from], [From], { placename(From) }.
to(To) --> [to], [To], { placename(To) }.
% Response generator
response([_]) --> [stop], [.].
response([From, To | Tail]) -->
goto(path(From, To)), [then], response([To | Tail]).
goto(path(From, To)) --> [go], from(From), to(To).
% Placenames
placename(selly_oak).
placename(aston).
placename(edgbaston).
% Mock routeplan/3
routeplan(selly_oak, aston, [selly_oak, edgbaston, aston]).
Hm, if I understand you correctly you just want to format the list nicely for printing out, no?
In SWI-Prolog this works:
output_string([A,B],StrIn,StrOut) :-
concat_atom([StrIn, 'Finally, Go from ', A, ' to ', B, '.'],StrOut),
write(StrOut).
output_string([A,B|Rest],StrIn,StrOut) :-
concat_atom([StrIn,'Go from ', A, ' to ', B, '.\n'],StrAB),
output_string([B|Rest],StrAB,StrOut).
then call with
output_string(P,'',_).
It's probably not very efficient, but it does the job. :)
For this sort of thing, I usually create shell predicates. So in your case...
guided:-
print('Enter your start point'),nl,
read(Start),
print('Enter your destination'),nl,
read(Dest),
routeplan(Start, Dest, Route),
print_route(Route).
And print_route/1 could be something recursive like this:
print_route([]).
print_route([[A,B,Method]|Tail]):-
print_route(Tail),
print('Go from '), print(A),
print(' to '), print(B),
print(' by '), print(Method), nl.
I've assumed that the 3rd variable of the routeplan/3 predicate is a list of lists. Also that it's built by adding to the tail. If it's not, it should be fairly easy to adapt. Ask in the comments.
Here are a few predicates to read lines from a file/stream into a Prolog string:
%%% get_line(S, CL): CL is the string read up to the end of the line from S.
%%% If reading past end of file, returns 'end_of_file' in CL first, raises
%%% an exception second time.
%%% :- pred get_string(+stream, -list(int)).
get_line(S, CL) :-
peek_code(S, C),
( C = -1
-> get_code(S, _),
CL = end_of_file
; get_line(S, C, CL)).
get_line(_, -1, CL) :- !, CL = []. % leave end of file mark on stream
get_line(S, 0'\n, CL) :- !,
get_code(S, _),
CL = [].
get_line(S, C, [C|CL]) :-
get_code(S, _),
peek_code(S, NC),
get_line(S, NC, CL).
%% read_lines(L): reads lines from current input to L. L is a list of list
%% of character codes, newline characters are not included.
%% :- pred read_lines(-list(list(char))).
read_lines(L) :-
current_input(In),
get_line(In, L0),
read_lines(In, L0, L).
%% read_lines(F, L): reads lines from F to L. L is a list of list of character
%% codes, newline characters are not included.
%% :- pred read_lines(+atom, -list(list(char))).
read_lines(F, L) :-
fail_on_error(open(F, read, S)),
call_cleanup((get_line(S, L0),
read_lines(S, L0, L)),
close(S)).
read_lines(_, end_of_file, L) :- !, L = [].
read_lines(S, H, [H|T]) :-
get_line(S, NH),
read_lines(S, NH, T).
Then, take a look at DCGs for information on how to parse a string.

Resources