Jack of all trades, master of none

För att bygga lagen.nu 2.0 kommer det krävas ett rätt stort lass med teknologier. Jag har väl ungefär samlat ihop alla pusselbitar och känner mig ungefär som när man storhandlat inför en riktigt ambitiös middagsbjudning — alla råvaror och alla verktyg finns på plats, nu gäller det bara att hantera dem. Lite om vad som ingår:

XML: Lagen.nu 1.0 använde XML en hel del bakom kulisserna, men XML-formaten var odokumenterade, ad-hoc’iga och i största allmänhet inte så väldigt XMLiga (inga namespaces, data som borde varit i noder lagrades i attribut och vice versa, inget utnyttjande av befintliga standarder som RDF och XLink). Det här ska på något sätt bli bättre i 2.0 — det finns en hel del internationella projekt kring hur juridisk information ska representeras i XML, men de flesta känns som kommittéprodukter med mycket snack och lite spec — det känns som XML inbjuder till sånt, i högre grad än andra komponenter i stacken nedan. Metalex verkar dock lovande.

XSLT: För att få ut de semantiskt korrekta XML-dokumenten på webben måste de transformeras till nån sorts HTML. För 1.0 gjorde jag en del riktigt knepiga transformationer då mantrat där var ”vem behöver databaser när vi kan slänga in allt i ett gigantiskt XML-dokument och XPath()a oss fram” — för 2.0 kommer en vanlig old-school relationsdatabas att användas, så förhoppningsvis blir det bara en fråga om att ta befintliga stylesheets och trimma lite.

SOAP: Det här är väl mera på nice-to-have-listan snarare än release-blocker-listan, men det vore kul att åtminstone doppa tårna i hela webservicesträsket. Två problem är dock att jag aldrig har jobbat mot någon skarp web service från klientsidan, så jag vet inte riktigt hur ett WS-API ska kännas för att vara bra, samt att jag egentligen inte har en bra känsla för vilka rättskälleinformationsfunktioner som skulle vara vettiga att göra åtkomliga som webservices.

HTML: Allt ska ju bli HTML till slut, så viss koll på läget måste jag ju ha även här. Det blir förmodligen XHTML 1.0 Strict, en viss grad av divitis (den lösning jag skissade på här visade sig vara ohållbar när man kör den på exempelvis inkomstskattelagen och många kommentarer), och förmodligen tyvärr sämre semantisk meningsfullhet än i 1.0 (det största problemet är numrerade listor — för att sätta en kommentar bredvid en punkt i en punktlista kan jag inte representera själva punkten som en LI-tag — det går inte att placera en P-tag med kommentaren vid sidan av när man är i ett UL-kontext). Dock så ska ett flertal tabeller bort och ersättas med DL-listor, efter tipsen här.

CSS: Ärligt talat är inte 1.0 särskilt visuellt upphetsande. Det kanske inte kommer bli pastellfärger och rundade hörn, men en något mer genomtänkt visuell känsla hoppas jag kunna åstadkomma. Jag har med min nya op-center-setup möjlighet att testa på Firefox, IE, Konqueror, Opera och Safari, och ser med skräckblandad förtjusning fram emot utmaningen att få det hela att se bra ut utan att degenerera till tabellsoppa.

DHTML/AJAX: Inte bara för att det är en nödvändig beståndsdel om man vill vara web 2.0, mycket av wikifunktionaliten skulle vinna på att med lite AJAX göra det möjligt att redigera kommentarer rakt på sidan, a la flickr‘s fotobeskrivningsmagi. Och vore det inte coolt om sökrutan föreslog lagtexter a la google suggest? Jag har kollat runt på vad för hjälpramverk som finns på javascriptutvecklingsscenen (jag har läst DHTML Utopia och såg inte alls fram enmot att göra all crossbrowserkompatibilitetssörja för hand) och fastnade tillslut för MochiKit (efter att ha kollat på Dojo, Prototype/script.aculo.us, YUI och den här artikeln) — att det beskrevs som kraftigt pythoninfluerat var ett tungt vägande skäl.

EBNF: En av de bästa sakerna med lagen.nu 1.0 var den EBNF-baserade tolkningen av lagtextreferenser i löpande text. Den är, i ärlighetens namn, mest ihophackad utan någon djupare förståelse för textparsning i den högre skolan, och det känns som att jag borde ägna lite tid åt SimpleParse-dokumentationen för att hantera andra typer av referenser, nu när jag ska hantera flera typer av rättskällor.

Python: Jag hamnar ofta i fällan att när jag, när jag lärt mig ett verktyg tillräckligt bra för att få riktigt jobb gjort med det, slutar lära mig mera. Under våren har jag dock gått tillbaks till grunderna för python och försökt utnyttja mer än de få procent av språket som 1.0 använder. Det blir vettig objektorientering, bättre utnyttjande av standardbiblioteket och kanske lite riktigt funktionell programmerings-tänk (första kapitlet i TPiP är en riktig ögonöppnare här). De tre viktigaste bitarna kommer nog bli Django för allt dynamiskt, BeautifulSoup för allt HTML-tröskande (tillsammans med SimpleParse enligt ovan), och ElementTree för allt XML-byggande.

MySQL: Och så ska ju saker lagras i en databas också. Jag är som tidigare nämnts skeptisk mot RDBMS-användande, men med tanke på hur fint django abstraherar bort det hela känns det motiverat att faktiskt plocka in en databasserver i mixen. Det blir förmodligen MySQL även om alla de coola kidsen använder Postgresql, men då jag redan har en MySQL-server körandes för WordPress, MediaWiki och lite annat, har jag än så länge inte sett nån verklig anledning att byta.

Ungefär så — det blir en ganska diger lista när man kollar på den. Vilket anknyter till den här bloggpostningens titel, det kan inte bli några djupa kunskaper inom varje enskild del (särskilt som en stor komponent inte är med här, nämligen domänkunskapen om just rättsinformation) men förhoppningsvis tillräckligt för att ro det hela i land.

Javascript-understödd layout

Taggningsmöjligheternalagen.nu är första steget i en process genom vilken det ska bli möjligt att koppla information (som etiketter, kommentarer eller bara understrykningar) till lagtext. Ett problem har varit hur man ska fixa det rent layoutmässigt.

Det övergripande resultatet jag är ute efter är följande:

De turkosa områdena är alltså lagtext, medans de gula är redaktionella kommentarer.

Det klassiska sättet att göra detta hade varit med en enkel tabellayout.De röda linjerna är tabellceller:

Men sånt är ju fel och fult. Det är inte semantiskt meningfullt, utan ett missbruk av dokumentstruktur för att åstadkomma en layouteffekt. Det är inte table-free design.

Det nya sättet att göra det med är CSS. För att få ett block att ligga bredvid ett annat block använder man float="left|right" och märker upp blocken med div-taggar. För att inte kommentarerna till stycke 1 ska flyta ihop med kommentarerna till stycke 2, utan ligga i linje med det stycke de kommenterar, måste varje lagtext-kommentarspar kapslas in i ytterligare en div (de röda linjerna är yttre div:ar, de gröna inre):

… och exakt hur skulle detta vara bättre, egentligen?

Vad vi har gjort är att återuppfinna tables för layout, fast med ett annat ord. Det semantiskt rätta vore att en stycke lagtext följs, på samma nivå i dokumentträdet, av kommentaren till denna text. Men det ska alltså presenteras sida-vid-sida. Hur göra detta?

Såhär!

Här är HTML-koden enkel, utan nästlade div:ar. Magin består i att kommentarsboxarna till en början är dolda (display=none i CSS-instruktionerna). När sidan är laddad och vi vet vilken position som varje lagtextbox har hamnat på, så kan vi använda absolute positioning och flytta kommentarsboxarna till sin rätta plats bredvid lagtexten:

             pe = FindPreviousBox(ps[i].previousSibling)
             ps[i].style.top = pe.offsetTop + "px"
             ps[i].style.display = "block";

(FindPreviousBox är en enkel rekursiv funktion som hittar rätt lagtextelement.) Vi hade inte kunnat göra det här statiskt, eftersom vi inte hade någon aning om var varje lagtextbox skulle komma att hamna på sidan i absoluta termer, eftersom detta beror på ffa läsarens fontstorlek. Men när sidan väl är laddad och layoutad är det en enkel operation att hitta rätt information i DOM:en.

Är det här en perfekt lösning? Nej, jag är inte ens säker på att den är bra. Framförallt funkar den riktigt dåligt om användaren har CSS men inte javascript, eftersom kommentarsboxarna då är gömda. Däremot funkar det bra med google och lynx.

Det kanske finns något semantiskt meningsfullt sätt att organisera informationen som låter mig uttrycka källtext med kommentarer på ett sånt sätt att det dessutom går att layouta fint. Men om inte annat är det kanske ett uppslag till hur man kan augumentera sin layout med lite javascript.

Imorgon ska jag prata om vikten av vettig lagstiftningsteknik ur ett demokratiskt perspektiv. Det blir mindre högtravande än det låter.

Avstavning i webbläsare

Fram till för några månader sedan hade jag inte tänkt på avstavning på minst femton år. Jag hade visserligen sett hur fint TeX kunde justera mina högermarginaler med hjälp av sin inbyggda avstavningsmotor, men i allt övrigt datoranvändande såg jag avstavning som något komplett onödigt. Rak högermarginal, bah!

Men i PM-uppgiften (PDF) till rättsteknikkursen ingick att se till att det vi lämnade in hade rak högermarginal och var korrekt avstavat. Svenska verkar vara ett relativt lättavstavat språk med enkla grundregler och utan så många fallgropar (jämför engelska meningsfragmentet ”the-rapists who pre-ached on wee-knights”?), så jag nöjde mig med att låta Words automatiska avstavning göra sitt jobb.

Nu är jag mer och mer sugen på fungerande avstavningslösningar även för webben. Om man ska ha in mycket information på litet utrymme, och dessutom har väldigt långa ord, som man ofta har i juridiken, skulle avstavning hjälpa mycket. Det finns två sätt att nå dit:

1: Sätt CSS3-propertyn word-break-inside till hyphenate. Det här förlitar sig på att användarens webläsare har en fungerande avstavningsmotor och ordlistor för det språk som används (vilket i sin tur förlitar sig på att författaren markerat vilket språk sidan eller stycket är skrivet med). I dagsläget tror jag inte en enda webläsare stödjer det här.

2: Använd ”soft hyphens”, dvs identifiera ett ords tänkbara avstavningspunkter på serversidan, och stoppa in ett ­ därhelst det skulle vara OK att avstava ett ord – för­hand­lings­skyl­dig­het­en och lita på att webläsaren gömmer undan de avstavningstecken som inte behövs. Tyvärr är det inte så lätt — framförallt gör inte alla webläsare rätt här (endast Lynx, Safari och, något förvånande, IE 5+). Mozilla-baserade webläsare ignorerar ­ helt och hållet, och NS4/IE4 skriver ut alla som bindestreck — ”för-hand-lings-skyl-dig-het-en”. Dessutom kan det ställa till problem med sökmotorer.

Jag tror jag kör på lösning nummer 1 och väntar på att världen ska komma ikapp.