Starting a web browser: Difference between revisions
m (→{{header|Phix}}: syntax coloured, marked p2js incompatible) |
|||
Line 1,036: | Line 1,036: | ||
</div> |
</div> |
||
=={{header|VBScript}}== |
|||
<lang vb> |
|||
CreateObject("WScript.Shell").run("https://rosettacode.org") |
|||
</lang> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{libheader|Wren-pattern}} |
{{libheader|Wren-pattern}} |
Revision as of 09:22, 23 July 2022
Build and show a web page displaying the data from the task separate the house number from the street name in a formatted and colored table.
- Task
Write the code which automatically opens a web page in a browser showing the addresses. No static data must be shown, only processed data.
EchoLisp
Since we are already in a browser window, the browser is started. print-hatml sends an html string to the standard output area. The table is styled with the "htable" css class, which is included in EchoLisp. <lang scheme>
- table from "Separate_the_house_number_from_the_street_name"
(print-html (table->html adresses)) </lang>
- Output:
Plataanstraat | 5 |
Straat | 12 |
Straat | 12 II |
Straat 1940 | II |
Dr. J. Straat | 40 |
Dr. J. Straat | 12 a |
Dr. J. Straat | 12-14 |
Laan 1940 – 1945 | 37 |
Plein 1940 | 2 |
1213-laan | 11 |
16 april | 1944 Pad 1 |
1e Kruisweg | 36 |
Laan 1940-'45 | 66 |
Laan '40-'45 | ❓❓❓ |
Langeloërduinen | 3 46 |
Marienwaerdt | 2e Dreef 2 |
Provincialeweg N205 | 1 |
Rivium | 2e Straat 59. |
Nieuwe gracht | 20rd |
Nieuwe gracht | 20rd 2 |
Nieuwe gracht | 20zw /2 |
Nieuwe gracht | 20zw/3 |
Nieuwe gracht | 20 zw/4 |
Bahnhofstr. | 4 |
Wertstr. | 10 |
Lindenhof | 1 |
Nordesch | 20 |
Weilstr. | 6 |
Harthauer Weg | 2 |
Mainaustr. | 49 |
August-Horch-Str. | 3 |
Marktplatz | 31 |
Schmidener Weg | 3 |
Karl-Weysser-Str. | 6 |
Go
This uses the same format and color scheme for the table as the Raku entry. <lang go>package main
import (
"fmt" "html/template" "log" "os" "os/exec" "strings" "time"
)
type row struct {
Address, Street, House, Color string
}
func isDigit(b byte) bool {
return '0' <= b && b <= '9'
}
func separateHouseNumber(address string) (street string, house string) {
length := len(address) fields := strings.Fields(address) size := len(fields) last := fields[size-1] penult := fields[size-2] if isDigit(last[0]) { isdig := isDigit(penult[0]) if size > 2 && isdig && !strings.HasPrefix(penult, "194") { house = fmt.Sprintf("%s %s", penult, last) } else { house = last } } else if size > 2 { house = fmt.Sprintf("%s %s", penult, last) } street = strings.TrimRight(address[:length-len(house)], " ") return
}
func check(err error) {
if err != nil { log.Fatal(err) }
}
var tmpl = ` <head>
<title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8">
</head> <body bgcolor="#d8dcd6">
Split the house number from the street name
Template:Range $row := .Template:End
Address | Street | House Number |
---|---|---|
Template:$row.Address | Template:$row.Street | Template:$row.House |
</body> ` func main() {
addresses := []string{ "Plataanstraat 5", "Straat 12", "Straat 12 II", "Dr. J. Straat 12", "Dr. J. Straat 12 a", "Dr. J. Straat 12-14", "Laan 1940 - 1945 37", "Plein 1940 2", "1213-laan 11", "16 april 1944 Pad 1", "1e Kruisweg 36", "Laan 1940-'45 66", "Laan '40-'45", "Langeloërduinen 3 46", "Marienwaerdt 2e Dreef 2", "Provincialeweg N205 1", "Rivium 2e Straat 59.", "Nieuwe gracht 20rd", "Nieuwe gracht 20rd 2", "Nieuwe gracht 20zw /2", "Nieuwe gracht 20zw/3", "Nieuwe gracht 20 zw/4", "Bahnhofstr. 4", "Wertstr. 10", "Lindenhof 1", "Nordesch 20", "Weilstr. 6", "Harthauer Weg 2", "Mainaustr. 49", "August-Horch-Str. 3", "Marktplatz 31", "Schmidener Weg 3", "Karl-Weysser-Str. 6", } browser := "firefox" // or whatever colors := [2]string{"#d7fffe", "#9dbcd4"} fileName := "addresses_table.html" ct := template.Must(template.New("").Parse(tmpl)) file, err := os.Create(fileName) check(err) rows := make([]row, len(addresses)) for i, address := range addresses { street, house := separateHouseNumber(address) if house == "" { house = "(none)" } color := colors[i%2] rows[i] = row{address, street, house, color} } err = ct.Execute(file, rows) check(err) cmd := exec.Command(browser, fileName) err = cmd.Run() check(err) file.Close() time.Sleep(5 * time.Second) // wait for 5 seconds before deleting file err = os.Remove(fileName) check(err)
}</lang>
- Output:
Similar to the Raku entry.
Julia
<lang julia>using Tables, BrowseTables
function testbrowsertable(addresstext)
lines = strip.(split(addresstext, "\n")) mat = fill("", length(lines), 2) regex = r"""^ (.*?) \s+ ( \d* (\-|\/)? \d* | \d{1,3} [a-zI./ ]* \d{0,3} ) $"""x for (i, line) in enumerate(lines) if (matched = match(regex, line)) != nothing mat[i, 1], mat[i, 2] = matched.captures end end data = Tables.table(mat) tmp = tempname() * ".html" write_html_table(tmp, data) if Sys.isapple() run(`open $tmp`) elseif Sys.iswindows() run(`cmd /c start $tmp`) else # linux etc. run(`xdg-open $tmp`) end println("Press Enter after you close the browser to exit and remove temp file.") readline() rm(tmp)
end
const adressen = """
Plataanstraat 5 Straat 12 Straat 12 II Dr. J. Straat 12 Dr. J. Straat 12 a Dr. J. Straat 12-14 Laan 1940 – 1945 37 Plein 1940 2 1213-laan 11 16 april 1944 Pad 1 1e Kruisweg 36 Laan 1940-’45 66 Laan ’40-’45 Langeloërduinen 3 46 Marienwaerdt 2e Dreef 2 Provincialeweg N205 1 Rivium 2e Straat 59. Nieuwe gracht 20rd Nieuwe gracht 20rd 2 Nieuwe gracht 20zw /2 Nieuwe gracht 20zw/3 Nieuwe gracht 20 zw/4 Bahnhofstr. 4 Wertstr. 10 Lindenhof 1 Nordesch 20 Weilstr. 6 Harthauer Weg 2 Mainaustr. 49 August-Horch-Str. 3 Marktplatz 31 Schmidener Weg 3 Karl-Weysser-Str. 6"""
testbrowsertable(adressen) </lang>
Nim
Based on Phix solution. Using same colors as Scala program.
<lang Nim>import os, strutils
func separateHouseNumber(address: string): tuple[street, house: string] =
let fields = address.splitWhitespace() let last = fields[^1] let penult = fields[^2] if last[0].isDigit(): let isdig = penult[0].isDigit() if fields.len > 2 and isdig and not penult.startsWith("194"): result.house = penult & ' ' & last else: result.house = last elif fields.len > 2: result.house = penult & ' ' & last result.street = address[0..address.high-result.house.len].strip(leading = false, trailing = true)
const
Addresses = ["Plataanstraat 5", "Straat 12", "Straat 12 II", "Dr. J. Straat 12", "Dr. J. Straat 12 a", "Dr. J. Straat 12-14", "Laan 1940 - 1945 37", "Plein 1940 2", "1213-laan 11", "16 april 1944 Pad 1", "1e Kruisweg 36", "Laan 1940-'45 66", "Laan '40-'45", "Langeloërduinen 3 46", "Marienwaerdt 2e Dreef 2", "Provincialeweg N205 1", "Rivium 2e Straat 59.", "Nieuwe gracht 20rd", "Nieuwe gracht 20rd 2", "Nieuwe gracht 20zw /2", "Nieuwe gracht 20zw/3", "Nieuwe gracht 20 zw/4", "Bahnhofstr. 4", "Wertstr. 10", "Lindenhof 1", "Nordesch 20", "Weilstr. 6", "Harthauer Weg 2", "Mainaustr. 49", "August-Horch-Str. 3", "Marktplatz 31", "Schmidener Weg 3", "Karl-Weysser-Str. 6"]
HtmlHeader = """ <html> <head> <title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8"> </head> <body bgcolor="#e6e6ff">
Split the house number from the street name
"""HtmlLine = ""
HtmlFooter = """
Address | Street | House Number |
---|---|---|
$# | $# | $# |
</body> </html> """
let htmlFile = open("test.html", fmWrite) htmlFile.write HtmlHeader for i, address in Addresses:
let color = if (i and 1) == 0: "#ebf1de" else: "#d8e4bc" let (street, house) = address.separateHouseNumber() htmlFile.write HtmlLine.format(color, address, street, house)
htmlFile.write HtmlFooter htmlFile.close()
discard execShellCmd("firefox test.html") os.sleep(5000) removeFile("test.html")</lang>
- Output:
Same as Phix with Scala colors.
Perl
Borrowing code from the Separate the house number from the street name task.
<lang perl>use File::Temp qw(tempfile);
my @addresses = ( 'Plataanstraat 5', 'Straat 12', 'Straat 12 II', 'Dr. J. Straat 12', 'Dr. J. Straat 12 a', 'Dr. J. Straat 12-14', 'Laan 1940 – 1945 37', 'Plein 1940 2', '1213-laan 11', '16 april 1944 Pad 1', '1e Kruisweg 36', 'Laan 1940-’45 66', 'Laan ’40-’45', 'Langeloërduinen 3 46', 'Marienwaerdt 2e Dreef 2', 'Provincialeweg N205 1', 'Rivium 2e Straat 59.', 'Nieuwe gracht 20rd', 'Nieuwe gracht 20rd 2', 'Nieuwe gracht 20zw /2', 'Nieuwe gracht 20zw/3', 'Nieuwe gracht 20 zw/4', 'Bahnhofstr. 4', 'Wertstr. 10', 'Lindenhof 1', 'Nordesch 20', 'Weilstr. 6', 'Harthauer Weg 2', 'Mainaustr. 49', 'August-Horch-Str. 3', 'Marktplatz 31', 'Schmidener Weg 3', 'Karl-Weysser-Str. 6');
my @row_color = ('#d7fffe', '#9dbcd4');
- build the table
sub genTable {
my $table = '
' . qq|\n|;my $i = 0; for my $addr (@addresses) {$table .= qq||;
my($street,$number) = $addr =~ m[^ (.*?) \s+ ( \d* (\-|\/)? \d* | \d{1,3} [a-zI./ ]* \d{0,3} ) $ ]x; if (!$number) { $street = $addr; $number = '(no match)' }$table .= qq|\n|;
}return $table . '
Address | Street | House Number |
---|---|---|
$addr | $street | $number |
';
}
my $streets_and_numbers = genTable();
- generate the page content
sub content { return <<END; <html> <head> <title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8"> </head> <body bgcolor="#d8dcd6">
Split the house number from the street name
$streets_and_numbers
</body> </html> END }
- Use a temporary file name and file handle
my ($fn, $fh) = tempfile :suffix('.html');
- dump the content to the file
open my $fh, '>', $fn; print $fh content(); close $fh;
- use appropriate command for X11 (other systems will need different invocation)
my $command = "xdg-open $fn";
- start the browser
system "$command";
- wait for a bit to give browser time to load before destroying temp file
sleep 5; </lang>
- Output:
Address | Street | House Number |
---|---|---|
Plataanstraat 5 | Plataanstraat | 5 |
Straat 12 | Straat | 12 |
Straat 12 II | Straat | 12 II |
Dr. J. Straat 12 | Dr. J. Straat | 12 |
Dr. J. Straat 12 a | Dr. J. Straat | 12 a |
Dr. J. Straat 12-14 | Dr. J. Straat | 12-14 |
Laan 1940 – 1945 37 | Laan 1940 – 1945 | 37 |
Plein 1940 2 | Plein 1940 | 2 |
1213-laan 11 | 1213-laan | 11 |
16 april 1944 Pad 1 | 16 april 1944 Pad | 1 |
1e Kruisweg 36 | 1e Kruisweg | 36 |
Laan 1940-’45 66 | Laan 1940-’45 | 66 |
Laan ’40-’45 | Laan ’40-’45 | (no match) |
Langeloërduinen 3 46 | Langeloërduinen | 3 46 |
Marienwaerdt 2e Dreef 2 | Marienwaerdt 2e Dreef | 2 |
Provincialeweg N205 1 | Provincialeweg N205 | 1 |
Rivium 2e Straat 59. | Rivium 2e Straat | 59. |
Nieuwe gracht 20rd | Nieuwe gracht | 20rd |
Nieuwe gracht 20rd 2 | Nieuwe gracht | 20rd 2 |
Nieuwe gracht 20zw /2 | Nieuwe gracht | 20zw /2 |
Nieuwe gracht 20zw/3 | Nieuwe gracht | 20zw/3 |
Nieuwe gracht 20 zw/4 | Nieuwe gracht | 20 zw/4 |
Bahnhofstr. 4 | Bahnhofstr. | 4 |
Wertstr. 10 | Wertstr. | 10 |
Lindenhof 1 | Lindenhof | 1 |
Nordesch 20 | Nordesch | 20 |
Weilstr. 6 | Weilstr. | 6 |
Harthauer Weg 2 | Harthauer Weg | 2 |
Mainaustr. 49 | Mainaustr. | 49 |
August-Horch-Str. 3 | August-Horch-Str. | 3 |
Marktplatz 31 | Marktplatz | 31 |
Schmidener Weg 3 | Schmidener Weg | 3 |
Karl-Weysser-Str. 6 | Karl-Weysser-Str. | 6 |
Phix
without js -- (file i/o, system) constant addresses = {"Plataanstraat 5", "Straat 12", "Straat 12 II", "Dr. J. Straat 12", "Dr. J. Straat 12 a", "Dr. J. Straat 12-14", "Laan 1940 - 1945 37", "Plein 1940 2", "1213-laan 11", "16 april 1944 Pad 1", "1e Kruisweg 36", "Laan 1940-'45 66", "Laan '40-'45", "Langeloërduinen 3 46", "Marienwaerdt 2e Dreef 2", "Provincialeweg N205 1", "Rivium 2e Straat 59.", "Nieuwe gracht 20rd", "Nieuwe gracht 20rd 2", "Nieuwe gracht 20zw /2", "Nieuwe gracht 20zw/3", "Nieuwe gracht 20 zw/4", "Bahnhofstr. 4", "Wertstr. 10", "Lindenhof 1", "Nordesch 20", "Weilstr. 6", "Harthauer Weg 2", "Mainaustr. 49", "August-Horch-Str. 3", "Marktplatz 31", "Schmidener Weg 3", "Karl-Weysser-Str. 6"} function isDigit(integer ch) return ch>='0' and ch<='9' end function function separateHouseNumber(integer i) string address = addresses[i] sequence parts = split(address) string street, house integer h = 0 if length(parts)>1 then string last = parts[$] if isDigit(last[1]) then h = 1 string penult = parts[$-1] if length(parts)>2 and isDigit(penult[1]) and match("194",penult)!=1 then h = 2 end if elsif length(parts)>2 then h = 2 end if end if if h then street = join(parts[1..$-h]) house = join(parts[$-h+1..$]) else street = join(parts) house = "(none)" end if string colour = iff(mod(i,2)=0?"#d7fffe":"#9dbcd4") return {colour,address,street,house} end function constant html_hdr = """ <html> <head> <title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8"> </head> <body bgcolor="#d8dcd6"> <p align="center"> <font face="Arial, sans-serif" size="5">Split the house number from the street name</font> </p> <p align="center"> <table border="2"> <tr bgcolor="#02ccfe"> <th>Address</th><th>Street</th><th>House Number</th> """, html_line = """ <tr bgcolor=%s><td>%s</td><td>%s</td><td>%s</td></tr> """, html_ftr = """ </table> </p> </body> </html> """ procedure main() integer fn = open("test.html","w") printf(fn,html_hdr) for i=1 to length(addresses) do printf(fn,html_line,separateHouseNumber(i)) end for printf(fn,html_ftr) close(fn) system("test.html") end procedure main()
output as perl
Racket
<lang racket>
- lang at-exp racket
... same code as "Separate_the_house_number_from_the_street_name" ...
(require net/sendurl scribble/html)
(define (render-table)
(for/list ([str (in-list (string-split adressen #rx" *\r?\n *"))] [i (in-naturals)]) (tr bgcolor: (if (even? i) "#fcf" "#cff") (td str) (map td (cond [(splits-adressen str) => cdr] [else '(??? ???)])))))
@(compose1 send-url/contents xml->string){
@html{@head{@title{Splitting Results}} @body{@h1{Splitting Results} @table{@render-table}}}
} </lang>
Raku
(formerly Perl 6)
Uses the code from the Separate the house number from the street name task almost verbatim. Included here to make a complete, runnable example.
<lang perl6>use File::Temp;
my $addresses = qq :to /END/;
Plataanstraat 5 Straat 12 Straat 12 II Dr. J. Straat 12 Dr. J. Straat 12 a Dr. J. Straat 12-14 Laan 1940 – 1945 37 Plein 1940 2 1213-laan 11 16 april 1944 Pad 1 1e Kruisweg 36 Laan 1940-’45 66 Laan ’40-’45 Langeloërduinen 3 46 Marienwaerdt 2e Dreef 2 Provincialeweg N205 1 Rivium 2e Straat 59. Nieuwe gracht 20rd Nieuwe gracht 20rd 2 Nieuwe gracht 20zw /2 Nieuwe gracht 20zw/3 Nieuwe gracht 20 zw/4 Bahnhofstr. 4 Wertstr. 10 Lindenhof 1 Nordesch 20 Weilstr. 6 Harthauer Weg 2 Mainaustr. 49 August-Horch-Str. 3 Marktplatz 31 Schmidener Weg 3 Karl-Weysser-Str. 6 END
my @row-color = '#d7fffe', '#9dbcd4';
- build the table
sub genTable () {
my $table = '
' ~ qq|\n|;my $i = 0; for $addresses.lines -> $addr {$table ~= qq||;
$addr ~~ m[ ( .*? ) [ \s+ ( | \d+ [ \- | \/ ] \d+ | <!before 1940 | 1945> \d+ <[ a..z I . / \x20 ]>* \d* ) ]? $ ];quietly $table ~= qq|\n|;
}$table ~ '
Address | Street | House Number |
---|---|---|
{$addr} | {$0.Str} | {$1.Str||} |
';
}
- generate the page content
sub content {
qq :to /END/; <html> <head> <title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8"> </head> <body bgcolor="#d8dcd6">
Split the house number from the street name
{ genTable }
</body> </html> END
}
- Use a temporary file name and file handle
my ($fn, $fh) = tempfile :suffix('.html');
- dump the content to the file
$fh.spurt: content;
- use appropriate command for Windows or X11
- other OSs/WMs may need different invocation
my $command = $*DISTRO.is-win ?? "start $fn" !! "xdg-open $fn";
- start the browser
shell $command;
- wait for a bit to give browser time to load before destroying temp file
sleep 5; </lang>
- Output:
Will start the default browser (or open a new tab/window in a running one) and display this table.
Address | Street | House Number |
---|---|---|
Plataanstraat 5 | Plataanstraat | 5 |
Straat 12 | Straat | 12 |
Straat 12 II | Straat | 12 II |
Dr. J. Straat 12 | Dr. J. Straat | 12 |
Dr. J. Straat 12 a | Dr. J. Straat | 12 a |
Dr. J. Straat 12-14 | Dr. J. Straat | 12-14 |
Laan 1940 – 1945 37 | Laan 1940 – 1945 | 37 |
Plein 1940 2 | Plein 1940 | 2 |
1213-laan 11 | 1213-laan | 11 |
16 april 1944 Pad 1 | 16 april 1944 Pad | 1 |
1e Kruisweg 36 | 1e Kruisweg | 36 |
Laan 1940-’45 66 | Laan 1940-’45 | 66 |
Laan ’40-’45 | Laan ’40-’45 | |
Langeloërduinen 3 46 | Langeloërduinen | 3 46 |
Marienwaerdt 2e Dreef 2 | Marienwaerdt 2e Dreef | 2 |
Provincialeweg N205 1 | Provincialeweg N205 | 1 |
Rivium 2e Straat 59. | Rivium 2e Straat | 59. |
Nieuwe gracht 20rd | Nieuwe gracht | 20rd |
Nieuwe gracht 20rd 2 | Nieuwe gracht | 20rd 2 |
Nieuwe gracht 20zw /2 | Nieuwe gracht | 20zw /2 |
Nieuwe gracht 20zw/3 | Nieuwe gracht | 20zw/3 |
Nieuwe gracht 20 zw/4 | Nieuwe gracht | 20 zw/4 |
Bahnhofstr. 4 | Bahnhofstr. | 4 |
Wertstr. 10 | Wertstr. | 10 |
Lindenhof 1 | Lindenhof | 1 |
Nordesch 20 | Nordesch | 20 |
Weilstr. 6 | Weilstr. | 6 |
Harthauer Weg 2 | Harthauer Weg | 2 |
Mainaustr. 49 | Mainaustr. | 49 |
August-Horch-Str. 3 | August-Horch-Str. | 3 |
Marktplatz 31 | Marktplatz | 31 |
Schmidener Weg 3 | Schmidener Weg | 3 |
Karl-Weysser-Str. 6 | Karl-Weysser-Str. | 6 |
Scala
Uses nothing but the Standard Library: <lang scala>import java.awt.Desktop import java.io.{IOException, PrintWriter} import java.net.{URI, ServerSocket} import scala.xml.Elem
class WebServer(port: Int, soleDocument: Elem) extends Thread {
this.setName(s"Server at $port")
override def run() { val listener = try { new ServerSocket(port) } catch { case e: java.net.BindException => throw new IllegalStateException(s"Port $port already taken!") } println(s"Listening on port ${listener.getLocalPort}")
while (!Thread.interrupted()) { try { //print(".") val socket = listener.accept new PrintWriter(socket.getOutputStream, true).println(soleDocument) socket.close() } catch { case ioe: IOException => println(ioe) } } }
} // class WebServer
object HtmlServer extends App {
val PORT = 64507 // Main val thread = new WebServer(PORT, HtmlBuilder) val uri = URI.create(s"http://localhost:$PORT/") thread.start()
def HtmlBuilder: Elem = { def adressen: Iterator[String] = """Plataanstraat 5 |Straat 12 |Straat 12 II |Straat 1940 II |Dr. J. Straat 40 |Dr. J. Straat 12 a |Dr. J. Straat 12-14 |Laan 1940 – 1945 37 |Plein 1940 2 |1213-laan 11 |16 april 1944 Pad 1 |1e Kruisweg 36 |Laan 1940-’45 66 |Laan ’40-’45 |Langeloërduinen 3 46 |Marienwaerdt 2e Dreef 2 |Provincialeweg N205 1 |Rivium 2e Straat 59. |Nieuwe gracht 20rd |Nieuwe gracht 20rd 2 |Nieuwe gracht 20zw /2 |Nieuwe gracht 20zw/3 |Nieuwe gracht 20 zw/4 |Bahnhofstr. 4 |Wertstr. 10 |Lindenhof 1 |Nordesch 20 |Weilstr. 6 |Harthauer Weg 2 |Mainaustr. 49 |August-Horch-Str. 3 |Marktplatz 31 |Schmidener Weg 3 |Karl-Weysser-Str. 6""".stripMargin.lines
def getSplittedAddresses(addresses: Iterator[String]) = { val extractor = new scala.util.matching.Regex( """(\s\d+[-/]\d+)|(\s(?!1940|1945)\d+[a-zI. /]*\d*)$|\d+\['][40|45]$""")
def splitsAdres(input: String): (String, String) = (extractor.split(input).mkString, extractor.findFirstIn(input).getOrElse(""))
addresses.map(org => { val temp = splitsAdres(org) List(org, temp._1, temp._2) }) }
def generateTable: Elem = {
def coloring(rownum: Any): String = { rownum match { case Nil => "#9bbb59" case n: Int => if (n % 2 == 0) "#ebf1de" else "#d8e4bc" } }{(List(List("Given Address", "Street", "House Number")) ++ getSplittedAddresses(adressen)). zipWithIndex.map { case (row, rownum) => (if (rownum == 0) Nil else rownum) +: row}.map(row => {row.map(cell => if (row.head == Nil) else )} )}
{cell} |
{cell} |
---|
} // def generateTable
<html> <head> <title>Rosetta.org Task solution</title> </head> <body lang="en-US" bgcolor="#e6e6ff" dir="LTR">
Split the house number from the street name
{generateTable}
</body> </html> } // def content if (Desktop.isDesktopSupported && Desktop.getDesktop.isSupported(Desktop.Action.BROWSE)) Desktop.getDesktop.browse(uri) else println(s"Automatic start of Web browser not possible.\nWeb browser must be started manually, use $uri.")
if (!thread.isAlive) sys.exit(-1) println("Web server started.") do print("Do you want to shutdown this server? <Y(es)/N>: ") while (!scala.io.StdIn.readBoolean) sys.exit()
}</lang>
- Output:
Split the house number from the street name
Given Address | Street | House Number | |
---|---|---|---|
1 | Plataanstraat 5 | Plataanstraat | 5 |
2 | Straat 12 | Straat | 12 |
3 | Straat 12 II | Straat | 12 II |
4 | Straat 1940 II | Straat 1940 II | |
5 | Dr. J. Straat40 | Dr. J. Straat | 40 |
6 | Dr. J. Straat 12 a | Dr. J. Straat | 12 a |
7 | Dr. J. Straat 12-14 | Dr. J. Straat | 12-14 |
8 | Laan 1940 – 1945 37 | Laan 1940 – 1945 | 37 |
9 | Plein 1940 2 | Plein 1940 | 2 |
10 | 1213-laan 11 | 1213-laan | 11 |
11 | 16 april 1944 Pad 1 | 16 april 1944 Pad | 1 |
12 | 1e Kruisweg 36 | 1e Kruisweg | 36 |
13 | Laan 1940-’45 66 | Laan 1940-’45 | 66 |
14 | Laan ’40-’45 | Laan ’40-’45 | |
15 | Langeloërduinen 3 46 | Langeloërduinen | 3 46 |
16 | Marienwaerdt 2e Dreef 2 | Marienwaerdt 2e Dreef | 2 |
17 | Provincialeweg N205 1 | Provincialeweg N205 | 1 |
18 | Rivium 2e Straat 59. | Rivium 2e Straat | 59. |
19 | Nieuwe gracht 20rd | Nieuwe gracht | 20rd |
20 | Nieuwe gracht 20rd 2 | Nieuwe gracht | 20rd 2 |
21 | Nieuwe gracht 20zw /2 | Nieuwe gracht | 20zw /2 |
22 | Nieuwe gracht 20zw/3 | Nieuwe gracht | 20zw/3 |
23 | Nieuwe gracht 20 zw/4 | Nieuwe gracht | 20 zw/4 |
24 | Bahnhofstr. 4 | Bahnhofstr. | 4 |
25 | Wertstr. 10 | Wertstr. | 10 |
26 | Lindenhof 1 | Lindenhof | 1 |
27 | Nordesch 20 | Nordesch | 20 |
28 | Weilstr. 6 | Weilstr. | 6 |
29 | Harthauer Weg 2 | Harthauer Weg | 2 |
30 | Mainaustr. 49 | Mainaustr. | 49 |
31 | August-Horch-Str. 3 | August-Horch-Str. | 3 |
32 | Marktplatz 31 | Marktplatz | 31 |
33 | Schmidener Weg 3 | Schmidener Weg | 3 |
34 | Karl-Weysser-Str. 6 | Karl-Weysser-Str. | 6 |
Tcl
<lang tcl>package require Tcl 8.6
- This is identical to the address task. Skip forward to the next section...
proc split_DE_NL_address {streetAddress} {
set RE {(?x)
^ (.*?) ( (?:\s \d+ [-/] \d+) | (?:\s (?!1940|1945)\d+ [a-zI. /]* \d*) )? $
} regexp $RE $streetAddress -> str num return [list [string trim $str] [string trim $num]]
}
set data {
Plataanstraat 5 Straat 12 Straat 12 II Dr. J. Straat 12 Dr. J. Straat 12 a Dr. J. Straat 12-14 Laan 1940 – 1945 37 Plein 1940 2 1213-laan 11 16 april 1944 Pad 1 1e Kruisweg 36 Laan 1940-’45 66 Laan ’40-’45 Langeloërduinen 3 46 Marienwaerdt 2e Dreef 2 Provincialeweg N205 1 Rivium 2e Straat 59. Nieuwe gracht 20rd Nieuwe gracht 20rd 2 Nieuwe gracht 20zw /2 Nieuwe gracht 20zw/3 Nieuwe gracht 20 zw/4 Bahnhofstr. 4 Wertstr. 10 Lindenhof 1 Nordesch 20 Weilstr. 6 Harthauer Weg 2 Mainaustr. 49 August-Horch-Str. 3 Marktplatz 31 Schmidener Weg 3 Karl-Weysser-Str. 6
}
- Construct the HTML to show
set html "<html><head><meta charset=\"UTF-8\"> <title>split_DE_NL_address</title></head><body>
"foreach streetAddress [split $data "\n"] {
set streetAddress [string trim $streetAddress] if {$streetAddress eq ""} continue lassign [split_DE_NL_address $streetAddress] str numappend html ""
}
append html "Address | Street | Number |
---|---|---|
$streetAddress | $str | $num |
</body></html>"
- Pick a unique filename with .html extension (important!)
set f [file tempfile filename street.html] fconfigure $f -encoding utf-8 puts $f $html close $f
- THE WEB BROWSER LAUNCH CODE MAGIC #####
- Relies on the default registration of browsers for .html files
- This is all very platform specific; Android requires another incantation again
if {$tcl_platform(platform) eq "windows"} {
exec {*}[auto_execok start] "" [file nativename $filename]
} elseif {$tcl_platform(os) eq "Darwin"} {
exec open $filename
} else {
exec xdg_open $filename
}</lang>
- Output:
Address | Street | Number |
---|---|---|
Plataanstraat 5 | Plataanstraat | 5 |
Straat 12 | Straat | 12 |
Straat 12 II | Straat | 12 II |
Dr. J. Straat 12 | Dr. J. Straat | 12 |
Dr. J. Straat 12 a | Dr. J. Straat | 12 a |
Dr. J. Straat 12-14 | Dr. J. Straat | 12-14 |
Laan 1940 – 1945 37 | Laan 1940 – 1945 | 37 |
Plein 1940 2 | Plein 1940 | 2 |
1213-laan 11 | 1213-laan | 11 |
16 april 1944 Pad 1 | 16 april 1944 Pad | 1 |
1e Kruisweg 36 | 1e Kruisweg | 36 |
Laan 1940-’45 66 | Laan 1940-’45 | 66 |
Laan ’40-’45 | Laan ’40-’45 | |
Langeloërduinen 3 46 | Langeloërduinen | 3 46 |
Marienwaerdt 2e Dreef 2 | Marienwaerdt 2e Dreef | 2 |
Provincialeweg N205 1 | Provincialeweg N205 | 1 |
Rivium 2e Straat 59. | Rivium 2e Straat | 59. |
Nieuwe gracht 20rd | Nieuwe gracht | 20rd |
Nieuwe gracht 20rd 2 | Nieuwe gracht | 20rd 2 |
Nieuwe gracht 20zw /2 | Nieuwe gracht | 20zw /2 |
Nieuwe gracht 20zw/3 | Nieuwe gracht | 20zw/3 |
Nieuwe gracht 20 zw/4 | Nieuwe gracht | 20 zw/4 |
Bahnhofstr. 4 | Bahnhofstr. | 4 |
Wertstr. 10 | Wertstr. | 10 |
Lindenhof 1 | Lindenhof | 1 |
Nordesch 20 | Nordesch | 20 |
Weilstr. 6 | Weilstr. | 6 |
Harthauer Weg 2 | Harthauer Weg | 2 |
Mainaustr. 49 | Mainaustr. | 49 |
August-Horch-Str. 3 | August-Horch-Str. | 3 |
Marktplatz 31 | Marktplatz | 31 |
Schmidener Weg 3 | Schmidener Weg | 3 |
Karl-Weysser-Str. 6 | Karl-Weysser-Str. | 6 |
VBScript
<lang vb> CreateObject("WScript.Shell").run("https://rosettacode.org") </lang>
Wren
An embedded program so we can ask the C host to open the browser for us after we've created the html file.
The Wren code is based in part on the Nim example and uses the same color scheme. <lang ecmascript>/* starting_web_browser.wren */
import "./pattern" for Pattern import "./fmt" for Fmt import "./trait" for Indexed
foreign class File {
foreign static remove(filename)
foreign static flushAll()
construct open(filename, mode) {}
foreign write(s)
foreign close()
}
class C {
foreign static system(s)
foreign static sleep(sec)
}
var digits = "0123456789" var p = Pattern.new("+1/s")
var separateHouseNumber = Fn.new { |address|
var len = address.count var splits = p.splitAll(address) var size = splits.count var last = splits[-1] var penult = splits[-2] var house if (digits.contains(last[0])) { if (size > 2 && digits.contains(penult[0]) && !penult.startsWith("194")) { house = penult + " " + last } else { house = last } } else if (size > 2) { house = penult + " " + last } else { house = "" } var street = address.take(len - house.count).join().trimEnd() return [street, house]
}
var addresses = [
"Plataanstraat 5", "Straat 12", "Straat 12 II", "Dr. J. Straat 12", "Dr. J. Straat 12 a", "Dr. J. Straat 12-14", "Laan 1940 - 1945 37", "Plein 1940 2", "1213-laan 11", "16 april 1944 Pad 1", "1e Kruisweg 36", "Laan 1940-'45 66", "Laan '40-'45", "Langeloërduinen 3 46", "Marienwaerdt 2e Dreef 2", "Provincialeweg N205 1", "Rivium 2e Straat 59.", "Nieuwe gracht 20rd", "Nieuwe gracht 20rd 2", "Nieuwe gracht 20zw /2", "Nieuwe gracht 20zw/3", "Nieuwe gracht 20 zw/4", "Bahnhofstr. 4", "Wertstr. 10", "Lindenhof 1", "Nordesch 20", "Weilstr. 6", "Harthauer Weg 2", "Mainaustr. 49", "August-Horch-Str. 3", "Marktplatz 31", "Schmidener Weg 3", "Karl-Weysser-Str. 6"
]
var htmlHeader = """ <html> <head> <title>Rosetta Code - Start a Web Browser</title> <meta charset="UTF-8"> </head> <body bgcolor="#e6e6ff">
Split the house number from the street name
"""
var htmlFooter = """
Address | Street | House Number |
---|
</body> </html> """
var htmlFile = File.open("test.html", "w") htmlFile.write(htmlHeader + "\n") for (se in Indexed.new(addresses)) {
var color = (se.index & 1 == 0) ? "#ebf1de" : "#d8e4bc" var address = se.value var res = separateHouseNumber.call(address) var street = res[0] var house = res[1] if (house == "") house = "(none)"
htmlFile.write("%(address)%(street)%(house)\n")
}
htmlFile.write(htmlFooter + "\n")
C.system("firefox test.html") // or whatever browser you use
File.flushAll() // flush all streams
C.sleep(5) // wait five seconds
File.remove("test.html") // remove the file</lang>
We now embed this in the following C program, compile and run it.
<lang c>/* gcc starting_web_browser.c -o starting_web_browser -lwren -lm */
- include <stdio.h>
- include <stdlib.h>
- include <string.h>
- include <unistd.h>
- include "wren.h"
/* C <=> Wren interface functions */
void C_fileAllocate(WrenVM* vm) {
FILE** pfp = (FILE**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(FILE*)); const char *filename = wrenGetSlotString(vm, 1); const char *mode = wrenGetSlotString(vm, 2); *pfp = fopen(filename, mode);
}
void C_write(WrenVM* vm) {
FILE* fp = *(FILE**)wrenGetSlotForeign(vm, 0); const char *s = wrenGetSlotString(vm, 1); fputs(s, fp);
}
void C_close(WrenVM* vm) {
FILE* fp = *(FILE**)wrenGetSlotForeign(vm, 0); fclose(fp);
}
void C_remove(WrenVM* vm) {
const char *filename = wrenGetSlotString(vm, 1); remove(filename);
}
void C_flushAll(WrenVM* vm) {
fflush(NULL);
}
void C_system(WrenVM* vm) {
const char *s = wrenGetSlotString(vm, 1); system(s);
}
void C_sleep(WrenVM* vm) {
int seconds = (int)wrenGetSlotDouble(vm, 1); sleep(seconds);
}
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods; methods.allocate = NULL; methods.finalize = NULL; if (strcmp(module, "main") == 0) { if (strcmp(className, "File") == 0) { methods.allocate = C_fileAllocate; } } return methods;
}
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) { if (strcmp(module, "main") == 0) { if (strcmp(className, "File") == 0) { if (!isStatic && strcmp(signature, "write(_)") == 0) return C_write; if (!isStatic && strcmp(signature, "close()") == 0) return C_close; if ( isStatic && strcmp(signature, "remove(_)") == 0) return C_remove; if ( isStatic && strcmp(signature, "flushAll()") == 0) return C_flushAll; } else if (strcmp(className, "C") == 0) { if ( isStatic && strcmp(signature, "system(_)") == 0) return C_system; if ( isStatic && strcmp(signature, "sleep(_)") == 0) return C_sleep; } } return NULL;
}
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) { case WREN_ERROR_COMPILE: printf("[%s line %d] [Error] %s\n", module, line, msg); break; case WREN_ERROR_STACK_TRACE: printf("[%s line %d] in %s\n", module, line, msg); break; case WREN_ERROR_RUNTIME: printf("[Runtime Error] %s\n", msg); break; }
}
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r"); fseek(f, 0, SEEK_END); long fsize = ftell(f); rewind(f); char *script = malloc(fsize + 1); fread(script, 1, fsize, f); fclose(f); script[fsize] = 0; return script;
}
static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
if( result.source) free((void*)result.source);
}
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0}; if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) { result.onComplete = loadModuleComplete; char fullName[strlen(name) + 6]; strcpy(fullName, name); strcat(fullName, ".wren"); result.source = readFile(fullName); } return result;
}
int main(int argc, char **argv) {
WrenConfiguration config; wrenInitConfiguration(&config); config.writeFn = &writeFn; config.errorFn = &errorFn; config.bindForeignClassFn = &bindForeignClass; config.bindForeignMethodFn = &bindForeignMethod; config.loadModuleFn = &loadModule; WrenVM* vm = wrenNewVM(&config); const char* module = "main"; const char* fileName = "starting_web_browser.wren"; char *script = readFile(fileName); WrenInterpretResult result = wrenInterpret(vm, module, script); switch (result) { case WREN_RESULT_COMPILE_ERROR: printf("Compile Error!\n"); break; case WREN_RESULT_RUNTIME_ERROR: printf("Runtime Error!\n"); break; case WREN_RESULT_SUCCESS: break; } wrenFreeVM(vm); free(script); return 0;
}</lang>
- Output:
Same as Nim.