declare
[HTTPClient] = {Module.link ['x-ozlib://mesaros/net/HTTPClient.ozf']}
[StringX] = {Module.link ['x-oz://system/String.ozf']}
[Regex] = {Module.link ['x-oz://contrib/regex']}
%% Displays page 1 and 3 of the search results.
%% The user can request and display more with context menu->Actions->Make Needed.
proc {ExampleUsage}
Pages = {YahooSearch "Rosetta code"}
in
{Inspector.configure widgetShowStrings true}
{ForAll {Nth Pages 1} Value.makeNeeded}
{ForAll {Nth Pages 3} Value.makeNeeded}
%% Display the infinite list of search result pages.
{Inspect Pages}
end
%% Returns a lazy list of pages.
%% A page is a lazy list of entries like this: result(url:U title:T content:C).
fun {YahooSearch Query}
FetchURL = {CreateURLFetcher}
fun {Page Nr}
StartResult = (Nr-1)*10+1
%% only retrieve it when really needed
Doc = {Value.byNeed fun {$}
{FetchURL "http://search.yahoo.com/search"
["p"#Query "b"#{Int.toString StartResult}]}
end}
RE = "" R1 R2}
Title = {Fix {Until "" R2 R3}}
{Const "" R3 R4}
choice
%% "enchanted" result?
{Const "
" R4 R5}
{Until "
" R5 R6 _}
[] %% result with links into document
{Const "" R4 R5}
{Until "
" R5 R6 _}
[] %% PDF file
{Const "" R4 R5}
{Until "
" R5 R6 _}
[] %% With Review
{Const "" R4 R5}
R6 = nil %% no nice abstract when a review is there
[] %% normal result
R6 = R4
end
Abstract =
choice
{Const "
" R6 R7}
{Fix {Until "
" R7 _}}
[] {Const "
" R6 R7}
{Fix {Until "
" R7 _}}
[] ""
end
in
Root = result(url:Url title:Title content:Abstract)
end
in
{CondSelect {SearchOne Parse} 1 parseError}
end
%% Result: contents of Xs until M is found.
%% Xs = {Append M Yr}
fun {Until M Xs ?Yr}
L R
in
{List.takeDrop Xs {Length M} L R}
if L == M then Yr = R nil
elsecase Xs of X|Xr then X|{Until M Xr Yr}
[] nil then Yr = nil nil
end
end
%% Asserts that Xs starts with C. Returns the remainder in Ys.
proc {Const C Xs ?Ys}
{List.takeDrop Xs {Length C} C Ys}
end
%% Assert that a quoted string follows.
%% Returns the unquoted string and binds Ys to the remainder of Xs.
fun {QuotedString &"|Xs ?Ys}
fun {Loop Xs Ys}
case Xs of &\\|&"|Xr then &\\|&"|{Loop Xr Ys}
[] &"|Xr then Ys = Xr nil
[] X|Xr then X|{Loop Xr Ys}
end
end
in
{Loop Xs Ys}
end
%% Remove formatting tags.
fun {Fix Xs}
{Until ""
{FoldL ["
" "" "
" "
" "..."]
fun {$ Ys Z}
{StringX.replace Ys Z ""}
end
Xs}
_}
end
in
{ExampleUsage}