5. Programmering av webbsidor Aarne Ranta Datorintroduktion 2009, D och DV, Chalmers & GU %!target:html %!postproc(html): #NEW %!postproc(html): #HR
#NEW ==HTML== 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) #NEW ==Exempel på HTML-dokument== [En enkel text test0.html] [Text med allt möjligt test1.html] [Fahrenheit-Celsius-tabell test2.html] [Text med länkar till Google test3.html] [Text med länkar till en ordbok test4.html] [Ett fotoalbum test5.html] #NEW ==Ett HTML-dokument== Den grundläggande strukturen i ett HTML-dokument finns i följande mall: ``` Head-titeln: texten överst i ramen Body: texten i textfältet.

Huvudtitel

Paragraf, bestående av text och annat, t.ex. länkar till webbsidor, text i fetstil, text i kursiv, text i maskinskrift, text i röd font, bilder, som är länkar till bildfiler och kan skalas till önskad storlek (i nästa paragraf):

Lite mindre titel

Och så en tabell:

A1 A2 A3
B1 B2 B3
``` Klicka [här mall.html] för att se dokumentet i din webbläsare. #NEW ==Ett annat HTML-dokument== ``` Pictures
``` Klicka [här test5.html] 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. #NEW ==HTML-element och taggar== 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`` MkHTML.hs]: #NEW ==Ett litet HTML-bibliotek== Alla dessa finns i [``MkHTML`` MkHTML.hs]: ``` 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 ``` #NEW ==Attribut== En tagg kan innehålla **attribut**, som ger extra information. Exempel 1: en **länk** har URL:en (= Uniform Resource Locator, "webbadressen") som attribut: ``` Haskell Home ``` Exempel 2: en **bild** har både bild-URL:en och valfria storleksattribut: ``` ``` **Obs**: URL-attributet kan vara en fil på samma dator, som i bildexemplet. **Obs**: sluttaggen har inga attribut. #NEW ==Generering av 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`` MkHTML.hs]. #NEW ==Fullständiga HTML-dokument== Dokumentet ska (oftast) ha formen ``` Titeln Innehållet ``` 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`` MkHTML.hs]. #NEW ==Ett fullständigt exempel i Haskell== HTML-koden: ``` Hello Hello World ``` Haskell-koden ``` html "Hello" (string "Hello World") ``` [Resultatet i webbläsaren test0.html] I Haskell blir det mindre att skriva. Och det blir inga syntaxfel t.ex. saknande sluttaggar. #NEW ==Ett annat exempel== HTML-koden: ``` Head-titeln: texten överst i ramen Body: texten i textfältet.

Huvudtitel

Paragraf, bestaende av text och annat, t.ex. lankar till webbsidor, text i fetstil, text i kursiv, text i maskinskrift, text i röd font, bilder, som ar lankar till bildfiler och kan skalas till onskad storlek (i nästa paragraf):

Lite mindre titel

``` 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" ]) ``` [Dokumentet i webbläsaren test1.html]. Vi vinner knappast något med Haskell här... #NEW ==Tabeller== En enkel tabell ser ut så här: || A1 | A2 | A3 || | B1 | B2 | B3 || HTML-koden ser ut så här: ```
A1 A2 A3
B1 B2 B3
``` Vi vill kunna skapa tabellen med Haskell-koden ``` table [["A1","A2","A3"],["B1","B2","B3"]] ``` #NEW ==Generering av tabeller== En tabell kan ses som en //lista av listor//. Den yttre listan är raderna (````), de inre är cellerna (````). 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`` MkHTML.hs] #NEW ==Generering av större tabeller== 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 test2.html]. #NEW ==Fotoalbumet== Vårt [fotoalbum test5.html] är en tabell där - varje cell visar en miniatyrbild ("thumbnail") - miniatyrbilden är en länk till samma bild i full storlek 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`` MkHTML.hs]) 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! #NEW ==Hur man skapar fillistan== Vi har använt Unix-kommandot ``ls``: ``` ls pictures/*.jpg > pics ``` som gav oss alla filer i katalogen [``pictures`` 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. #NEW ==Generering av Google-sökningar== Om man går till [Google www.google.se] 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") ``` [det här dokumentet test3.html]. #NEW ==Dynamiska HTML-sidor== 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 http://www.haskell.org/haskellwiki/Practical_web_programming_in_Haskell]. Ett exempel med Haskell, [GF http://www.cs.chalmers.se/Cs/Research/Language-technology/GF/] och [Google Web Toolkit http://code.google.com/webtoolkit/]: [flerspråkiga kylskåpsmagneter http://tournesol.cs.chalmers.se:41296/fridge/]. #NEW ==Andra sätt att skapa HTML== De här föreläsningarna har skapats med [txt2tags http://txt2tags.sourceforge.net/]. Källan till den här föreläsningen ser ut [så här dator-05.txt]. Fördelar: - lättare att skriva än HTML - kan genereras till andra format, t.ex. LaTeX (och därmed PDF) Nackdelar: - blir inte lika snyggt som handskrivet HTML kan bli #NEW ==Uppgifter== **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`` MkHTML.hs]. 2. Undersök hur man skapar söklänkar till [Wikipedia http://en.wikipedia.org/] 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`` 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 http://images.google.se]. 4. Modifiera ordstatistikfunktionen i [``Freq.hs`` Freq.hs] ([föreläsning 4 dator-04.html]) 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 redRoom.txt]. #NEW ==Sammanfattning och referens== Vi hade inget nytt Haskell-material, utan bara en del HTML, som kan sammanfattas i [malldokumentet mall.html] med källkoden ``` Head: texten överst i ramen Body: texten i textfältet.

Huvudtitel

Paragraf, bestående av text och annat, t.ex. länkar till webbsidor, text i fetstil, text i kursiv, text i maskinskrift, text i röd font, bilder, som är länkar till bildfiler och kan skalas till önskad storlek (i nästa paragraf):

Lite mindre titel

Och så en tabell:

A1 A2 A3
B1 B2 B3
```