HTML = HyperText Markup Language - språket som används för att skriva webbsidor.
"Markup": taggar som strukturerar texten.
En webbläsare (t.ex. Firefox) är ett program som tolkar HTML och visar texten genom att göra de saker som taggarna anger.
(Jfr. GHCi: det är ett program som tolkar Haskell)
Text med länkar till en ordbok
Den grundläggande strukturen i ett HTML-dokument finns i följande mall:
<html> <head><title>Head-titeln: texten överst i ramen</title></head> <body> Body: texten i textfältet. <h1>Huvudtitel</h1> <p> Paragraf, bestående av text och annat, t.ex. <a href="http://www.haskell.org">länkar till webbsidor</a>, <b>text i fetstil</b>, <i>text i kursiv</i>, <tt>text i maskinskrift</tt>, <font color="red">text i röd font</font>, bilder, som är länkar till bildfiler och kan skalas till önskad storlek (i nästa paragraf): </p> <p> <img width="132"src="didno.jpg"> </p> <h2>Lite mindre titel</h2> <p>Och så en tabell:</p> <table border="yes"> <tr> <td>A1</td> <td>A2</td> <td>A3</td> </tr> <tr> <td>B1</td> <td>B2</td> <td>B3</td> </tr> </table> </body> </html>
Klicka här för att se dokumentet i din webbläsare.
<html><head><title>Pictures</title></head> <body><table border="yes"><tr><td><a href="pictures/IMG_4922.jpg"><img src="pictures/IMG_4922.jpg" width="128"></a></td> <td><a href="pictures/IMG_4935.jpg"><img src="pictures/IMG_4935.jpg" width="128"></a></td> <td><a href="pictures/IMG_4944.jpg"><img src="pictures/IMG_4944.jpg" width="128"></a></td> <td><a href="pictures/IMG_4950.jpg"><img src="pictures/IMG_4950.jpg" width="128"></a></td> <td><a href="pictures/IMG_4955.jpg"><img src="pictures/IMG_4955.jpg" width="128"></a></td> </tr> <tr><td><a href="pictures/IMG_4956.jpg"><img src="pictures/IMG_4956.jpg" width="128"></a></td> <td><a href="pictures/IMG_4957.jpg"><img src="pictures/IMG_4957.jpg" width="128"></a></td> <td><a href="pictures/IMG_4966.jpg"><img src="pictures/IMG_4966.jpg" width="128"></a></td> <td><a href="pictures/IMG_4971.jpg"><img src="pictures/IMG_4971.jpg" width="128"></a></td> <td><a href="pictures/IMG_4974.jpg"><img src="pictures/IMG_4974.jpg" width="128"></a></td> </tr> <tr><td><a href="pictures/IMG_4999.jpg"><img src="pictures/IMG_4999.jpg" width="128"></a></td> <td><a href="pictures/IMG_5005.jpg"><img src="pictures/IMG_5005.jpg" width="128"></a></td> <td><a href="pictures/IMG_5029.jpg"><img src="pictures/IMG_5029.jpg" width="128"></a></td> <td><a href="pictures/IMG_5036.jpg"><img src="pictures/IMG_5036.jpg" width="128"></a></td> <td><a href="pictures/IMG_5037.jpg"><img src="pictures/IMG_5037.jpg" width="128"></a></td> </tr> <tr><td><a href="pictures/IMG_5043.jpg"><img src="pictures/IMG_5043.jpg" width="128"></a></td> <td><a href="pictures/IMG_5049.jpg"><img src="pictures/IMG_5049.jpg" width="128"></a></td> <td><a href="pictures/IMG_5059.jpg"><img src="pictures/IMG_5059.jpg" width="128"></a></td> <td><a href="pictures/IMG_5072.jpg"><img src="pictures/IMG_5072.jpg" width="128"></a></td> <td><a href="pictures/IMG_5081.jpg"><img src="pictures/IMG_5081.jpg" width="128"></a></td> </tr> <tr><td><a href="pictures/IMG_5091.jpg"><img src="pictures/IMG_5091.jpg" width="128"></a></td> <td><a href="pictures/IMG_5099.jpg"><img src="pictures/IMG_5099.jpg" width="128"></a></td> <td><a href="pictures/IMG_5106.jpg"><img src="pictures/IMG_5106.jpg" width="128"></a></td> <td><a href="pictures/IMG_5111.jpg"><img src="pictures/IMG_5111.jpg" width="128"></a></td> <td><a href="pictures/IMG_5112.jpg"><img src="pictures/IMG_5112.jpg" width="128"></a></td> </tr> <tr></tr> </table> </body></html>
Klicka här för att se dokumentet i din webbläsare.
Vill någon skriva sånt här?
Nej! Vi ska skriva ett Haskell-program som skriver HTML-filen.
Detta är ett exempel på generativ programmering: man skriver program som genererar program.
En tagg är text mellan <
och >
. Vi börjar med en funktion
som producerar en tagg
tag :: String -> String tag t = "<" ++ t ++ ">"
och motsvarande sluttagg:
endTag :: String -> String endTag t = tag ("/" ++ t)
De flesta HTML-elementen skapas genom att omsluta mindre element med en tagg och dess sluttagg:
tagged :: String -> HTML -> HTML tagged t h = tag t ++ h ++ endTag t
Till exempel fetstil:
bold :: HTML -> HTML bold h = tagged "b" h
Själva typen HTML? Vi nöjer oss med den enklaste möjliga,
type HTML = String
Alla dessa definitioner finns i biblioteket som har skapats för
den här föreläsningen och uppgifterna: MkHTML
:
Alla dessa finns i MkHTML
:
para :: HTML -> HTML para h = tagged "p" h header :: Int -> HTML -> HTML header i h = tagged ("h" ++ show i) h bold :: HTML -> HTML bold h = tagged "b" h italic :: HTML -> HTML italic h = tagged "i" h typewriter :: HTML -> HTML typewriter h = tagged "tt" h string :: String -> HTML string s = s list :: [HTML] -> HTML list hs = unlines hs
En tagg kan innehålla attribut, som ger extra information.
Exempel 1: en länk har URL:en (= Uniform Resource Locator, "webbadressen") som attribut:
<a href="http://www.haskell.org">Haskell Home</a>
Exempel 2: en bild har både bild-URL:en och valfria storleksattribut:
<img src="pictures/IMG_5091.jpg" width="128">
Obs: URL-attributet kan vara en fil på samma dator, som i bildexemplet.
Obs: sluttaggen har inga attribut.
Vi kan generalisera den tagg-skapande funktionen:
attrTag :: String -> [(String,String)] -> String attrTag t attrs = tag (t ++ " " ++ unwords [a ++"=" ++ "\"" ++ v ++ "\"" | (a,v) <- attrs])
Nu kan vi skriva
attrTagged :: String -> [(String,String)] -> HTML -> HTML attrTagged t attrs h = attrTag t attrs ++ h ++ endTag t
Och sedan:
link :: String -> HTML -> HTML link url txt = attrTagged "a" [("href",url)] txt image :: String -> Int -> HTML image url size = attrTag "img" [("src",url),("width", show size)]
Alla dessa finns i MkHTML
.
Dokumentet ska (oftast) ha formen
<html> <head> <title> Titeln </title> </head> <body> Innehållet </body> </html>
Vi skapar detta med
html :: String -> HTML -> HTML html hd bod = tagged "html" (headTitle (string hd) ++++ body bod) headTitle :: String -> HTML headTitle s = tagged "head" (tagged "title" s) body :: HTML -> HTML body h = tagged "body" h
Alla dessa finns i MkHTML
.
HTML-koden:
<html> <head> <title>Hello</title> </head> <body> Hello World </body> </html>
Haskell-koden
html "Hello" (string "Hello World")
I Haskell blir det mindre att skriva.
Och det blir inga syntaxfel t.ex. saknande sluttaggar.
HTML-koden:
<html> <head><title>Head-titeln: texten överst i ramen</title></head> <body> Body: texten i textfältet. <h1>Huvudtitel</h1> <p> Paragraf, bestaende av text och annat, t.ex. <a href="http://www.haskell.org">lankar till webbsidor</a>, <b>text i fetstil</b>, <i>text i kursiv</i>, <tt>text i maskinskrift</tt>, <font color="red">text i röd font</font>, bilder, som ar lankar till bildfiler och kan skalas till onskad storlek (i nästa paragraf): </p> <p> <img width="132"src="didno.jpg"> </p> <h2>Lite mindre titel</h2> </body> </html>
Haskell-koden:
html "Head-titeln: texten overst i ramen" (list [ string "Body: texten i textfaltet.", header 1 "Huvudtiteln", para (list [ string "Paragraf, bestaende av text och annat, t.ex.", link "http://www.haskell.org" "lankar till webbsidor", bold "text i fetstil", italic "text i kursiv", typewriter "text i maskinskrift", colored "red" "text i rod font", string "bilder, som ar lankar till bildfiler och kan skalas", string "till onskad storlek (i nasta paragraf):" ]), para (image "didno.jpg" 512), header 2 "Lite mindre titel" ])
Vi vinner knappast något med Haskell här...
En enkel tabell ser ut så här:
A1 | A2 | A3 | |
---|---|---|---|
B1 | B2 | B3 |
HTML-koden ser ut så här:
<table border="yes"> <tr> <td>A1</td> <td>A2</td> <td>A3</td> </tr> <tr> <td>B1</td> <td>B2</td> <td>B3</td> </tr> </table>
Vi vill kunna skapa tabellen med Haskell-koden
table [["A1","A2","A3"],["B1","B2","B3"]]
En tabell kan ses som en lista av listor.
Den yttre listan är raderna (<tr>
), de inre är cellerna (<td>
).
Vi kan så klart använda listkomprehension:
table :: [[HTML]] -> HTML table rows = attrTagged "table" [("border","yes")] (list [tagged "tr" (list [tagged "td" cell | cell <- row]) | row <- rows])
Funktionen finns även i MkHTML
Vi kan generera innehållet i tabellen med listkomprehension:
html "Fahrenheit to Celcius" (table [[show f, show (5*(f - 32)/9)] | f <- [0,20 .. 300]])
Resultatet finns här.
Vårt fotoalbum är en tabell där
Om pics
är listan av bildernas URL:er, kan vi generera albumet med
html "Pictures" (table (grid 5 [link pic (image pic 128) | pic <- pics]))
Funktionen grid
(finns i MkHTML
) styckar upp en lista
till dellistor av önskad längd:
grid :: Int -> [a] -> [[a]] grid i [] = [] grid i xs = take i xs : grid i (drop i xs)
Obs: grid
är en rekursiv funktion, dvs. den anropar sig själv.
Detta begrepp hör till nästa Haskell-kurs!
Vi har använt Unix-kommandot ls
:
ls pictures/*.jpg > pics
som gav oss alla filer i katalogen pictures
med namnsuffixen jpg
.
Dessa skrevs till filen pics
, som sedan lästes av en IO-funktion
så här:
mk_test5 :: IO () mk_test5 = do s <- readFile "pics" let pics = lines s let doc = html "Pictures" (table (grid 5 [link pic (image pic 128) | pic <- pics])) writeFile "test5.html" doc
Vi går inte genom detaljerna på den här kursen - men den här koden kan tillämpas till vilken som helst katalog med JPG-filer.
Om man går till Google och slår in ett sökord, t.ex. "haskell", öppnas en webbsida som har URL
http://www.google.se/search?&q=haskell
Från detta kan vi gissa en funktion
googled :: String -> HTML googled s = link ("http://www.google.se/search?&q=" ++ s) s
För att länka varje ord i en text till en Google-sökning används
googledText :: String -> HTML googledText s = unwords [googled w | w <- words s]
Som exempel på detta, skapar Haskell-koden
html "Google bakom lankarna" (googledText "Varje ord som klickas skickas till Google")
Vi har visat hur man skapar statiska sidor: de skapas en gång, läggs ut på nätet, och ändras inte automatiskt.
Dynamiska sidor: ett program skriver nya sidor t.ex. som svar till besökarnas frågor.
Google är ett typexempel.
Haskell är ett möjligt språk även för dynamisk webbprogrammering, se här.
Ett exempel med Haskell, GF och Google Web Toolkit: flerspråkiga kylskåpsmagneter.
De här föreläsningarna har skapats med txt2tags.
Källan till den här föreläsningen ser ut så här.
Fördelar:
Nackdelar:
Redovisning. Visa de resulterande HTML-sidorna i en webbläsare.
1. Skapa en HTML-fil som innehåller ditt namn och foto (om du har
ett digitalt; annars någon annan trevlig bild). och valfritt annat
material. Gör detta manuellt i HTML eller med en Haskell-funktion
genom att använda MkHTML.hs
.
2. Undersök hur man skapar söklänkar till Wikipedia och generera sedan en HTML-sida som innehåller en tabell med namnen på de 27 EU-länderna, med 3 länder på en rad. Varje land ska vara länkat till Wikipedia-artikeln om landet. Börja med att söka upp listan av EU-länderna på nätet. (Vi rekommenderar engelsk Wikipedia sör att slippa problemen med äåö.)
3. Skapa ett eget fotoalbum genom att återanvända funktionen mk_test5.html
i MkHTML.hs
. Albumet ska innehålla minst 15 bilder.
Tips: om du inte har egna digitala bilder, kan du
hitta sådana med Googles bildsökning.
4. Modifiera ordstatistikfunktionen i Freq.hs
(föreläsning 4)
så att den skriver ut de 100 vanligaste orden med antalet förekomster till
en tabell i en HTML-fil. I redovisningen, visa resultatet för
Röda rummet.
Vi hade inget nytt Haskell-material, utan bara en del HTML, som kan sammanfattas i malldokumentet med källkoden
<html> <head><title>Head: texten överst i ramen</title></head> <body> Body: texten i textfältet. <h1>Huvudtitel</h1> <p> Paragraf, bestående av text och annat, t.ex. <a href="http://www.haskell.org">länkar till webbsidor</a>, <b>text i fetstil</b>, <i>text i kursiv</i>, <tt>text i maskinskrift</tt>, <font color="red">text i röd font</font>, bilder, som är länkar till bildfiler och kan skalas till önskad storlek (i nästa paragraf): </p> <p> <img width= "512" src="didno.jpg"> </p> <h2>Lite mindre titel</h2> <p> Och så en tabell: </p> <table border="yes"> <tr> <td>A1</td> <td>A2</td> <td>A3</td> </tr> <tr> <td>B1</td> <td>B2</td> <td>B3</td> </tr> </table> </body> </html>